Subversion Repositories SmartDukaan

Rev

Rev 2680 | Rev 3064 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
412 ashish 1
'''
2
Created on 05-Aug-2010
3
 
4
@author: ashish
5
'''
644 chandransh 6
from shop2020.thriftpy.logistics.ttypes import LogisticsInfo,\
3044 chandransh 7
    LogisticsServiceException, DeliveryType
644 chandransh 8
from shop2020.logistics.service.impl.DataAccessor import get_empty_AWB,\
675 chandransh 9
    get_shipment_info, initialize, get_logistics_estimation, get_provider,\
1730 ankur.sing 10
    get_providers, close_session, get_free_awb_count, get_holidays
669 chandransh 11
from shop2020.logistics.service.impl.Converters import to_t_awbupdate,\
12
    to_t_provider
494 rajveer 13
from shop2020.clients.InventoryClient import InventoryClient
14
from shop2020.config.client.ConfigClient import ConfigClient
15
import datetime
644 chandransh 16
import math
1687 vikas 17
import sys
1730 ankur.sing 18
from shop2020.logistics.service.impl.DataService import ServiceableLocationDetails,\
19
    PublicHolidays
472 rajveer 20
 
412 ashish 21
class LogisticsServiceHandler:
22
 
1248 chandransh 23
    def __init__(self, dbname='logistics'):
24
        initialize(dbname)
746 rajveer 25
        try:
26
            config_client = ConfigClient()
27
            self.cutoff_time = int(config_client.get_property('delivery_cutoff_time'))
28
            self.stock_threshold = int(config_client.get_property('inventory_stock_threshold'))
29
            self.time_to_producre = int(config_client.get_property('inventory_time_to_procure'))
776 rajveer 30
            self.default_pincode = int(config_client.get_property('default_pincode'))
1687 vikas 31
        except Exception as ex:
32
            print "[ERROR] Unexpected config error:", sys.exc_info()[0]
746 rajveer 33
            self.cutoff_time = 15
34
            self.stock_threshold = 2
776 rajveer 35
            self.time_to_producre = 48
36
            self.default_pincode = "110001" 
2680 rajveer 37
 
38
        ##FIXME 
39
        self.kanwaar_effected_pins_by_two_days = ['244713', '247667', '248001', '248002', '248003', '248005', '248006', 
40
                                             '248008', '248009', '248110', '248146', '248171', '248179', '249201', 
41
                                             '249401', '249403', '249404', '249407', '249408', '249409', '249410', 
42
                                             '249411', '262405', '263139', '263153']
43
        self.kanwaar_effected_pins_by_one_day = ['201001', '201002', '201003', '201004', '201005', '201007', '201009', 
44
                                            '201010', '201011', '201012', '201014', '201204', '202001', '202002', 
45
                                            '203001', '203131', '204101']
746 rajveer 46
 
669 chandransh 47
    def getProvider(self, providerId):
675 chandransh 48
        """
49
        Returns a provider for a given provider ID. Throws an exception if none found.
50
 
51
        Parameters:
52
         - providerId
53
        """
796 rajveer 54
        try:
1137 chandransh 55
            provider = get_provider(providerId)
56
            if provider:
57
                return to_t_provider(provider)
58
            else:
59
                raise LogisticsServiceException(101, "No Provider found for the given id")
796 rajveer 60
        finally:
61
            close_session()
62
 
675 chandransh 63
    def getAllProviders(self, ):
64
        """
65
        Returns a list containing all the providers.
66
        """
796 rajveer 67
        try:
68
            return [to_t_provider(provider) for provider in get_providers()]
69
        finally:
70
            close_session()
71
 
3044 chandransh 72
    def getLogisticsInfo(self, destination_pincode, itemId, type):
483 rajveer 73
        """
74
        Parameters:
75
         - destination_pincode
716 rajveer 76
         - item_id
3044 chandransh 77
         - type
483 rajveer 78
        """
796 rajveer 79
        try:
3044 chandransh 80
            logistics_info = self.get_logistics_estimation_with_type(itemId, destination_pincode, type)
81
            logistics_info.airway_billno = get_empty_AWB(logistics_info.providerId, type)
796 rajveer 82
            return logistics_info
83
        finally:
84
            close_session()
85
 
412 ashish 86
    def getEmptyAWB(self, provider_id):
87
        """
88
        Parameters:
89
         - provider_id
90
        """
796 rajveer 91
        try:
92
            return get_empty_AWB(provider_id)
93
        finally:
94
            close_session()
95
 
644 chandransh 96
    def getShipmentInfo(self, awb, providerId):
412 ashish 97
        """
98
        Parameters:
99
         - awb
766 rajveer 100
         - providerId
412 ashish 101
        """
796 rajveer 102
        try:
103
            awb_updates = get_shipment_info(awb, providerId)
104
            t_updates = []
105
            for update in awb_updates:
106
                t_updates.append(to_t_awbupdate(update))
107
            return t_updates
108
        finally:
109
            close_session()
