Subversion Repositories SmartDukaan

Rev

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