Subversion Repositories SmartDukaan

Rev

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