Subversion Repositories SmartDukaan

Rev

Rev 10185 | Rev 13146 | 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:
7857 rajveer 50
        delivery_estimate_cache[delivery_estimate.destination_pin, delivery_estimate.provider_id, delivery_estimate.warehouse_location]\
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)
9964 anupam.sin 80
 
81
    if item_selling_price > 60000 or item_selling_price <= 250:
82
        codAllowed = False
83
 
7857 rajveer 84
    warehouse_location = 0
85
    if billingWarehouseId in [12,13]:
86
        warehouse_location = 1
87
 
3217 rajveer 88
    if not provider_id:
5692 rajveer 89
        raise LogisticsServiceException(101, "No provider assigned for pincode: " + str(destination_pin))
644 chandransh 90
    try:
7857 rajveer 91
        delivery_time = delivery_estimate_cache[destination_pin, provider_id, warehouse_location][0]
92
        delivery_delay = delivery_estimate_cache[destination_pin, provider_id, warehouse_location][1]
6537 rajveer 93
        delivery_estimate = _DeliveryEstimateObject(delivery_time, delivery_delay, provider_id, codAllowed, otgAvailable)
3218 rajveer 94
        return delivery_estimate
1504 ankur.sing 95
    except Exception as ex:
96
        print ex
644 chandransh 97
        raise LogisticsServiceException(103, "No Logistics partner listed for this destination pincode and the primary warehouse")
3150 rajveer 98
 
7608 rajveer 99
def __get_logistics_provider_for_destination_pincode(destination_pin, item_selling_price, weight, type, billingWarehouseId):
9154 rajveer 100
    if serviceable_location_cache.get(6).has_key(destination_pin):
101
        if weight < 480 and serviceable_location_cache.get(3).has_key(destination_pin) and type == DeliveryType.PREPAID:
7981 rajveer 102
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(3).get(destination_pin)
103
            if item_selling_price <= providerPrepaidLimit:
104
                iscod = iscod and item_selling_price <= websiteCodLimit
105
                otgAvailable = otgAvailable and item_selling_price >= 2000
106
                return 3, iscod, otgAvailable
107
        else:
108
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(6).get(destination_pin)
109
            if item_selling_price <= providerPrepaidLimit:
110
                iscod = iscod and item_selling_price <= websiteCodLimit
111
                otgAvailable = otgAvailable and item_selling_price >= 2000
112
                return 6, iscod, otgAvailable
113
 
114
    if serviceable_location_cache.get(3).has_key(destination_pin):
115
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(3).get(destination_pin)
7627 rajveer 116
        if item_selling_price <= providerPrepaidLimit:
7608 rajveer 117
            iscod = iscod and item_selling_price <= websiteCodLimit
118
            otgAvailable = otgAvailable and item_selling_price >= 2000
7981 rajveer 119
            return 3, iscod, otgAvailable
8575 rajveer 120
 
121
    if billingWarehouseId not in [12,13] and serviceable_location_cache.get(7).has_key(destination_pin):
122
        if item_selling_price < 3000 and serviceable_location_cache.get(1).has_key(destination_pin):
123
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(1).get(destination_pin)
124
            if item_selling_price <= providerPrepaidLimit:
125
                iscod = iscod and item_selling_price <= websiteCodLimit
126
                otgAvailable = otgAvailable and item_selling_price >= 2000
127
                return 1, iscod, otgAvailable
128
        else:
129
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(7).get(destination_pin)
130
            if item_selling_price <= providerPrepaidLimit:
131
                iscod = iscod and item_selling_price <= websiteCodLimit
132
                otgAvailable = otgAvailable and item_selling_price >= 2000
133
                return 7, iscod, otgAvailable
134
 
7627 rajveer 135
    if serviceable_location_cache.get(1).has_key(destination_pin):
136
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(1).get(destination_pin)
137
        if item_selling_price <= providerPrepaidLimit:
7608 rajveer 138
            iscod = iscod and item_selling_price <= websiteCodLimit
139
            otgAvailable = otgAvailable and item_selling_price >= 2000
7627 rajveer 140
            return 1, iscod, otgAvailable
7981 rajveer 141
 
10185 amit.gupta 142
    return None, False, False    
5278 rajveer 143
 
6017 amar.kumar 144
def get_destination_code(providerId, pinCode):
145
    serviceableLocationDetail = ServiceableLocationDetails.query.filter_by(provider_id = providerId, dest_pincode = pinCode).one()
