Subversion Repositories SmartDukaan

Rev

Rev 8182 | Rev 10688 | 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
'''
3133 rajveer 6
from shop2020.clients.CatalogClient import CatalogClient
5944 mandeep.dh 7
from shop2020.clients.InventoryClient import InventoryClient
494 rajveer 8
from shop2020.config.client.ConfigClient import ConfigClient
5944 mandeep.dh 9
from shop2020.logistics.service.impl import DataAccessor
10
from shop2020.logistics.service.impl.Converters import to_t_awbupdate, \
11
    to_t_provider, to_t_pickup_store
12
from shop2020.logistics.service.impl.DataAccessor import get_empty_AWB, \
13
    get_shipment_info, initialize, get_logistics_estimation, get_provider, \
14
    get_providers, close_session, get_free_awb_count, get_holidays, is_alive, \
15
    get_provider_for_pickup_type, get_pickup_store, get_all_pickup_stores, \
6322 amar.kumar 16
    get_pickup_store_by_hotspot_id, get_destination_code, update_pincode, \
9840 amit.gupta 17
    add_pincode, store_shipment_info, adjust_delivery_time, get_min_advance_amount, \
18
    add_new_awbs, run_Logistics_Location_Info_Update
19
from shop2020.logistics.service.impl.DataService import \
20
    ServiceableLocationDetails
5944 mandeep.dh 21
from shop2020.thriftpy.logistics.ttypes import LogisticsInfo, \
22
    LogisticsServiceException, DeliveryType, PickUpType
23
from shop2020.thriftpy.model.v1.catalog.ttypes import status
9840 amit.gupta 24
from shop2020.thriftpy.logistics.ttypes import ItemText
25
from shop2020.utils.Utils import to_java_date, to_py_date
26
import collections
494 rajveer 27
import datetime
644 chandransh 28
import math
1687 vikas 29
import sys
9840 amit.gupta 30
#Start:- Added by Manish Sharma for Multiple Pincode Updation on 05-Jul-2013
31
#End:- Added by Manish Sharma for Multiple Pincode Updation on 05-Jul-2013
472 rajveer 32
 
412 ashish 33
class LogisticsServiceHandler:
34
 
3187 rajveer 35
    def __init__(self, dbname='logistics', db_hostname='localhost'):
36
        initialize(dbname, db_hostname)
746 rajveer 37
        try:
38
            config_client = ConfigClient()
5978 rajveer 39
            self.sourceId = int(config_client.get_property("sourceid"))
746 rajveer 40
            self.cutoff_time = int(config_client.get_property('delivery_cutoff_time'))
5843 mandeep.dh 41
            self.cod_cutoff_time = 24 #int(config_client.get_property('delivery_cutoff_time'))
776 rajveer 42
            self.default_pincode = int(config_client.get_property('default_pincode'))
1687 vikas 43
        except Exception as ex:
44
            print "[ERROR] Unexpected config error:", sys.exc_info()[0]
5978 rajveer 45
            self.sourceId = 1
746 rajveer 46
            self.cutoff_time = 15
5843 mandeep.dh 47
            self.cod_cutoff_time = 24
4866 rajveer 48
            self.default_pincode = "110001"
5978 rajveer 49
 
3064 chandransh 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
 
5767 rajveer 76
    def getLogisticsInfo(self, destination_pincode, itemId, type, pickUp):
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)
5767 rajveer 85
            if pickUp == PickUpType.RUNNER or pickUp == PickUpType.SELF:
86
                logistics_info.providerId = get_provider_for_pickup_type(pickUp)
7946 manish.sha 87
            #logistics_info.airway_billno = get_empty_AWB(logistics_info.providerId, type)
796 rajveer 88
            return logistics_info
89
        finally:
90
            close_session()
91
 
5247 rajveer 92
    def getEmptyAWB(self, providerId, type):
412 ashish 93
        """
94
        Parameters:
95
         - provider_id
5247 rajveer 96
         - type
412 ashish 97
        """
796 rajveer 98
        try:
5247 rajveer 99
            return get_empty_AWB(providerId, type)
796 rajveer 100
        finally:
101
            close_session()
102
 
6643 rajveer 103
    def getShipmentInfo(self, awbNumber, providerId):
412 ashish 104
        """
105
        Parameters:
6643 rajveer 106
         - awbNumber
766 rajveer 107
         - providerId
412 ashish 108
        """
796 rajveer 109
        try:
6643 rajveer 110
            awb_updates = get_shipment_info(awbNumber, providerId)
796 rajveer 111
            t_updates = []
112
            for update in awb_updates:
113
                t_updates.append(to_t_awbupdate(update))
114
            return t_updates
115
        finally:
116
            close_session()
3044 chandransh 117
 
6643 rajveer 118
    def storeShipmentInfo(self, update):
119
        """
120
        Parameters:
121
         - update
122
        """
123
        try:
124
            store_shipment_info(update)
125
        finally:
126
            close_session()
127
 
128
 
4630 mandeep.dh 129
    def getLogisticsEstimation(self, itemId, destination_pin, type):
472 rajveer 130
        """
131
        Parameters:
132
         - itemId
133
         - destination_pin
4630 mandeep.dh 134
         - type
472 rajveer 135
        """
644 chandransh 136
        try:
4630 mandeep.dh 137
            return self.get_logistics_estimation_with_type(itemId, destination_pin, type)
796 rajveer 138
        finally:
139
            close_session()
3044 chandransh 140
 
7256 rajveer 141
 
142
    def getLogisticsEstimationForStore(self, itemId, destination_pin, type):
143
        """
144
        Parameters:
145
         - itemId
146
         - destination_pin
147
         - type
148
        """
149
        try:
150
            todate = datetime.datetime.now()
151
            logistics_info = self.get_logistics_estimation_with_type(itemId, destination_pin, type)
7273 rajveer 152
            logistics_info.deliveryTime = to_java_date(todate +  datetime.timedelta(days = adjust_delivery_time(todate, logistics_info.deliveryTime)))
153
            logistics_info.shippingTime = to_java_date(todate +  datetime.timedelta(days = adjust_delivery_time(todate, logistics_info.shippingTime)))
7275 rajveer 154
            minAdvanceAmount, logistics_info.codAllowed = get_min_advance_amount(itemId, destination_pin, logistics_info.providerId, logistics_info.codAllowed)
155
            ## Send minadvanceamount in providerId field 
156
            logistics_info.providerId = int(minAdvanceAmount)
7256 rajveer 157
            return logistics_info
158
        finally:
159
            close_session()
160
 
4630 mandeep.dh 161
    def get_logistics_estimation_with_type(self, itemId, destination_pin, type):
3044 chandransh 162
        try:
5295 rajveer 163
            #Get the id and location of actual warehouse that'll be used to fulfil this order.
5944 mandeep.dh 164
            client = InventoryClient().get_client()
7589 rajveer 165
            fulfilmentWarehouseId, expected_delay, billingWarehouseId, sellingPrice, totalAvailability, weight = client.getItemAvailabilityAtLocation(itemId, self.sourceId)
3044 chandransh 166
        except Exception as ex:
167
            raise LogisticsServiceException(103, "Unable to fetch inventory information about this item.")
5295 rajveer 168
 
7608 rajveer 169
        delivery_estimate = get_logistics_estimation(destination_pin, sellingPrice, weight, type, billingWarehouseId)
3218 rajveer 170
        if delivery_estimate is None:
3044 chandransh 171
            raise LogisticsServiceException(104, "Unable to fetch delivery estimate for this pincode.")
5295 rajveer 172
 
3044 chandransh 173
 
5270 rajveer 174
        ## Commented below part as we have only Delhi as warehouse city. If we will add some more warehouses in different cities, this could be  useful. 
4009 chandransh 175
        # We are revising the estimates based on the actual warehouse that this order will be assigned to.
176
        # This warehouse may be located in a zone which is different from the one we allocated for this pincode.
5270 rajveer 177
        #delivery_estimate = get_logistics_estimation(destination_pin, item.sellingPrice, warehouse_loc, type)
178
        #if delivery_estimate is None:
179
        #    raise LogisticsServiceException(105, "Unable to fetch delivery estimate for pincode: " + destination_pin + " and revised location: " + str(warehouse_loc))
3044 chandransh 180
 
6537 rajveer 181
        delivery_time = 24 * (delivery_estimate.delivery_time + delivery_estimate.delivery_delay)
3044 chandransh 182
 
4009 chandransh 183
        '''
