Subversion Repositories SmartDukaan

Rev

Rev 7733 | Rev 7841 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
442 rajveer 1
'''
2
Created on 13-Sep-2010
3
 
4
@author: rajveer
5
'''
6
 
7
from shop2020.logistics.service.impl import DataService
644 chandransh 8
from shop2020.logistics.service.impl.DataService import Awb, AwbUpdate, Provider, \
3218 rajveer 9
     DeliveryEstimate, WarehouseAllocation, \
5555 rajveer 10
    PublicHolidays, ServiceableLocationDetails, PickupStore
3044 chandransh 11
from shop2020.thriftpy.logistics.ttypes import LogisticsServiceException,\
7786 manish.sha 12
    DeliveryType, LogisticsLocationInfo
442 rajveer 13
from shop2020.utils.Utils import log_entry, to_py_date, to_java_date
5964 amar.kumar 14
from sqlalchemy.sql import or_
442 rajveer 15
from elixir import session
1730 ankur.sing 16
import datetime, time
1504 ankur.sing 17
import sys
3355 chandransh 18
import logging
7293 anupam.sin 19
from shop2020.clients.CatalogClient import CatalogClient
3355 chandransh 20
logging.basicConfig(level=logging.DEBUG)
442 rajveer 21
 
3217 rajveer 22
warehouse_allocation_cache = {}
23
serviceable_location_cache = {}
24
delivery_estimate_cache = {}
6370 rajveer 25
 
3218 rajveer 26
'''
27
This class is for only data transfer. Never used outside this module.
28
'''
29
class _DeliveryEstimateObject:
6537 rajveer 30
    def __init__(self, delivery_time, delivery_delay, provider_id, codAllowed, otgAvailable):
3218 rajveer 31
        self.delivery_time = delivery_time
6537 rajveer 32
        self.delivery_delay = delivery_delay
3218 rajveer 33
        self.provider_id = provider_id
4866 rajveer 34
        self.codAllowed = codAllowed
6524 rajveer 35
        self.otgAvailable = otgAvailable
3218 rajveer 36
 
3187 rajveer 37
def initialize(dbname="logistics", db_hostname="localhost"):
442 rajveer 38
    log_entry("initialize@DataAccessor", "Initializing data service")
3187 rajveer 39
    DataService.initialize(dbname, db_hostname)
3218 rajveer 40
    print "Starting cache population at: " + str(datetime.datetime.now())
3217 rajveer 41
    __cache_warehouse_allocation_table()
42
    __cache_serviceable_location_details_table()
43
    __cache_delivery_estimate_table()
44
    close_session()
3218 rajveer 45
    print "Done cache population at: " + str(datetime.datetime.now())
442 rajveer 46
 
3217 rajveer 47
def __cache_delivery_estimate_table():
48
    delivery_estimates = DeliveryEstimate.query.all()
49
    for delivery_estimate in delivery_estimates:
5692 rajveer 50
        delivery_estimate_cache[delivery_estimate.destination_pin, delivery_estimate.provider_id]\
6537 rajveer 51
        =delivery_estimate.delivery_time, delivery_estimate.delivery_delay
3217 rajveer 52
 
53
def __cache_serviceable_location_details_table():
5964 amar.kumar 54
    serviceable_locations = ServiceableLocationDetails.query.filter(or_("exp!=0","cod!=0"))
3217 rajveer 55
    for serviceable_location in serviceable_locations:
56
        try:
57
            provider_pincodes = serviceable_location_cache[serviceable_location.provider_id]
58
        except:
59
            provider_pincodes = {}
60
            serviceable_location_cache[serviceable_location.provider_id] = provider_pincodes 
7627 rajveer 61
        provider_pincodes[serviceable_location.dest_pincode] = serviceable_location.dest_code, serviceable_location.exp, serviceable_location.cod, serviceable_location.otgAvailable, serviceable_location.websiteCodLimit, serviceable_location.storeCodLimit, serviceable_location.providerPrepaidLimit
3217 rajveer 62
 
63
def __cache_warehouse_allocation_table():
64
    warehouse_allocations = WarehouseAllocation.query.all()
