Subversion Repositories SmartDukaan

Rev

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