Subversion Repositories SmartDukaan

Rev

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