65
    for warehouse_allocation in warehouse_allocations:
66
        warehouse_allocation_cache[warehouse_allocation.pincode]=warehouse_allocation.primary_warehouse_location
67
 
644 chandransh 68
def get_provider(provider_id):
766 rajveer 69
    provider =  Provider.get_by(id=provider_id)
70
    return provider
644 chandransh 71
 
72
def get_providers():
5387 rajveer 73
    providers = Provider.query.filter_by(isActive = 1).all()
766 rajveer 74
    return providers 
644 chandransh 75
 
7608 rajveer 76
def get_logistics_estimation(destination_pin, item_selling_price, weight, type, billingWarehouseId):
5692 rajveer 77
    logging.info("Getting logistics estimation for pincode:" + destination_pin )
1504 ankur.sing 78
 
7608 rajveer 79
    provider_id, codAllowed, otgAvailable = __get_logistics_provider_for_destination_pincode(destination_pin, item_selling_price, weight, type, billingWarehouseId)
3064 chandransh 80
 
3217 rajveer 81
    if not provider_id:
5692 rajveer 82
        raise LogisticsServiceException(101, "No provider assigned for pincode: " + str(destination_pin))
644 chandransh 83
    try:
5692 rajveer 84
        delivery_time = delivery_estimate_cache[destination_pin, provider_id][0]
6537 rajveer 85
        delivery_delay = delivery_estimate_cache[destination_pin, provider_id][1]
86
        delivery_estimate = _DeliveryEstimateObject(delivery_time, delivery_delay, provider_id, codAllowed, otgAvailable)
3218 rajveer 87
        return delivery_estimate
1504 ankur.sing 88
    except Exception as ex:
89
        print ex
644 chandransh 90
        raise LogisticsServiceException(103, "No Logistics partner listed for this destination pincode and the primary warehouse")
3150 rajveer 91
 
7608 rajveer 92
def __get_logistics_provider_for_destination_pincode(destination_pin, item_selling_price, weight, type, billingWarehouseId):
93
    if billingWarehouseId != 12 and serviceable_location_cache.get(6).has_key(destination_pin):
94
        if weight < 480 and serviceable_location_cache.get(3).has_key(destination_pin) and (type == DeliveryType.PREPAID or item_selling_price < 3000):
7627 rajveer 95
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(3).get(destination_pin)
96
            if item_selling_price <= providerPrepaidLimit:
97
                iscod = iscod and item_selling_price <= websiteCodLimit
98
                otgAvailable = otgAvailable and item_selling_price >= 2000
99
                return 3, iscod, otgAvailable
100
        else:
101
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(6).get(destination_pin)
102
            if item_selling_price <= providerPrepaidLimit:
103
                iscod = iscod and item_selling_price <= websiteCodLimit
104
                otgAvailable = otgAvailable and item_selling_price >= 2000
105
                return 6, iscod, otgAvailable
106
 
107
    if serviceable_location_cache.get(3).has_key(destination_pin):
108
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(3).get(destination_pin)
109
        if item_selling_price <= providerPrepaidLimit:
7608 rajveer 110
            iscod = iscod and item_selling_price <= websiteCodLimit
111
            otgAvailable = otgAvailable and item_selling_price >= 2000
112
            return 3, iscod, otgAvailable
7627 rajveer 113
 
114
    if serviceable_location_cache.get(1).has_key(destination_pin):
115
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(1).get(destination_pin)
116
        if item_selling_price <= providerPrepaidLimit:
7608 rajveer 117
            iscod = iscod and item_selling_price <= websiteCodLimit
118
            otgAvailable = otgAvailable and item_selling_price >= 2000
7627 rajveer 119
            return 1, iscod, otgAvailable
4866 rajveer 120
    else:
7442 vikram.rag 121
        return None, False, False    
5278 rajveer 122
 
6017 amar.kumar 123
def get_destination_code(providerId, pinCode):
124
    serviceableLocationDetail = ServiceableLocationDetails.query.filter_by(provider_id = providerId, dest_pincode = pinCode).one()
125
    return serviceableLocationDetail.dest_code
126
 
644 chandransh 127
def add_empty_AWBs(numbers, provider_id, type):
442 rajveer 128
    for number in numbers:
644 chandransh 129
        query = Awb.query.filter_by(awb_number = number, provider_id = provider_id)
444 rajveer 130
        try:
131
            query.one()
132
        except:    
644 chandransh 133
            awb = Awb()
444 rajveer 134
            awb.awb_number = number
644 chandransh 135
            awb.provider_id = provider_id
444 rajveer 136
            awb.is_available = True
644 chandransh 137
            awb.type = type
138
    session.commit()
442 rajveer 139
 
444 rajveer 140
def set_AWB_as_used(awb_number):
644 chandransh 141
    query = Awb.query.filter_by(awb_number = awb_number)
444 rajveer 142
    awb = query.one() 
143
    awb.is_available=False
144
    session.commit()
145
 
3044 chandransh 146
def get_empty_AWB(provider_id, type = DeliveryType.PREPAID):
2342 chandransh 147
    query = Awb.query.with_lockmode("update").filter_by(provider_id = provider_id, is_available = True)  #check the provider thing
3044 chandransh 148
    if type == DeliveryType.PREPAID:
149
        query = query.filter_by(type="Prepaid")
150
    if type == DeliveryType.COD:
151
        query = query.filter_by(type="COD")
152
 
442 rajveer 153
    try:
644 chandransh 154
        awb = query.first()
155
        awb.is_available = False
156
        session.commit()
444 rajveer 157
        return awb.awb_number
442 rajveer 158
    except:
644 chandransh 159
        raise LogisticsServiceException(103, "Unable to get an AWB for the given Provider: " + str(provider_id))
1137 chandransh 160
 
3103 chandransh 161
def get_free_awb_count(provider_id, type):
162
    count = Awb.query.filter_by(provider_id = provider_id, is_available = True, type=type).count()
1137 chandransh 163
    if count == None:
164
        count = 0
165
    return count
442 rajveer 166
 
644 chandransh 167
def get_shipment_info(awb_number, provider_id):
168
    awb = Awb.get_by(awb_number = awb_number, provider_id = provider_id)
169
    query = AwbUpdate.query.filter_by(awb = awb)
766 rajveer 170
    info = query.all()
171
    return info
172
 
6643 rajveer 173
def store_shipment_info(update):
174
    updates = AwbUpdate.query.filter_by(providerId = update.providerId, awbNumber  = update.awbNumber, location = update.location, date = to_py_date(update.date), status = update.status, description = update.description).all()
175
    if not updates:
176
        dupdate = AwbUpdate()
177
        dupdate.providerId = update.providerId
178
        dupdate.awbNumber  = update.awbNumber
179
        dupdate.location = update.location
180
        dupdate.date = to_py_date(update.date)
181
        dupdate.status = update.status
182
        dupdate.description = update.description
183
        session.commit()
184
 
1730 ankur.sing 185
def get_holidays(start_date, end_date):
186
    query = PublicHolidays.query
187
    if start_date != -1:
188
        query = query.filter(PublicHolidays.date >= to_py_date(start_date))
189
    if end_date != -1:
190
        query = query.filter(PublicHolidays.date <= to_py_date(end_date))
191
    holidays = query.all()
192
    holiday_dates = [to_java_date(datetime.datetime(*time.strptime(str(holiday.date), '%Y-%m-%d')[:3])) for holiday in holidays] 
193
    return holiday_dates
194
 
5527 anupam.sin 195
def get_provider_for_pickup_type(pickUp):
196
    return Provider.query.filter(Provider.pickup == pickUp).first().id
197
 
766 rajveer 198
def close_session():
199
    if session.is_active:
200
        print "session is active. closing it."
2823 chandransh 201
        session.close()
3376 rajveer 202
 
203
def is_alive():
204
    try:
205
        session.query(Awb.id).limit(1).one()
206
        return True
207
    except:
5555 rajveer 208
        return False
209
 
210
def get_all_pickup_stores():
5572 anupam.sin 211
    pickupStores = PickupStore.query.all()
212
    return pickupStores
5555 rajveer 213
 
214
def get_pickup_store(storeId):
5719 rajveer 215
    return PickupStore.query.filter_by(id = storeId).one()