146
    return serviceableLocationDetail.dest_code
147
 
644 chandransh 148
def add_empty_AWBs(numbers, provider_id, type):
442 rajveer 149
    for number in numbers:
644 chandransh 150
        query = Awb.query.filter_by(awb_number = number, provider_id = provider_id)
444 rajveer 151
        try:
152
            query.one()
153
        except:    
644 chandransh 154
            awb = Awb()
444 rajveer 155
            awb.awb_number = number
644 chandransh 156
            awb.provider_id = provider_id
444 rajveer 157
            awb.is_available = True
644 chandransh 158
            awb.type = type
159
    session.commit()
442 rajveer 160
 
444 rajveer 161
def set_AWB_as_used(awb_number):
644 chandransh 162
    query = Awb.query.filter_by(awb_number = awb_number)
444 rajveer 163
    awb = query.one() 
164
    awb.is_available=False
165
    session.commit()
166
 
3044 chandransh 167
def get_empty_AWB(provider_id, type = DeliveryType.PREPAID):
2342 chandransh 168
    query = Awb.query.with_lockmode("update").filter_by(provider_id = provider_id, is_available = True)  #check the provider thing
3044 chandransh 169
    if type == DeliveryType.PREPAID:
170
        query = query.filter_by(type="Prepaid")
171
    if type == DeliveryType.COD:
172
        query = query.filter_by(type="COD")
173
 
442 rajveer 174
    try:
644 chandransh 175
        awb = query.first()
176
        awb.is_available = False
177
        session.commit()
444 rajveer 178
        return awb.awb_number
442 rajveer 179
    except:
644 chandransh 180
        raise LogisticsServiceException(103, "Unable to get an AWB for the given Provider: " + str(provider_id))
1137 chandransh 181
 
3103 chandransh 182
def get_free_awb_count(provider_id, type):
183
    count = Awb.query.filter_by(provider_id = provider_id, is_available = True, type=type).count()
1137 chandransh 184
    if count == None:
185
        count = 0
186
    return count
442 rajveer 187
 
644 chandransh 188
def get_shipment_info(awb_number, provider_id):
189
    awb = Awb.get_by(awb_number = awb_number, provider_id = provider_id)
190
    query = AwbUpdate.query.filter_by(awb = awb)
766 rajveer 191
    info = query.all()
192
    return info
193
 
6643 rajveer 194
def store_shipment_info(update):
195
    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()
196
    if not updates:
197
        dupdate = AwbUpdate()
198
        dupdate.providerId = update.providerId
199
        dupdate.awbNumber  = update.awbNumber
200
        dupdate.location = update.location
201
        dupdate.date = to_py_date(update.date)
202
        dupdate.status = update.status
203
        dupdate.description = update.description
204
        session.commit()
205
 
1730 ankur.sing 206
def get_holidays(start_date, end_date):
207
    query = PublicHolidays.query
208
    if start_date != -1:
209
        query = query.filter(PublicHolidays.date >= to_py_date(start_date))
210
    if end_date != -1:
211
        query = query.filter(PublicHolidays.date <= to_py_date(end_date))
212
    holidays = query.all()
213
    holiday_dates = [to_java_date(datetime.datetime(*time.strptime(str(holiday.date), '%Y-%m-%d')[:3])) for holiday in holidays] 
214
    return holiday_dates
215
 
5527 anupam.sin 216
def get_provider_for_pickup_type(pickUp):
217
    return Provider.query.filter(Provider.pickup == pickUp).first().id
218
 
766 rajveer 219
def close_session():
220
    if session.is_active:
221
        print "session is active. closing it."
2823 chandransh 222
        session.close()
3376 rajveer 223
 
224
def is_alive():
225
    try:
226
        session.query(Awb.id).limit(1).one()
227
        return True
228
    except:
5555 rajveer 229
        return False
230
 
231
def get_all_pickup_stores():
5572 anupam.sin 232
    pickupStores = PickupStore.query.all()
233
    return pickupStores
5555 rajveer 234
 
235
def get_pickup_store(storeId):
5719 rajveer 236
    return PickupStore.query.filter_by(id = storeId).one()
237
 
238
def get_pickup_store_by_hotspot_id(hotspotId):
239
    return PickupStore.query.filter_by(hotspotId = hotspotId).one()
