Subversion Repositories SmartDukaan

Rev

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