Subversion Repositories SmartDukaan

Rev

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