Subversion Repositories SmartDukaan

Rev

Rev 2679 | Rev 3044 | 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,\
7
    LogisticsServiceException
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
 
644 chandransh 72
    def getLogisticsInfo(self, destination_pincode, itemId):
483 rajveer 73
        """
74
        Parameters:
75
         - destination_pincode
716 rajveer 76
         - item_id
483 rajveer 77
        """
796 rajveer 78
        try:
79
            logistics_info = self.getLogisticsEstimation(itemId, destination_pincode)
80
            logistics_info.airway_billno = get_empty_AWB(logistics_info.providerId)
81
            return logistics_info
82
        finally:
83
            close_session()
84
 
412 ashish 85
    def getEmptyAWB(self, provider_id):
86
        """
87
        Parameters:
88
         - provider_id
89
        """
796 rajveer 90
        try:
91
            return get_empty_AWB(provider_id)
92
        finally:
93
            close_session()
94
 
644 chandransh 95
    def getShipmentInfo(self, awb, providerId):
412 ashish 96
        """
97
        Parameters:
98
         - awb
766 rajveer 99
         - providerId
412 ashish 100
        """
796 rajveer 101
        try:
102
            awb_updates = get_shipment_info(awb, providerId)
103
            t_updates = []
104
            for update in awb_updates:
105
                t_updates.append(to_t_awbupdate(update))
106
            return t_updates
107
        finally:
108
            close_session()
109
 
644 chandransh 110
    def getLogisticsEstimation(self, itemId, destination_pin):
472 rajveer 111
        """
112
        Parameters:
113
         - itemId
114
         - destination_pin
115
        """
644 chandransh 116
        try:
796 rajveer 117
            if not destination_pin:
118
                destination_pin = self.default_pincode
1504 ankur.sing 119
            try:
120
                client = InventoryClient().get_client()
121
                item = client.getItem(itemId)
122
            except Exception as ex:
123
                raise LogisticsServiceException(103, "Unable to fetch inventory information about this item.")
2341 chandransh 124
 
1504 ankur.sing 125
            delivery_estimate = get_logistics_estimation(destination_pin, item.sellingPrice)
796 rajveer 126
            if delivery_estimate is None:
2341 chandransh 127
                raise LogisticsServiceException(104, "Unable to fetch delivery estimate for this pincode.")
128
 
796 rajveer 129
            warehouse_loc = delivery_estimate.warehouse_location
130
            try:
2341 chandransh 131
                #Get the id and location of actual warehouse that'll be used to fulfill this order.
132
                warehouse_loc, warehouse_id, items_in_inventory = client.getItemAvailabilityAtLocation(warehouse_loc, itemId)
1504 ankur.sing 133
            except Exception as ex:
2341 chandransh 134
                raise LogisticsServiceException(103, "Unable to fetch inventory information about this item.")
135
 
136
            # We are revising the estimated based on the actual warehouse that will be assigned to this order.
137
            # This warehouse may be located in a different zone that the one we allocated for this pincode.
138
            delivery_estimate = get_logistics_estimation(destination_pin, item.sellingPrice, warehouse_loc)
139
            if delivery_estimate is None:
140
                raise LogisticsServiceException(105, "Unable to fetch delivery estimate for pincode: " + destination_pin + " and revised location: " + str(warehouse_loc))
141
 
142
            delivery_time = 24*delivery_estimate.delivery_time
143
 
144
            # Increase the estimate if the actual stock is less than the threshold 
796 rajveer 145
            if items_in_inventory < self.stock_threshold :
146
                delivery_time = delivery_time + self.time_to_producre
2231 chandransh 147
 
2341 chandransh 148
            #Further increase the estimate if it's late in the day
149
            if self.cutoff_time <= datetime.datetime.now().hour:
150
                delivery_time = delivery_time + 24
151
 
796 rajveer 152
            delivery_time = int(math.ceil(delivery_time/24.0))
153
 
2679 rajveer 154
 
155
            ## FIXME Due to Kanwaar on the delhi Dehradun route deliveries on following pin codes will be effected.
156
            ## Changing as per ticket number #462
2680 rajveer 157
            if destination_pin in self.kanwaar_effected_pins_by_two_days:
2679 rajveer 158
                delivery_time += 2;
2680 rajveer 159
            elif destination_pin in self.kanwaar_effected_pins_by_one_day:
2679 rajveer 160
                delivery_time += 1;
161
            ## FIXME Remove the above code once Kanwaar season is over    
162
 
796 rajveer 163
            logistics_info = LogisticsInfo()
164
            logistics_info.deliveryTime = delivery_time
165
            logistics_info.providerId = delivery_estimate.provider_id
166
            logistics_info.warehouseId = warehouse_id
167
 
168
            return logistics_info
169
        finally:
170
            close_session()
171
 
731 chandransh 172
    def getDestinationCode(self, providerId, pinCode):
173
        """
174
        Returns the short three letter code of a pincode for the given provider.
175
        Raises an exception if the pin code is not serviced by the given provider.
176
 
177
        Parameters:
178
         - providerId
179
         - pinCode
180
        """
796 rajveer 181
        try:
182
            sld = ServiceableLocationDetails.get_by(provider_id = providerId, dest_pincode = pinCode)
183
            if sld != None:
184
                return sld.dest_code
185
            else:
186
                raise LogisticsServiceException(101, "The pincode " + pinCode + " is not serviced by this provider: " + str(providerId))
187
        finally:
188
            close_session()
1137 chandransh 189
 
190
    def getFreeAwbCount(self, providerId):
191
        """
192
        Returns the number of unused AWB numbers for the given provider
796 rajveer 193
 
1137 chandransh 194
        Parameters:
195
         - providerId
196
        """
197
        try:
198
            return get_free_awb_count(providerId)
199
        finally:
200
            close_session()
1730 ankur.sing 201
 
202
    def getHolidays(self, fromDate, toDate):
203
        """
204
        Returns list of Holiday dates between fromDate and toDate (both inclusive)
205
        fromDate should be passed as milliseconds corresponding to the start of the day.
206
        If fromDate is passed as -1, fromDate is not considered for filtering
207
        If toDate is passed as -1, toDate is not considered for filtering
1137 chandransh 208
 
1730 ankur.sing 209
        Parameters:
210
         - fromDate
211
         - toDate
212
        """
213
        try:
214
            return get_holidays(fromDate, toDate)
215
        finally:
216
            close_session()
217
 
766 rajveer 218
    def closeSession(self, ):
219
        close_session()