3044 chandransh 110
 
644 chandransh 111
    def getLogisticsEstimation(self, itemId, destination_pin):
472 rajveer 112
        """
113
        Parameters:
114
         - itemId
115
         - destination_pin
116
        """
644 chandransh 117
        try:
3044 chandransh 118
            return self.get_logistics_estimation_with_type(itemId, destination_pin)
796 rajveer 119
        finally:
120
            close_session()
3044 chandransh 121
 
122
    def get_logistics_estimation_with_type(self, itemId, destination_pin, type = DeliveryType.PREPAID):
123
        if not destination_pin:
124
            destination_pin = self.default_pincode
125
        try:
126
            client = InventoryClient().get_client()
127
            item = client.getItem(itemId)
128
        except Exception as ex:
129
            raise LogisticsServiceException(103, "Unable to fetch inventory information about this item.")
130
 
131
        delivery_estimate = get_logistics_estimation(destination_pin, item.sellingPrice)
132
        if delivery_estimate is None:
133
            raise LogisticsServiceException(104, "Unable to fetch delivery estimate for this pincode.")
134
 
135
        warehouse_loc = delivery_estimate.warehouse_location
136
        try:
137
            #Get the id and location of actual warehouse that'll be used to fulfill this order.
138
            warehouse_loc, warehouse_id, items_in_inventory = client.getItemAvailabilityAtLocation(warehouse_loc, itemId)
139
        except Exception as ex:
140
            raise LogisticsServiceException(103, "Unable to fetch inventory information about this item.")
141
 
142
        # We are revising the estimated based on the actual warehouse that will be assigned to this order.
143
        # This warehouse may be located in a different zone that the one we allocated for this pincode.
144
        delivery_estimate = get_logistics_estimation(destination_pin, item.sellingPrice, warehouse_loc)
145
        if delivery_estimate is None:
146
            raise LogisticsServiceException(105, "Unable to fetch delivery estimate for pincode: " + destination_pin + " and revised location: " + str(warehouse_loc))
147
 
148
        delivery_time = 24*delivery_estimate.delivery_time
149
 
150
        # Increase the estimate if the actual stock is less than the threshold 
151
        if items_in_inventory < self.stock_threshold :
152
            delivery_time = delivery_time + self.time_to_producre
153
 
154
        #Further increase the estimate if it's late in the day
155
        if self.cutoff_time <= datetime.datetime.now().hour:
156
            delivery_time = delivery_time + 24
157
 
158
        delivery_time = int(math.ceil(delivery_time/24.0))
159
 
160
 
161
        ## FIXME Due to Kanwaar on the delhi Dehradun route deliveries on following pin codes will be effected.
162
        ## Changing as per ticket number #462
163
        if destination_pin in self.kanwaar_effected_pins_by_two_days:
164
            delivery_time += 2;
165
        elif destination_pin in self.kanwaar_effected_pins_by_one_day:
166
            delivery_time += 1;
167
        ## FIXME Remove the above code once Kanwaar season is over    
168
 
169
        logistics_info = LogisticsInfo()
170
        logistics_info.deliveryTime = delivery_time
171
        logistics_info.providerId = delivery_estimate.provider_id
172
        logistics_info.warehouseId = warehouse_id
173
 
174
        return logistics_info
175
 
731 chandransh 176
    def getDestinationCode(self, providerId, pinCode):
177
        """
178
        Returns the short three letter code of a pincode for the given provider.
179
        Raises an exception if the pin code is not serviced by the given provider.
180
 
181
        Parameters:
182
         - providerId
183
         - pinCode
184
        """
796 rajveer 185
        try:
186
            sld = ServiceableLocationDetails.get_by(provider_id = providerId, dest_pincode = pinCode)
187
            if sld != None:
188
                return sld.dest_code
189
            else:
190
                raise LogisticsServiceException(101, "The pincode " + pinCode + " is not serviced by this provider: " + str(providerId))
191
        finally:
192
            close_session()
1137 chandransh 193
 
194
    def getFreeAwbCount(self, providerId):
195
        """
196
        Returns the number of unused AWB numbers for the given provider
796 rajveer 197
 
1137 chandransh 198
        Parameters:
199
         - providerId
200
        """
201
        try:
202
            return get_free_awb_count(providerId)
203
        finally:
204
            close_session()
1730 ankur.sing 205
 
206
    def getHolidays(self, fromDate, toDate):
207
        """
208
        Returns list of Holiday dates between fromDate and toDate (both inclusive)
209
        fromDate should be passed as milliseconds corresponding to the start of the day.
210
        If fromDate is passed as -1, fromDate is not considered for filtering
211
        If toDate is passed as -1, toDate is not considered for filtering
1137 chandransh 212
 
1730 ankur.sing 213
        Parameters:
214
         - fromDate
215
         - toDate
216
        """
217
        try:
218
            return get_holidays(fromDate, toDate)
219
        finally:
220
            close_session()
221
 
766 rajveer 222
    def closeSession(self, ):
223
        close_session()