6322 amar.kumar 240
 
6524 rajveer 241
def add_pincode(provider, pincode, destCode, exp, cod, stationType, otgAvailable):
7914 rajveer 242
    provider = Provider.query.filter_by(id = provider).one()
6322 amar.kumar 243
    serviceableLocationDetails = ServiceableLocationDetails()
244
    serviceableLocationDetails.provider = provider
245
    serviceableLocationDetails.dest_pincode = pincode
246
    serviceableLocationDetails.dest_code = destCode
247
    serviceableLocationDetails.exp = exp
248
    serviceableLocationDetails.cod = cod
249
    serviceableLocationDetails.station_type = stationType
6524 rajveer 250
    serviceableLocationDetails.otgAvailable = otgAvailable
7733 manish.sha 251
    if provider.id == 1:
7627 rajveer 252
        codlimit = 10000
253
        prepaidlimit = 50000
7733 manish.sha 254
    elif provider.id == 3:
7627 rajveer 255
        codlimit = 25000
256
        prepaidlimit = 100000
7733 manish.sha 257
    elif provider.id == 6:
7627 rajveer 258
        codlimit = 25000
259
        prepaidlimit = 100000
260
    serviceableLocationDetails.providerPrepaidLimit = prepaidlimit
261
    serviceableLocationDetails.providerCodLimit = codlimit
262
    serviceableLocationDetails.websiteCodLimit = codlimit
263
    serviceableLocationDetails.storeCodLimit = codlimit
6322 amar.kumar 264
    session.commit()
265
 
6524 rajveer 266
def update_pincode(providerId, pincode, exp, cod, otgAvailable):
6615 amar.kumar 267
    serviceableLocationDetails = ServiceableLocationDetails.get_by(provider_id = providerId, dest_pincode = pincode)
6322 amar.kumar 268
    serviceableLocationDetails.exp = exp
269
    serviceableLocationDetails.cod = cod
6524 rajveer 270
    serviceableLocationDetails.otgAvailable = otgAvailable
7256 rajveer 271
    session.commit()
7567 rajveer 272
 
273
def add_new_awbs(provider_id, isCod, awbs):
274
    provider = get_provider(provider_id)
275
    if isCod:
276
        dtype = 'Cod'
277
    else:
278
        dtype = 'Prepaid'
279
    for awb in awbs:
280
        a = Awb()
281
        a.type =  dtype
282
        a.is_available = True
283
        a.awb_number = awb
284
        a.provider = provider 
285
    session.commit()
7608 rajveer 286
    return True
7256 rajveer 287
 
288
def adjust_delivery_time(start_time, delivery_days):
289
    '''
290
    Returns the actual no. of days which will pass while 'delivery_days'
291
    no. of business days will pass since 'order_time'. 
292
    '''
293
    start_date = start_time.date()
294
    end_date = start_date + datetime.timedelta(days = delivery_days)
7272 amit.gupta 295
    holidays = get_holidays(to_java_date(start_time), -1)
7256 rajveer 296
    holidays = [to_py_date(holiday).date() for holiday in holidays]
297
 
298
    while start_date <= end_date:
299
        if start_date.weekday() == 6 or start_date in holidays:
300
            delivery_days = delivery_days + 1
301
            end_date = end_date + datetime.timedelta(days = 1)
302
        start_date = start_date + datetime.timedelta(days = 1)
303
 
304
    return delivery_days
7275 rajveer 305
 
306
def get_min_advance_amount(itemId, destination_pin, providerId, codAllowed):
307
    client = CatalogClient().get_client()
308
    sp = client.getStorePricing(itemId)
309
 
310
    if codAllowed:
311
        return sp.minAdvancePrice, True
312
    else:
7857 rajveer 313
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit = serviceable_location_cache.get(providerId).get(destination_pin)
7275 rajveer 314
        if iscod:
315
            if providerId == 6:
7489 rajveer 316
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 317
            if providerId == 3:
7489 rajveer 318
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 319
            if providerId == 1:
7489 rajveer 320
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 321
        else:
7425 rajveer 322
            return sp.recommendedPrice, False
7733 manish.sha 323
#Start:- Added by Manish Sharma for Multiple Pincode Updation on 05-Jul-2013
324
 
