Subversion Repositories SmartDukaan

Rev

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