Subversion Repositories SmartDukaan

Rev

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