7786 manish.sha 325
def run_Logistics_Location_Info_Update(logisticsLocationInfoList, runCompleteUpdate):
326
    if runCompleteUpdate == True :
327
        serviceableLocationDetails = ServiceableLocationDetails.query.all()
328
        for serviceableLocationDetail in serviceableLocationDetails:
7841 manish.sha 329
            serviceableLocationDetail.exp = False
330
            serviceableLocationDetail.cod = False
7786 manish.sha 331
    for logisticsLocationInfo in logisticsLocationInfoList:
7841 manish.sha 332
        serviceableLocationDetail = ServiceableLocationDetails.get_by(provider_id = logisticsLocationInfo.providerId, dest_pincode = logisticsLocationInfo.pinCode)
7914 rajveer 333
        provider = Provider.query.filter_by(id = logisticsLocationInfo.providerId).one()
7841 manish.sha 334
        if serviceableLocationDetail:
335
            serviceableLocationDetail.exp = logisticsLocationInfo.expAvailable
336
            serviceableLocationDetail.cod = logisticsLocationInfo.codAvailable
337
            serviceableLocationDetail.otgAvailable = logisticsLocationInfo.otgAvailable
338
            serviceableLocationDetail.providerCodLimit = logisticsLocationInfo.codLimit
339
            serviceableLocationDetail.providerPrepaidLimit = logisticsLocationInfo.prepaidLimit
340
            serviceableLocationDetail.storeCodLimit = logisticsLocationInfo.codLimit
8219 manish.sha 341
            serviceableLocationDetail.websiteCodLimit = min(26000,logisticsLocationInfo.codLimit)
7841 manish.sha 342
        else:
343
            serviceableLocationDetail= ServiceableLocationDetails()
344
            serviceableLocationDetail.provider = provider
345
            serviceableLocationDetail.dest_pincode = logisticsLocationInfo.pinCode
346
            serviceableLocationDetail.dest_code = logisticsLocationInfo.destinationCode
347
            serviceableLocationDetail.exp = logisticsLocationInfo.expAvailable
348
            serviceableLocationDetail.cod = logisticsLocationInfo.codAvailable
349
            serviceableLocationDetail.station_type = 0
350
            serviceableLocationDetail.otgAvailable = logisticsLocationInfo.otgAvailable
351
            serviceableLocationDetail.providerCodLimit = logisticsLocationInfo.codLimit
352
            serviceableLocationDetail.providerPrepaidLimit = logisticsLocationInfo.prepaidLimit
353
            serviceableLocationDetail.storeCodLimit = logisticsLocationInfo.codLimit
8219 manish.sha 354
            serviceableLocationDetail.websiteCodLimit = min(26000,logisticsLocationInfo.codLimit)
7841 manish.sha 355
 
7870 rajveer 356
        deliveryEstimate = DeliveryEstimate.get_by(provider_id = logisticsLocationInfo.providerId, destination_pin = logisticsLocationInfo.pinCode, warehouse_location = logisticsLocationInfo.warehouseId) 
7841 manish.sha 357
        if deliveryEstimate:
358
            deliveryEstimate.warehouse_location= logisticsLocationInfo.warehouseId
359
            deliveryEstimate.delivery_time= logisticsLocationInfo.deliveryTime
360
            deliveryEstimate.delivery_delay= logisticsLocationInfo.delivery_delay
361
        else:
362
            deliveryEstimate = DeliveryEstimate()
363
            deliveryEstimate.destination_pin= logisticsLocationInfo.pinCode
364
            deliveryEstimate.provider = provider
365
            deliveryEstimate.warehouse_location= logisticsLocationInfo.warehouseId
366
            deliveryEstimate.delivery_time= logisticsLocationInfo.deliveryTime
367
            deliveryEstimate.delivery_delay= logisticsLocationInfo.delivery_delay
7733 manish.sha 368
    session.commit()
7786 manish.sha 369
 
7733 manish.sha 370
#End:- Added by Manish Sharma for Multiple Pincode Updation on 05-Jul-2013             
7275 rajveer 371
 
12895 manish.sha 372
def get_first_delivery_estimate_for_wh_location(pincode, whLocation):
373
    delEstimate = DeliveryEstimate.query.filter(DeliveryEstimate.destination_pin == pincode).filter(DeliveryEstimate.warehouse_location == whLocation).first()
374
    if delEstimate is None:
375
        return -1
376
    else:
377
        return 1
378