Subversion Repositories SmartDukaan

Rev

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