184
        We're now calculating the expected shipping delay which is independent of
185
        the courier agency and is completely within our control (well, almost).
186
        '''
3355 chandransh 187
        #Always add the expected delay
4009 chandransh 188
        shipping_delay = 24 * expected_delay
3355 chandransh 189
 
4829 rajveer 190
        # Sometimes we set negative shipping delay just in case we know time to procure will be less than the default.
191
        # If we have received inventory and forgot to remove expected delay from item, it could lead to display negative shipping days. 
192
        if shipping_delay < 0:
193
            shipping_delay = 0
194
 
3044 chandransh 195
        #Further increase the estimate if it's late in the day
3064 chandransh 196
        current_hour = datetime.datetime.now().hour
197
        if type == DeliveryType.PREPAID and self.cutoff_time <= current_hour:
4009 chandransh 198
            shipping_delay = shipping_delay + 24
3044 chandransh 199
 
4426 rajveer 200
        #In case of COD,increase delay by one more day
201
        if type == DeliveryType.COD:
202
            shipping_delay = shipping_delay + 24
6524 rajveer 203
            delivery_estimate.otgAvailable = False
4426 rajveer 204
 
4010 chandransh 205
        delivery_time = delivery_time + shipping_delay
206
 
4009 chandransh 207
        shipping_delay = int(math.ceil(shipping_delay/24.0))
4010 chandransh 208
        delivery_time = int(math.ceil(delivery_time/24.0))
3044 chandransh 209
 
210
        logistics_info = LogisticsInfo()
211
        logistics_info.deliveryTime = delivery_time
3218 rajveer 212
        logistics_info.providerId = delivery_estimate.provider_id
5110 mandeep.dh 213
        logistics_info.warehouseId = billingWarehouseId
214
        logistics_info.fulfilmentWarehouseId = fulfilmentWarehouseId
4009 chandransh 215
        logistics_info.shippingTime = shipping_delay
4870 rajveer 216
        logistics_info.codAllowed = delivery_estimate.codAllowed 
6524 rajveer 217
        logistics_info.otgAvailable = delivery_estimate.otgAvailable
6726 rajveer 218
        logistics_info.deliveryDelay = delivery_estimate.delivery_delay
3044 chandransh 219
 
5595 anupam.sin 220
        try:
221
            return logistics_info
222
        finally:
223
            close_session()
3044 chandransh 224
 
731 chandransh 225
    def getDestinationCode(self, providerId, pinCode):
226
        """
227
        Returns the short three letter code of a pincode for the given provider.
228
        Raises an exception if the pin code is not serviced by the given provider.
229
 
230
        Parameters:
231
         - providerId
232
         - pinCode
233
        """
796 rajveer 234
        try:
3217 rajveer 235
            try:
3218 rajveer 236
                dest_code = DataAccessor.serviceable_location_cache[providerId][pinCode][0]
3217 rajveer 237
                return dest_code
238
            except:
6017 amar.kumar 239
                try:
240
                    dest_code = get_destination_code(providerId, pinCode) 
241
                    return dest_code
242
                except:
8182 amar.kumar 243
                    if providerId >7:
244
                        return ""
6017 amar.kumar 245
                    raise LogisticsServiceException(101, "The pincode " + pinCode + " is not serviced by this provider: " + str(providerId))
796 rajveer 246
        finally:
247
            close_session()
1137 chandransh 248
 
3103 chandransh 249
    def getFreeAwbCount(self, providerId, type):
1137 chandransh 250
        """
3103 chandransh 251
        Returns the number of unused AWB numbers for the given provider of the given type
796 rajveer 252
 
1137 chandransh 253
        Parameters:
254
         - providerId
3103 chandransh 255
         - type
1137 chandransh 256
        """
257
        try:
3103 chandransh 258
            return get_free_awb_count(providerId, type)
1137 chandransh 259
        finally:
260
            close_session()
1730 ankur.sing 261
 
262
    def getHolidays(self, fromDate, toDate):
263
        """
264
        Returns list of Holiday dates between fromDate and toDate (both inclusive)
265
        fromDate should be passed as milliseconds corresponding to the start of the day.
266
        If fromDate is passed as -1, fromDate is not considered for filtering
267
        If toDate is passed as -1, toDate is not considered for filtering
1137 chandransh 268
 
1730 ankur.sing 269
        Parameters:
270
         - fromDate
271
         - toDate
272
        """
273
        try:
274
            return get_holidays(fromDate, toDate)
275
        finally:
276
            close_session()
5527 anupam.sin 277
 
278
    def getProviderForPickupType(self, pickUp):
279
        try:
280
            return get_provider_for_pickup_type(pickUp)
281
        finally:
282
            close_session()
3064 chandransh 283
 
766 rajveer 284
    def closeSession(self, ):
285
        close_session()
3376 rajveer 286
 
287
    def isAlive(self, ):
288
        """
289
        For checking weather service is active alive or not. It also checks connectivity with database
290
        """
291
        try:
292
            return is_alive()
293
        finally:
294
            close_session()
4934 amit.gupta 295
 
296
    def getEntityLogisticsEstimation(self, catalogItemId, destination_pin, type):
297
        """
298
        Returns a LogisticsInfo structure w/o an airway bill number. Use this method during the estimation phase.
299
        Raises an exception if this pincode is not allocated to any warehouse zone or provider. Also, if the pincode
300
        is allocated to a warehouse zone but there are no actual warehouses in that zone, an exception is raised.
301
 
302
        Parameters:
303
         - catalogItemId
304
         - destination_pin
305
         - type
306
        """
307
        try:
308
            return self.get_entity_logistics_estimation_with_type(catalogItemId, destination_pin, type)
309
        finally:
310
            close_session()
311
 
312
    def get_entity_logistics_estimation_with_type(self, catalog_item_id, destination_pin, type):
313
        try:
314
            client = CatalogClient().get_client()
315
            items = client.getValidItemsByCatalogId(catalog_item_id)
316
        except Exception as ex:
317
            raise LogisticsServiceException(103, "Unable to fetch inventory information about this entity.")
318
 
319
        estimateList = []
320
 
321
        for item in items:
322
            estimationInfo = self.get_logistics_estimation_with_type(item.id, destination_pin, type)
323
            if item.itemStatus == status.ACTIVE:
9840 amit.gupta 324
                estimateList.append((0, estimationInfo.deliveryTime, "BUY NOW", item.id))
4934 amit.gupta 325
            elif item.itemStatus == status.PAUSED:
9840 amit.gupta 326
                estimateList.append((1, estimationInfo.deliveryTime, "NOTIFY ME", item.id))
4934 amit.gupta 327
            elif item.itemStatus == status.PAUSED_BY_RISK:
9840 amit.gupta 328
                estimateList.append((2, estimationInfo.deliveryTime, "NOTIFY ME", item.id))
6074 amit.gupta 329
            elif item.itemStatus == status.COMING_SOON:
9840 amit.gupta 330
                estimateList.append((3, estimationInfo.deliveryTime, "COMING SOON", item.id))
4934 amit.gupta 331
 
332
        estimateList.sort()
5595 anupam.sin 333
        try:
9840 amit.gupta 334
            return [ ItemText(estimate[-1], estimate[-2]) for estimate in estimateList]
5595 anupam.sin 335
        finally:
336
            close_session()
5555 rajveer 337
 
5595 anupam.sin 338
    def getAllPickupStores(self):
339
        try:
340
            return [to_t_pickup_store(pickup_store) for pickup_store in get_all_pickup_stores()]
341
        finally:
342
            close_session()
5555 rajveer 343
 
344
    def getPickupStore(self, storeId):
345
        """
346
        Parameters:
347
         - storeId
348
        """
5595 anupam.sin 349
        try:
350
            storeToReturn = to_t_pickup_store(get_pickup_store(storeId))
351
            return storeToReturn
352
        finally:
5719 rajveer 353
            close_session()
354
 
355
    def getPickupStoreByHotspotId(self, hotspotId):
356
        """
357
        Parameters:
358
         - hotspotId
359
        """
360
        try:
361
            storeToReturn = to_t_pickup_store(get_pickup_store_by_hotspot_id(hotspotId))
362
            return storeToReturn
363
        finally:
6322 amar.kumar 364
            close_session()
6524 rajveer 365
    def addPincode(self, providerId, pincode, destCode, exp, cod, stationType, otgAvailable):
6322 amar.kumar 366
        try:
6524 rajveer 367
            add_pincode(providerId, pincode, destCode, exp, cod, stationType, otgAvailable)
6322 amar.kumar 368
        finally:
369
            close_session()
6524 rajveer 370
    def updatePincode(self, providerId, pincode, exp, cod, otgAvailable):
6322 amar.kumar 371
        try:
6524 rajveer 372
            update_pincode(providerId, pincode, exp, cod, otgAvailable)
6322 amar.kumar 373
        finally:
7567 rajveer 374
            close_session()
375
 
376
    def addNewAwbs(self, providerId, isCod, awbs):
377
        try:
7608 rajveer 378
            return add_new_awbs(providerId, isCod, awbs)
7567 rajveer 379
        finally:
7733 manish.sha 380
            close_session()
7786 manish.sha 381
 
382
 
383
    def runLogisticsLocationInfoUpdate(self, logisticsLocationInfoList, runCompleteUpdate):
7733 manish.sha 384
        try:
7786 manish.sha 385
            run_Logistics_Location_Info_Update(logisticsLocationInfoList, runCompleteUpdate)
7733 manish.sha 386
        finally:
387
            close_session()
7888 rajveer 388
 
389
    def adjustDeliveryDays(self, startDate, days):
390
        try:
391
            return adjust_delivery_time(to_py_date(startDate), days)
392
        finally:
393
            close_session()