216
 
217
def get_pickup_store_by_hotspot_id(hotspotId):
218
    return PickupStore.query.filter_by(hotspotId = hotspotId).one()
6322 amar.kumar 219
 
6524 rajveer 220
def add_pincode(provider, pincode, destCode, exp, cod, stationType, otgAvailable):
6322 amar.kumar 221
    provider = Provider().query.filter_by(id = provider).one()
222
    serviceableLocationDetails = ServiceableLocationDetails()
223
    serviceableLocationDetails.provider = provider
224
    serviceableLocationDetails.dest_pincode = pincode
225
    serviceableLocationDetails.dest_code = destCode
226
    serviceableLocationDetails.exp = exp
227
    serviceableLocationDetails.cod = cod
228
    serviceableLocationDetails.station_type = stationType
6524 rajveer 229
    serviceableLocationDetails.otgAvailable = otgAvailable
7733 manish.sha 230
    if provider.id == 1:
7627 rajveer 231
        codlimit = 10000
232
        prepaidlimit = 50000
7733 manish.sha 233
    elif provider.id == 3:
7627 rajveer 234
        codlimit = 25000
235
        prepaidlimit = 100000
7733 manish.sha 236
    elif provider.id == 6:
7627 rajveer 237
        codlimit = 25000
238
        prepaidlimit = 100000
239
    serviceableLocationDetails.providerPrepaidLimit = prepaidlimit
240
    serviceableLocationDetails.providerCodLimit = codlimit
241
    serviceableLocationDetails.websiteCodLimit = codlimit
242
    serviceableLocationDetails.storeCodLimit = codlimit
6322 amar.kumar 243
    session.commit()
244
 
6524 rajveer 245
def update_pincode(providerId, pincode, exp, cod, otgAvailable):
6615 amar.kumar 246
    serviceableLocationDetails = ServiceableLocationDetails.get_by(provider_id = providerId, dest_pincode = pincode)
6322 amar.kumar 247
    serviceableLocationDetails.exp = exp
248
    serviceableLocationDetails.cod = cod
6524 rajveer 249
    serviceableLocationDetails.otgAvailable = otgAvailable
7256 rajveer 250
    session.commit()
7567 rajveer 251
 
252
def add_new_awbs(provider_id, isCod, awbs):
253
    provider = get_provider(provider_id)
254
    if isCod:
255
        dtype = 'Cod'
256
    else:
257
        dtype = 'Prepaid'
258
    for awb in awbs:
259
        a = Awb()
260
        a.type =  dtype
261
        a.is_available = True
262
        a.awb_number = awb
263
        a.provider = provider 
264
    session.commit()
7608 rajveer 265
    return True
7256 rajveer 266
 
267
def adjust_delivery_time(start_time, delivery_days):
268
    '''
269
    Returns the actual no. of days which will pass while 'delivery_days'
270
    no. of business days will pass since 'order_time'. 
271
    '''
272
    start_date = start_time.date()
273
    end_date = start_date + datetime.timedelta(days = delivery_days)
7272 amit.gupta 274
    holidays = get_holidays(to_java_date(start_time), -1)
7256 rajveer 275
    holidays = [to_py_date(holiday).date() for holiday in holidays]
276
 
277
    while start_date <= end_date:
278
        if start_date.weekday() == 6 or start_date in holidays:
279
            delivery_days = delivery_days + 1
280
            end_date = end_date + datetime.timedelta(days = 1)
281
        start_date = start_date + datetime.timedelta(days = 1)
282
 
283
    return delivery_days
7275 rajveer 284
 
285
def get_min_advance_amount(itemId, destination_pin, providerId, codAllowed):
286
    client = CatalogClient().get_client()
287
    sp = client.getStorePricing(itemId)
288
 
289
    if codAllowed:
290
        return sp.minAdvancePrice, True
291
    else:
7627 rajveer 292
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(providerId).get(destination_pin)
7275 rajveer 293
        if iscod:
294
            if providerId == 6:
7489 rajveer 295
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 296
            if providerId == 3:
7489 rajveer 297
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 298
            if providerId == 1:
7489 rajveer 299
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 300
        else:
7425 rajveer 301
            return sp.recommendedPrice, False
7733 manish.sha 302
#Start:- Added by Manish Sharma for Multiple Pincode Updation on 05-Jul-2013
303
 
7786 manish.sha 304
def run_Logistics_Location_Info_Update(logisticsLocationInfoList, runCompleteUpdate):
305
    if runCompleteUpdate == True :
306
        serviceableLocationDetails = ServiceableLocationDetails.query.all()
307
        for serviceableLocationDetail in serviceableLocationDetails:
308
            if serviceableLocationDetail.exp :
309
                serviceableLocationDetail.exp = False
310
            if  serviceableLocationDetail.cod :
311
                serviceableLocationDetail.cod = False
312
            if serviceableLocationDetail.otgAvailable :
313
                serviceableLocationDetail.otgAvailable = False
314
    for logisticsLocationInfo in logisticsLocationInfoList:
315
         serviceableLocationDetail = ServiceableLocationDetails.get_by(provider_id = logisticsLocationInfo.providerId, dest_pincode = logisticsLocationInfo.pinCode)
316
         provider = Provider().query.filter_by(id = logisticsLocationInfo.providerId).one()
317
         if serviceableLocationDetail:
318
             serviceableLocationDetail.exp = logisticsLocationInfo.expAvailable
319
             serviceableLocationDetail.cod = logisticsLocationInfo.codAvailable
320
             serviceableLocationDetail.otgAvailable = logisticsLocationInfo.otgAvailable
321
             serviceableLocationDetail.providerCodLimit = logisticsLocationInfo.codLimit
322
             serviceableLocationDetail.providerPrepaidLimit = logisticsLocationInfo.prepaidLimit
323
             serviceableLocationDetail.storeCodLimit = logisticsLocationInfo.codLimit
324
             serviceableLocationDetail.websiteCodLimit = logisticsLocationInfo.codLimit
325
         else:
326
             serviceableLocationDetail= ServiceableLocationDetails()
327
             serviceableLocationDetail.provider = provider
328
             serviceableLocationDetail.dest_pincode = logisticsLocationInfo.pinCode
329
             serviceableLocationDetail.dest_code = logisticsLocationInfo.destinationCode
330
             serviceableLocationDetail.exp = logisticsLocationInfo.expAvailable
331
             serviceableLocationDetail.cod = logisticsLocationInfo.codAvailable
332
             serviceableLocationDetail.station_type = 0
333
             serviceableLocationDetail.otgAvailable = logisticsLocationInfo.otgAvailable
334
             serviceableLocationDetail.providerCodLimit = logisticsLocationInfo.codLimit
335
             serviceableLocationDetail.providerPrepaidLimit = logisticsLocationInfo.prepaidLimit
336
             serviceableLocationDetail.storeCodLimit = logisticsLocationInfo.codLimit
337
             serviceableLocationDetail.websiteCodLimit = logisticsLocationInfo.codLimit
338
         deliveryEstimate = DeliveryEstimate.get_by(provider_id = logisticsLocationInfo.providerId, destination_pin = logisticsLocationInfo.pinCode) 
339
         if deliveryEstimate:
340
             deliveryEstimate.warehouse_location= logisticsLocationInfo.warehouseId
341
             deliveryEstimate.delivery_time= logisticsLocationInfo.deliveryTime
342
             deliveryEstimate.delivery_delay= logisticsLocationInfo.delivery_delay
343
         else:
344
             deliveryEstimate = DeliveryEstimate()
345
             deliveryEstimate.destination_pin= logisticsLocationInfo.pinCode
346
             deliveryEstimate.provider = provider
347
             deliveryEstimate.warehouse_location= logisticsLocationInfo.warehouseId
348
             deliveryEstimate.delivery_time= logisticsLocationInfo.deliveryTime
349
             deliveryEstimate.delivery_delay= logisticsLocationInfo.delivery_delay
7733 manish.sha 350
    session.commit()
7786 manish.sha 351
 
7733 manish.sha 352
#End:- Added by Manish Sharma for Multiple Pincode Updation on 05-Jul-2013             
7275 rajveer 353