Subversion Repositories SmartDukaan

Rev

Rev 19420 | Rev 19474 | 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
 
16025 amit.gupta 7
from elixir import session
8
from shop2020.clients.CatalogClient import CatalogClient
9
from shop2020.clients.InventoryClient import InventoryClient
442 rajveer 10
from shop2020.logistics.service.impl import DataService
644 chandransh 11
from shop2020.logistics.service.impl.DataService import Awb, AwbUpdate, Provider, \
16025 amit.gupta 12
    DeliveryEstimate, WarehouseAllocation, PublicHolidays, \
19421 manish.sha 13
    ServiceableLocationDetails, PickupStore, Locations, ProviderCosting
16025 amit.gupta 14
from shop2020.thriftpy.logistics.ttypes import LogisticsServiceException, \
19421 manish.sha 15
    DeliveryType, LogisticsLocationInfo, LocationInfo, ProviderInfo, DeliveryEstimateAndCosting
19413 amit.gupta 16
from shop2020.thriftpy.model.v1.inventory.ttypes import Warehouse, BillingType, \
16025 amit.gupta 17
    WarehouseType
442 rajveer 18
from shop2020.utils.Utils import log_entry, to_py_date, to_java_date
5964 amar.kumar 19
from sqlalchemy.sql import or_
16025 amit.gupta 20
import datetime
3355 chandransh 21
import logging
13146 manish.sha 22
import os
16025 amit.gupta 23
import sys
24
import time
19413 amit.gupta 25
from collections import namedtuple
26
 
3355 chandransh 27
logging.basicConfig(level=logging.DEBUG)
442 rajveer 28
 
19413 amit.gupta 29
PincodeProvider = namedtuple("PincodeProvider", ["dest_pin", "provider"])
30
 
3217 rajveer 31
warehouse_allocation_cache = {}
32
serviceable_location_cache = {}
33
delivery_estimate_cache = {}
16025 amit.gupta 34
warehouse_location_cache = {}
19413 amit.gupta 35
location_state={}
36
state_locations = {}
19421 manish.sha 37
provider_costing_sheet = {}
38
DELHIVERY = 3
6370 rajveer 39
 
19413 amit.gupta 40
#pincode location map is ab
41
#{'110001':{1:{"sameState":False, "providerInfo":{1:(1,1), 2:(1,1)}}},}
42
pincode_locations = {}
43
#{(dest_pin, provider):(otgAvailable,providerCodLimit, websiteCodLimit, storeCodLimit, providerPrepaidLimit)} 
44
serviceable_map = {}
45
 
46
#Need to identify a better way
47
statepinmap={'11':0, 
48
             '40':1,'41':1,'42':1,'43':1,'44':1,
49
             '56':2, '57':2, '58':2, '59':2,
50
             '12':3, '13':3, 
51
             '30':4, '31':4, '32':4, '33':4, '34':4,
52
             '36':6,'37':6,'38':6,'39':6
53
             }
54
 
3218 rajveer 55
'''
56
This class is for only data transfer. Never used outside this module.
57
'''
58
class _DeliveryEstimateObject:
6537 rajveer 59
    def __init__(self, delivery_time, delivery_delay, provider_id, codAllowed, otgAvailable):
3218 rajveer 60
        self.delivery_time = delivery_time
6537 rajveer 61
        self.delivery_delay = delivery_delay
3218 rajveer 62
        self.provider_id = provider_id
4866 rajveer 63
        self.codAllowed = codAllowed
6524 rajveer 64
        self.otgAvailable = otgAvailable
3218 rajveer 65
 
3187 rajveer 66
def initialize(dbname="logistics", db_hostname="localhost"):
442 rajveer 67
    log_entry("initialize@DataAccessor", "Initializing data service")
3187 rajveer 68
    DataService.initialize(dbname, db_hostname)
3218 rajveer 69
    print "Starting cache population at: " + str(datetime.datetime.now())
16025 amit.gupta 70
    #__cache_warehouse_allocation_table()
71
    __cache_warehouse_locations()
3217 rajveer 72
    __cache_serviceable_location_details_table()
73
    __cache_delivery_estimate_table()
19413 amit.gupta 74
    __cache_locations()
75
    __cache_pincode_estimates()    
19421 manish.sha 76
    __cache_courier_costing_table()
3217 rajveer 77
    close_session()
3218 rajveer 78
    print "Done cache population at: " + str(datetime.datetime.now())
442 rajveer 79
 
19413 amit.gupta 80
def __cache_locations():
81
    locations = Locations.query.all()
82
    for location in locations:
83
        location_state[location.id] = location.state_id
84
        if not state_locations.has_key(location.state_id):
85
            state_locations[location.state_id] = []
86
        state_locations[location.state_id] = state_locations[location.state_id].append(location.state_id)
87
 
88
def __cache_pincode_estimates():
89
    delivery_estimates = DeliveryEstimate.query.all()
90
    for delivery_estimate in delivery_estimates:
91
        if not pincode_locations.has_key(delivery_estimate.destination_pin):
92
            pincode_locations[delivery_estimate.destination_pin] = {}
93
        destination_pinMap = pincode_locations[delivery_estimate.destination_pin] 
94
        if not destination_pinMap.has_key(delivery_estimate.warehouse_location):
95
            destination_pinMap[delivery_estimate.warehouse_location] = {}
96
            state_id = location_state.get(delivery_estimate.warehouse_location)
97
            sameState = __getStateFromPin(delivery_estimate.destination_pin) == state_id
98
            destination_pinMap[delivery_estimate.warehouse_location]['sameState']=sameState
99
            destination_pinMap[delivery_estimate.warehouse_location]['providerInfo'] = {} 
100
        destination_pinMap[delivery_estimate.warehouse_location]['providerInfo'][delivery_estimate.provider_id] = delivery_estimate.delivery_time + delivery_estimate.delivery_delay
101
 
102
 
103
 
104
def __cache_pincode_provider_serviceability():
105
    pincode_providers = ServiceableLocationDetails.query.filter(ServiceableLocationDetails.exp==1)
106
    for pp in pincode_providers:
107
        serviceable_map[PincodeProvider(pp.dest_pincode, pp.provider_id)] = (pp.cod, pp.otgAvailable,pp.providerCodLimit, pp.websiteCodLimit, pp.storeCodLimit, pp.providerPrepaidLimit)
108
 
109
 
3217 rajveer 110
def __cache_delivery_estimate_table():
111
    delivery_estimates = DeliveryEstimate.query.all()
112
    for delivery_estimate in delivery_estimates:
7857 rajveer 113
        delivery_estimate_cache[delivery_estimate.destination_pin, delivery_estimate.provider_id, delivery_estimate.warehouse_location]\
19421 manish.sha 114
        =delivery_estimate.delivery_time, delivery_estimate.delivery_delay, delivery_estimate.providerZoneCode
3217 rajveer 115
 
116
def __cache_serviceable_location_details_table():
5964 amar.kumar 117
    serviceable_locations = ServiceableLocationDetails.query.filter(or_("exp!=0","cod!=0"))
3217 rajveer 118
    for serviceable_location in serviceable_locations:
119
        try:
120
            provider_pincodes = serviceable_location_cache[serviceable_location.provider_id]
121
        except:
122
            provider_pincodes = {}
123
            serviceable_location_cache[serviceable_location.provider_id] = provider_pincodes 
7627 rajveer 124
        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 125
 
126
def __cache_warehouse_allocation_table():
127
    warehouse_allocations = WarehouseAllocation.query.all()
128
    for warehouse_allocation in warehouse_allocations:
129
        warehouse_allocation_cache[warehouse_allocation.pincode]=warehouse_allocation.primary_warehouse_location
130
 
16025 amit.gupta 131
def __cache_warehouse_locations():
132
    client = InventoryClient().get_client()
19413 amit.gupta 133
    #client.getAllWarehouses(True)
16025 amit.gupta 134
    for warehouse in client.getAllWarehouses(True):
135
        warehouse_location_cache[warehouse.billingWarehouseId]=warehouse.logisticsLocation
19421 manish.sha 136
 
137
def __cache_courier_costing_table():
138
    allCostings = ProviderCosting.query.all()
139
    for costing in allCostings:
140
        if provider_costing_sheet.has_key(costing.provider_id):
141
            costingMap = provider_costing_sheet.get(costing.provider_id)
142
            costingMap[costing.zoneCode] = costing
143
            provider_costing_sheet[costing.provider_id] = costingMap
144
        else:
145
            costingMap = {}
146
            costingMap[costing.zoneCode] = costing
147
            provider_costing_sheet[costing.provider_id] = costingMap
148
 
16025 amit.gupta 149
 
644 chandransh 150
def get_provider(provider_id):
766 rajveer 151
    provider =  Provider.get_by(id=provider_id)
152
    return provider
644 chandransh 153
 
154
def get_providers():
5387 rajveer 155
    providers = Provider.query.filter_by(isActive = 1).all()
19413 amit.gupta 156
    return providers
644 chandransh 157
 
19413 amit.gupta 158
#it would return only states where our warehouses are present else return -1
159
def __getStateFromPin(pin):
160
    if pin[:3] in ['744', '682']:
161
        return -1
162
    elif statepinmap.has_key(pin[:2]):
163
        return statepinmap[pin[:2]]
164
    else:
165
        return -1
166
 
167
 
168
def get_logistics_locations(destination_pin, selling_price_list):
169
    #pincode_locations = {1:{"sameState":False, "providerInfo":{<provider_id>:<delay_days>}},}
170
    #pp.otgAvailable,pp.providerCodLimit, pp.websiteCodLimit, pp.storeCodLimit, pp.providerPrepaidLimit
171
    returnMap = {}
172
    if pincode_locations.has_key(destination_pin):
173
        locations = pincode_locations[destination_pin]
174
        for item_selling_price in selling_price_list:
175
            returnMap[item_selling_price] = {}
176
            for location_id, value in locations.iteritems():
177
                returnMap[item_selling_price][location_id] = LocationInfo(locationId = location_id, sameState=value['sameState'])
178
                #put weight logic here
179
                otgAvailable = False
180
                codAvailable = False
181
                minDelay = -1
182
                maxDelay = -1
183
                serviceable = False
184
                for provider_id, delay_days in value['providerInfo'].iteritems():
19420 amit.gupta 185
                    pp = PincodeProvider(destination_pin, provider_id)
186
                    if not serviceable_map.has_key(pp):
187
                        continue
188
                    iscod, isotg, providerCodLimit, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_map[pp]  
19413 amit.gupta 189
                    if item_selling_price <= providerPrepaidLimit:
190
                        if not serviceable:
191
                            serviceable = True
192
                            minDelay = delay_days
193
                            maxDelay = delay_days
194
                        else:
195
                            minDelay = min(delay_days,minDelay)
196
                            maxDelay = max(delay_days,maxDelay)
197
                        iscod = iscod and item_selling_price <= min(providerCodLimit, websiteCodLimit)
198
                        isotg = (isotg and item_selling_price >= 2000)
199
                        otgAvailable = otgAvailable or isotg
200
                        codAvailable = codAvailable or iscod
201
                if serviceable:        
202
                    returnMap[item_selling_price][location_id].otgAvailable = otgAvailable
203
                    returnMap[item_selling_price][location_id].codAvailable = codAvailable
204
                    returnMap[item_selling_price][location_id].minDelay = minDelay
205
                    returnMap[item_selling_price][location_id].maxDelay = maxDelay
206
    return returnMap
207
 
7608 rajveer 208
def get_logistics_estimation(destination_pin, item_selling_price, weight, type, billingWarehouseId):
5692 rajveer 209
    logging.info("Getting logistics estimation for pincode:" + destination_pin )
1504 ankur.sing 210
 
7608 rajveer 211
    provider_id, codAllowed, otgAvailable = __get_logistics_provider_for_destination_pincode(destination_pin, item_selling_price, weight, type, billingWarehouseId)
9964 anupam.sin 212
 
17530 manish.sha 213
    logging.info("Provider Id:  " + str(provider_id) +" codAllowed: "+str(codAllowed)+" otgAvailable: "+str(otgAvailable)+ " item_selling_price: "+str(item_selling_price))
214
 
215
    if item_selling_price > 60000:# or item_selling_price <= 250:
9964 anupam.sin 216
        codAllowed = False
217
 
16025 amit.gupta 218
    warehouse_location = warehouse_location_cache.get(billingWarehouseId)
219
    if warehouse_location is None:
220
        warehouse_location = 0
7857 rajveer 221
 
3217 rajveer 222
    if not provider_id:
5692 rajveer 223
        raise LogisticsServiceException(101, "No provider assigned for pincode: " + str(destination_pin))
644 chandransh 224
    try:
16025 amit.gupta 225
        logging.info( "destination_pin %s, provider_id %s, warehouse_location %s"%(destination_pin, provider_id, warehouse_location))
226
        logging.info( "Estimates %s, %s"%(delivery_estimate_cache[destination_pin, provider_id, warehouse_location]))
7857 rajveer 227
        delivery_time = delivery_estimate_cache[destination_pin, provider_id, warehouse_location][0]
228
        delivery_delay = delivery_estimate_cache[destination_pin, provider_id, warehouse_location][1]
6537 rajveer 229
        delivery_estimate = _DeliveryEstimateObject(delivery_time, delivery_delay, provider_id, codAllowed, otgAvailable)
3218 rajveer 230
        return delivery_estimate
1504 ankur.sing 231
    except Exception as ex:
232
        print ex
644 chandransh 233
        raise LogisticsServiceException(103, "No Logistics partner listed for this destination pincode and the primary warehouse")
3150 rajveer 234
 
7608 rajveer 235
def __get_logistics_provider_for_destination_pincode(destination_pin, item_selling_price, weight, type, billingWarehouseId):
13357 manish.sha 236
    '''
237
    if serviceable_location_cache.get(6).has_key(destination_pin):
238
        if weight < 480 and serviceable_location_cache.get(3).has_key(destination_pin) and type == DeliveryType.PREPAID:
239
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(3).get(destination_pin)
240
            if item_selling_price <= providerPrepaidLimit:
241
                iscod = iscod and item_selling_price <= websiteCodLimit
242
                otgAvailable = otgAvailable and item_selling_price >= 2000
243
                return 3, iscod, otgAvailable
244
        else:
245
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(6).get(destination_pin)
246
            if item_selling_price <= providerPrepaidLimit:
247
                iscod = iscod and item_selling_price <= websiteCodLimit
248
                otgAvailable = otgAvailable and item_selling_price >= 2000
249
                return 6, iscod, otgAvailable
250
    '''        
7981 rajveer 251
    if serviceable_location_cache.get(3).has_key(destination_pin):
252
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(3).get(destination_pin)
7627 rajveer 253
        if item_selling_price <= providerPrepaidLimit:
7608 rajveer 254
            iscod = iscod and item_selling_price <= websiteCodLimit
255
            otgAvailable = otgAvailable and item_selling_price >= 2000
7981 rajveer 256
            return 3, iscod, otgAvailable
8575 rajveer 257
 
17992 manish.sha 258
    if billingWarehouseId not in [12,13] and serviceable_location_cache.has_key(7) and serviceable_location_cache.get(7).has_key(destination_pin):
8575 rajveer 259
        if item_selling_price < 3000 and serviceable_location_cache.get(1).has_key(destination_pin):
260
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(1).get(destination_pin)
261
            if item_selling_price <= providerPrepaidLimit:
262
                iscod = iscod and item_selling_price <= websiteCodLimit
263
                otgAvailable = otgAvailable and item_selling_price >= 2000
264
                return 1, iscod, otgAvailable
265
        else:
266
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(7).get(destination_pin)
267
            if item_selling_price <= providerPrepaidLimit:
268
                iscod = iscod and item_selling_price <= websiteCodLimit
269
                otgAvailable = otgAvailable and item_selling_price >= 2000
270
                return 7, iscod, otgAvailable
271
 
7627 rajveer 272
    if serviceable_location_cache.get(1).has_key(destination_pin):
273
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(1).get(destination_pin)
274
        if item_selling_price <= providerPrepaidLimit:
7608 rajveer 275
            iscod = iscod and item_selling_price <= websiteCodLimit
276
            otgAvailable = otgAvailable and item_selling_price >= 2000
7627 rajveer 277
            return 1, iscod, otgAvailable
7981 rajveer 278
 
10185 amit.gupta 279
    return None, False, False    
5278 rajveer 280
 
6017 amar.kumar 281
def get_destination_code(providerId, pinCode):
282
    serviceableLocationDetail = ServiceableLocationDetails.query.filter_by(provider_id = providerId, dest_pincode = pinCode).one()
283
    return serviceableLocationDetail.dest_code
284
 
644 chandransh 285
def add_empty_AWBs(numbers, provider_id, type):
442 rajveer 286
    for number in numbers:
644 chandransh 287
        query = Awb.query.filter_by(awb_number = number, provider_id = provider_id)
444 rajveer 288
        try:
289
            query.one()
290
        except:    
644 chandransh 291
            awb = Awb()
444 rajveer 292
            awb.awb_number = number
644 chandransh 293
            awb.provider_id = provider_id
444 rajveer 294
            awb.is_available = True
644 chandransh 295
            awb.type = type
296
    session.commit()
19413 amit.gupta 297
 
298
def get_pincode_item_serviceability():
299
    pass
442 rajveer 300
 
444 rajveer 301
def set_AWB_as_used(awb_number):
644 chandransh 302
    query = Awb.query.filter_by(awb_number = awb_number)
444 rajveer 303
    awb = query.one() 
304
    awb.is_available=False
305
    session.commit()
306
 
3044 chandransh 307
def get_empty_AWB(provider_id, type = DeliveryType.PREPAID):
2342 chandransh 308
    query = Awb.query.with_lockmode("update").filter_by(provider_id = provider_id, is_available = True)  #check the provider thing
3044 chandransh 309
    if type == DeliveryType.PREPAID:
310
        query = query.filter_by(type="Prepaid")
311
    if type == DeliveryType.COD:
312
        query = query.filter_by(type="COD")
313
 
13158 manish.sha 314
    additionalQuery = query
315
    query = query.filter_by(awbUsedFor=0)
316
 
442 rajveer 317
    try:
644 chandransh 318
        awb = query.first()
13158 manish.sha 319
        if awb is None:
320
            additionalQuery = additionalQuery.filter_by(awbUsedFor=2)
321
            awb = additionalQuery.first()
644 chandransh 322
        awb.is_available = False
323
        session.commit()
444 rajveer 324
        return awb.awb_number
442 rajveer 325
    except:
644 chandransh 326
        raise LogisticsServiceException(103, "Unable to get an AWB for the given Provider: " + str(provider_id))
1137 chandransh 327
 
3103 chandransh 328
def get_free_awb_count(provider_id, type):
329
    count = Awb.query.filter_by(provider_id = provider_id, is_available = True, type=type).count()
1137 chandransh 330
    if count == None:
331
        count = 0
332
    return count
442 rajveer 333
 
644 chandransh 334
def get_shipment_info(awb_number, provider_id):
335
    awb = Awb.get_by(awb_number = awb_number, provider_id = provider_id)
336
    query = AwbUpdate.query.filter_by(awb = awb)
766 rajveer 337
    info = query.all()
338
    return info
339
 
6643 rajveer 340
def store_shipment_info(update):
341
    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()
342
    if not updates:
343
        dupdate = AwbUpdate()
344
        dupdate.providerId = update.providerId
345
        dupdate.awbNumber  = update.awbNumber
346
        dupdate.location = update.location
347
        dupdate.date = to_py_date(update.date)
348
        dupdate.status = update.status
349
        dupdate.description = update.description
350
        session.commit()
351
 
1730 ankur.sing 352
def get_holidays(start_date, end_date):
353
    query = PublicHolidays.query
354
    if start_date != -1:
355
        query = query.filter(PublicHolidays.date >= to_py_date(start_date))
356
    if end_date != -1:
357
        query = query.filter(PublicHolidays.date <= to_py_date(end_date))
358
    holidays = query.all()
359
    holiday_dates = [to_java_date(datetime.datetime(*time.strptime(str(holiday.date), '%Y-%m-%d')[:3])) for holiday in holidays] 
360
    return holiday_dates
361
 
5527 anupam.sin 362
def get_provider_for_pickup_type(pickUp):
363
    return Provider.query.filter(Provider.pickup == pickUp).first().id
364
 
766 rajveer 365
def close_session():
366
    if session.is_active:
367
        print "session is active. closing it."
2823 chandransh 368
        session.close()
3376 rajveer 369
 
370
def is_alive():
371
    try:
372
        session.query(Awb.id).limit(1).one()
373
        return True
374
    except:
5555 rajveer 375
        return False
376
 
377
def get_all_pickup_stores():
5572 anupam.sin 378
    pickupStores = PickupStore.query.all()
379
    return pickupStores
5555 rajveer 380
 
381
def get_pickup_store(storeId):
5719 rajveer 382
    return PickupStore.query.filter_by(id = storeId).one()
383
 
384
def get_pickup_store_by_hotspot_id(hotspotId):
385
    return PickupStore.query.filter_by(hotspotId = hotspotId).one()
6322 amar.kumar 386
 
6524 rajveer 387
def add_pincode(provider, pincode, destCode, exp, cod, stationType, otgAvailable):
7914 rajveer 388
    provider = Provider.query.filter_by(id = provider).one()
6322 amar.kumar 389
    serviceableLocationDetails = ServiceableLocationDetails()
390
    serviceableLocationDetails.provider = provider
391
    serviceableLocationDetails.dest_pincode = pincode
392
    serviceableLocationDetails.dest_code = destCode
393
    serviceableLocationDetails.exp = exp
394
    serviceableLocationDetails.cod = cod
395
    serviceableLocationDetails.station_type = stationType
6524 rajveer 396
    serviceableLocationDetails.otgAvailable = otgAvailable
7733 manish.sha 397
    if provider.id == 1:
7627 rajveer 398
        codlimit = 10000
399
        prepaidlimit = 50000
7733 manish.sha 400
    elif provider.id == 3:
7627 rajveer 401
        codlimit = 25000
402
        prepaidlimit = 100000
7733 manish.sha 403
    elif provider.id == 6:
7627 rajveer 404
        codlimit = 25000
405
        prepaidlimit = 100000
406
    serviceableLocationDetails.providerPrepaidLimit = prepaidlimit
407
    serviceableLocationDetails.providerCodLimit = codlimit
408
    serviceableLocationDetails.websiteCodLimit = codlimit
409
    serviceableLocationDetails.storeCodLimit = codlimit
6322 amar.kumar 410
    session.commit()
411
 
6524 rajveer 412
def update_pincode(providerId, pincode, exp, cod, otgAvailable):
6615 amar.kumar 413
    serviceableLocationDetails = ServiceableLocationDetails.get_by(provider_id = providerId, dest_pincode = pincode)
6322 amar.kumar 414
    serviceableLocationDetails.exp = exp
415
    serviceableLocationDetails.cod = cod
6524 rajveer 416
    serviceableLocationDetails.otgAvailable = otgAvailable
7256 rajveer 417
    session.commit()
7567 rajveer 418
 
13146 manish.sha 419
def add_new_awbs(provider_id, isCod, awbs, awbUsedFor):
7567 rajveer 420
    provider = get_provider(provider_id)
421
    if isCod:
422
        dtype = 'Cod'
423
    else:
424
        dtype = 'Prepaid'
425
    for awb in awbs:
426
        a = Awb()
427
        a.type =  dtype
428
        a.is_available = True
429
        a.awb_number = awb
13146 manish.sha 430
        a.awbUsedFor = awbUsedFor
7567 rajveer 431
        a.provider = provider 
432
    session.commit()
7608 rajveer 433
    return True
7256 rajveer 434
 
435
def adjust_delivery_time(start_time, delivery_days):
436
    '''
437
    Returns the actual no. of days which will pass while 'delivery_days'
438
    no. of business days will pass since 'order_time'. 
439
    '''
440
    start_date = start_time.date()
441
    end_date = start_date + datetime.timedelta(days = delivery_days)
7272 amit.gupta 442
    holidays = get_holidays(to_java_date(start_time), -1)
7256 rajveer 443
    holidays = [to_py_date(holiday).date() for holiday in holidays]
444
 
445
    while start_date <= end_date:
446
        if start_date.weekday() == 6 or start_date in holidays:
447
            delivery_days = delivery_days + 1
448
            end_date = end_date + datetime.timedelta(days = 1)
449
        start_date = start_date + datetime.timedelta(days = 1)
450
 
451
    return delivery_days
7275 rajveer 452
 
453
def get_min_advance_amount(itemId, destination_pin, providerId, codAllowed):
454
    client = CatalogClient().get_client()
455
    sp = client.getStorePricing(itemId)
456
 
457
    if codAllowed:
458
        return sp.minAdvancePrice, True
459
    else:
7857 rajveer 460
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit = serviceable_location_cache.get(providerId).get(destination_pin)
7275 rajveer 461
        if iscod:
462
            if providerId == 6:
7489 rajveer 463
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 464
            if providerId == 3:
7489 rajveer 465
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 466
            if providerId == 1:
7489 rajveer 467
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 468
        else:
7425 rajveer 469
            return sp.recommendedPrice, False
7733 manish.sha 470
#Start:- Added by Manish Sharma for Multiple Pincode Updation on 05-Jul-2013
471
 
7786 manish.sha 472
def run_Logistics_Location_Info_Update(logisticsLocationInfoList, runCompleteUpdate):
473
    if runCompleteUpdate == True :
474
        serviceableLocationDetails = ServiceableLocationDetails.query.all()
475
        for serviceableLocationDetail in serviceableLocationDetails:
7841 manish.sha 476
            serviceableLocationDetail.exp = False
477
            serviceableLocationDetail.cod = False
7786 manish.sha 478
    for logisticsLocationInfo in logisticsLocationInfoList:
7841 manish.sha 479
        serviceableLocationDetail = ServiceableLocationDetails.get_by(provider_id = logisticsLocationInfo.providerId, dest_pincode = logisticsLocationInfo.pinCode)
7914 rajveer 480
        provider = Provider.query.filter_by(id = logisticsLocationInfo.providerId).one()
7841 manish.sha 481
        if serviceableLocationDetail:
482
            serviceableLocationDetail.exp = logisticsLocationInfo.expAvailable
483
            serviceableLocationDetail.cod = logisticsLocationInfo.codAvailable
484
            serviceableLocationDetail.otgAvailable = logisticsLocationInfo.otgAvailable
485
            serviceableLocationDetail.providerCodLimit = logisticsLocationInfo.codLimit
486
            serviceableLocationDetail.providerPrepaidLimit = logisticsLocationInfo.prepaidLimit
487
            serviceableLocationDetail.storeCodLimit = logisticsLocationInfo.codLimit
8219 manish.sha 488
            serviceableLocationDetail.websiteCodLimit = min(26000,logisticsLocationInfo.codLimit)
7841 manish.sha 489
        else:
490
            serviceableLocationDetail= ServiceableLocationDetails()
491
            serviceableLocationDetail.provider = provider
492
            serviceableLocationDetail.dest_pincode = logisticsLocationInfo.pinCode
493
            serviceableLocationDetail.dest_code = logisticsLocationInfo.destinationCode
494
            serviceableLocationDetail.exp = logisticsLocationInfo.expAvailable
495
            serviceableLocationDetail.cod = logisticsLocationInfo.codAvailable
496
            serviceableLocationDetail.station_type = 0
497
            serviceableLocationDetail.otgAvailable = logisticsLocationInfo.otgAvailable
498
            serviceableLocationDetail.providerCodLimit = logisticsLocationInfo.codLimit
499
            serviceableLocationDetail.providerPrepaidLimit = logisticsLocationInfo.prepaidLimit
500
            serviceableLocationDetail.storeCodLimit = logisticsLocationInfo.codLimit
8219 manish.sha 501
            serviceableLocationDetail.websiteCodLimit = min(26000,logisticsLocationInfo.codLimit)
7841 manish.sha 502
 
7870 rajveer 503
        deliveryEstimate = DeliveryEstimate.get_by(provider_id = logisticsLocationInfo.providerId, destination_pin = logisticsLocationInfo.pinCode, warehouse_location = logisticsLocationInfo.warehouseId) 
7841 manish.sha 504
        if deliveryEstimate:
505
            deliveryEstimate.warehouse_location= logisticsLocationInfo.warehouseId
506
            deliveryEstimate.delivery_time= logisticsLocationInfo.deliveryTime
507
            deliveryEstimate.delivery_delay= logisticsLocationInfo.delivery_delay
19421 manish.sha 508
            deliveryEstimate.providerZoneCode = logisticsLocationInfo.zoneCode
7841 manish.sha 509
        else:
510
            deliveryEstimate = DeliveryEstimate()
511
            deliveryEstimate.destination_pin= logisticsLocationInfo.pinCode
512
            deliveryEstimate.provider = provider
513
            deliveryEstimate.warehouse_location= logisticsLocationInfo.warehouseId
514
            deliveryEstimate.delivery_time= logisticsLocationInfo.deliveryTime
515
            deliveryEstimate.delivery_delay= logisticsLocationInfo.delivery_delay
19421 manish.sha 516
            deliveryEstimate.providerZoneCode = logisticsLocationInfo.zoneCode
7733 manish.sha 517
    session.commit()
7786 manish.sha 518
 
7733 manish.sha 519
#End:- Added by Manish Sharma for Multiple Pincode Updation on 05-Jul-2013             
7275 rajveer 520
 
12895 manish.sha 521
def get_first_delivery_estimate_for_wh_location(pincode, whLocation):
522
    delEstimate = DeliveryEstimate.query.filter(DeliveryEstimate.destination_pin == pincode).filter(DeliveryEstimate.warehouse_location == whLocation).first()
523
    if delEstimate is None:
524
        return -1
525
    else:
526
        return 1
13146 manish.sha 527
 
528
def get_provider_limit_details_for_pincode(provider, pincode):
529
    serviceAbleDetails = ServiceableLocationDetails.get_by(provider_id = provider, dest_pincode = pincode)
530
    returnDataMap = {}
531
    if serviceAbleDetails:
532
        returnDataMap["websiteCodLimit"] = str(serviceAbleDetails.websiteCodLimit)
19230 manish.sha 533
        returnDataMap["providerCodLimit"] = str(serviceAbleDetails.providerCodLimit)
13146 manish.sha 534
        returnDataMap["providerPrepaidLimit"] = str(serviceAbleDetails.providerPrepaidLimit)
535
 
536
    return returnDataMap
537
 
538
def get_new_empty_awb(providerId, type, orderQuantity):
539
    query = Awb.query.with_lockmode("update").filter_by(provider_id = providerId, is_available = True)  #check the provider thing
540
    if type == DeliveryType.PREPAID:
541
        query = query.filter_by(type="Prepaid")
542
    if type == DeliveryType.COD:
543
        query = query.filter_by(type="COD")
544
 
545
    additionalQuery = query
546
    if orderQuantity == 1:
547
        query = query.filter_by(awbUsedFor=0)
548
    if orderQuantity >1:
549
        query = query.filter_by(awbUsedFor=1) 
550
 
551
    try:
552
        awb = query.first()
553
        if awb is None:
554
            additionalQuery = additionalQuery.filter_by(awbUsedFor=2)
555
            awb = additionalQuery.first()
556
        awb.is_available = False
557
        session.commit()
558
        return awb.awb_number
559
    except:
560
        raise LogisticsServiceException(103, "Unable to get an AWB for the given Provider: " + str(providerId))
19421 manish.sha 561
 
562
def get_costing_and_delivery_estimate_for_pincode(pincode, transactionAmount, isCod, weight, billingWarehouseId):
563
    deliveryEstimate = {}
564
    logsiticsCosting = {}
565
    providerCostingMap = {}
566
    serviceability = {}
567
 
568
    for providerId in serviceable_location_cache.keys():
569
        if serviceable_location_cache.has_key(providerId) and serviceable_location_cache.get(providerId).has_key(pincode):
570
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit = serviceable_location_cache.get(providerId).get(pincode)
571
            if isCod and iscod:
572
                serviceability[providerId] = serviceable_location_cache.get(providerId).get(pincode)
573
            elif isCod and not iscod:
574
                continue
575
            else:
576
                serviceability[providerId] = serviceable_location_cache.get(providerId).get(pincode)
577
 
578
    warehouse_location = warehouse_location_cache.get(billingWarehouseId)
579
    if warehouse_location is None:
580
        warehouse_location = 0
581
 
582
    noCostFoundCount = 0
583
    if len(serviceability)>0:
584
        for providerId, serviceableDetails in serviceability.items():
585
            delivery_time = delivery_estimate_cache[pincode, providerId, warehouse_location][0]
586
            delivery_delay = delivery_estimate_cache[pincode, providerId, warehouse_location][1]
587
            zoneCode = delivery_estimate_cache[pincode, providerId, warehouse_location][2]
588
            sla = delivery_time + delivery_delay
589
            if deliveryEstimate.has_key(sla):
590
                estimate = deliveryEstimate.get(sla)
591
                estimate.append(providerId)
592
                deliveryEstimate[sla] = estimate
593
            else:
594
                estimate = []
595
                estimate.append(providerId)
596
                deliveryEstimate[sla] = estimate
597
 
598
            logisticsCost = 0
599
            codCollectionCharges = 0    
600
            logisticsCostObj = None 
601
            if provider_costing_sheet.has_key(providerId) and provider_costing_sheet.get(providerId).has_key(zoneCode):
602
                logisticsCostObj = provider_costing_sheet.get(providerId).get(zoneCode)
603
                logisticsCost = logisticsCostObj.initialLogisticsCost
604
                if weight > logisticsCostObj.initialWeightUpperLimit:
605
                    additionalWeight = weight-logisticsCostObj.initialWeightUpperLimit
606
                    additionalCostMultiplier = additionalWeight/logisticsCostObj.additionalUnitWeight
607
                    additionalCost = additionalCostMultiplier*logisticsCostObj.additionalUnitLogisticsCost
608
                    logisticsCost = logisticsCost + additionalCost
609
                if isCod:
610
                    if logisticsCostObj.codCollectionFactor:
611
                        codCollectionCharges = max(logisticsCostObj.minimumCodCollectionCharges, transactionAmount*logisticsCostObj.codCollectionFactor)
612
                        logisticsCost = logisticsCost + max(logisticsCostObj.minimumCodCollectionCharges, transactionAmount*logisticsCostObj.codCollectionFactor)
613
                    else:
614
                        codCollectionCharges = logisticsCostObj.minimumCodCollectionCharges
615
                        logisticsCost = logisticsCost + logisticsCostObj.minimumCodCollectionCharges
616
 
617
                if logsiticsCosting.has_key(logisticsCost):
618
                    costingList = logsiticsCosting.get(logisticsCost)
619
                    costingList.append(providerId)
620
                    logsiticsCosting[logisticsCost] = costingList
621
                else:
622
                    costingList = []
623
                    costingList.append(providerId)
624
                    logsiticsCosting[logisticsCost] = costingList
625
 
626
                providerCostingMap[providerId] = [logisticsCost,codCollectionCharges]
627
            else:
628
                noCostFoundCount = noCostFoundCount +1
629
                continue
630
    else:
631
        raise LogisticsServiceException(101, "No provider assigned for pincode: " + str(pincode))
632
 
633
 
634
    if noCostFoundCount == len(serviceability):
635
        raise LogisticsServiceException(101, "No Costing Found for this pincode: " + str(pincode) +" for any of the provider")
636
 
637
    allSla = sorted(deliveryEstimate.keys())
638
    if len(allSla)==1:
639
        allEligibleProviders = deliveryEstimate.get(allSla[0])
640
        if len(allEligibleProviders)==1:
641
            costingDetails = providerCostingMap.get(allEligibleProviders[0])
642
            delEstCostObj = DeliveryEstimateAndCosting()
643
            delEstCostObj.logistics_provider_id = allEligibleProviders[0]
644
            delEstCostObj.pincode = pincode
645
            delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, allEligibleProviders[0], warehouse_location][0]
646
            delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, allEligibleProviders[0], warehouse_location][1]
647
            delEstCostObj.codAllowed = serviceability[allEligibleProviders[0]][2]
648
            delEstCostObj.otgAvailable = serviceability[allEligibleProviders[0]][3]
649
            delEstCostObj.logisticsCost = costingDetails[0]-costingDetails[1]
650
            delEstCostObj.codCollectionCharges = costingDetails[1]
651
            return delEstCostObj
652
        else:
653
            costingListOrder = []
654
            for providerId in allEligibleProviders:
655
                costingDetails = providerCostingMap.get(allEligibleProviders[0])
656
                if costingDetails[0] not in costingListOrder:
657
                    costingListOrder.append(costingDetails[0])
658
 
659
            if DELHIVERY in allEligibleProviders:
660
                delihiveryCosting = providerCostingMap.get(DELHIVERY)
661
                considerCost = min(min(costingListOrder)+10, delihiveryCosting[0])
662
                if considerCost == delihiveryCosting[0]:
663
                    delEstCostObj = DeliveryEstimateAndCosting()
664
                    delEstCostObj.logistics_provider_id = DELHIVERY
665
                    delEstCostObj.pincode = pincode
666
                    delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, DELHIVERY, warehouse_location][0]
667
                    delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, DELHIVERY, warehouse_location][1]
668
                    delEstCostObj.codAllowed = serviceability[DELHIVERY][2]
669
                    delEstCostObj.otgAvailable = serviceability[DELHIVERY][3]
670
                    delEstCostObj.logisticsCost = delihiveryCosting[0]-delihiveryCosting[1]
671
                    delEstCostObj.codCollectionCharges = delihiveryCosting[1]
672
                    return delEstCostObj
673
                else:
674
                    considerCost = considerCost -10
675
                    eligibleProviders = logsiticsCosting.get(considerCost)
676
                    costingDetails = providerCostingMap.get(eligibleProviders[0])
677
                    delEstCostObj = DeliveryEstimateAndCosting()
678
                    delEstCostObj.logistics_provider_id = eligibleProviders[0]
679
                    delEstCostObj.pincode = pincode
680
                    delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, eligibleProviders[0], warehouse_location][0]
681
                    delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, eligibleProviders[0], warehouse_location][1]
682
                    delEstCostObj.codAllowed = serviceability[eligibleProviders[0]][2]
683
                    delEstCostObj.otgAvailable = serviceability[eligibleProviders[0]][3]
684
                    delEstCostObj.logisticsCost = costingDetails[0]-costingDetails[1]
685
                    delEstCostObj.codCollectionCharges = costingDetails[1]
686
                    return delEstCostObj
687
            else:
688
                costingListOrder = sorted(costingListOrder)
689
                eligibleProviders = logsiticsCosting.get(costingListOrder[0])
690
                costingDetails = providerCostingMap.get(eligibleProviders[0])
691
                delEstCostObj = DeliveryEstimateAndCosting()
692
                delEstCostObj.logistics_provider_id = eligibleProviders[0]
693
                delEstCostObj.pincode = pincode
694
                delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, eligibleProviders[0], warehouse_location][0]
695
                delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, eligibleProviders[0], warehouse_location][1]
696
                delEstCostObj.codAllowed = serviceability[eligibleProviders[0]][2]
697
                delEstCostObj.otgAvailable = serviceability[eligibleProviders[0]][3]
698
                delEstCostObj.logisticsCost = costingDetails[0]-costingDetails[1]
699
                delEstCostObj.codCollectionCharges = costingDetails[1]
700
                return delEstCostObj
701
 
702
    else:
703
        if allSla[1]-allSla[0]!=1:
704
            allEligibleProviders = deliveryEstimate.get(allSla[0])
705
            if len(allEligibleProviders)==1:
706
                costingDetails = providerCostingMap.get(allEligibleProviders[0])
707
                delEstCostObj = DeliveryEstimateAndCosting()
708
                delEstCostObj.logistics_provider_id = allEligibleProviders[0]
709
                delEstCostObj.pincode = pincode
710
                delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, allEligibleProviders[0], warehouse_location][0]
711
                delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, allEligibleProviders[0], warehouse_location][1]
712
                delEstCostObj.codAllowed = serviceability[allEligibleProviders[0]][2]
713
                delEstCostObj.otgAvailable = serviceability[allEligibleProviders[0]][3]
714
                delEstCostObj.logisticsCost = costingDetails[0]-costingDetails[1]
715
                delEstCostObj.codCollectionCharges = costingDetails[1]
716
                return delEstCostObj
717
            else:
718
                costingListOrder = []
719
                for providerId in allEligibleProviders:
720
                    costingDetails = providerCostingMap.get(allEligibleProviders[0])
721
                    if costingDetails[0] not in costingListOrder:
722
                        costingListOrder.append(costingDetails[0])
723
 
724
                if DELHIVERY in allEligibleProviders:
725
                    delihiveryCosting = providerCostingMap.get(DELHIVERY)
726
                    considerCost = min(min(costingListOrder)+10, delihiveryCosting[0])
727
                    if considerCost == delihiveryCosting[0]:
728
                        delEstCostObj = DeliveryEstimateAndCosting()
729
                        delEstCostObj.logistics_provider_id = DELHIVERY
730
                        delEstCostObj.pincode = pincode
731
                        delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, DELHIVERY, warehouse_location][0]
732
                        delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, DELHIVERY, warehouse_location][1]
733
                        delEstCostObj.codAllowed = serviceability[DELHIVERY][2]
734
                        delEstCostObj.otgAvailable = serviceability[DELHIVERY][3]
735
                        delEstCostObj.logisticsCost = delihiveryCosting[0]-delihiveryCosting[1]
736
                        delEstCostObj.codCollectionCharges = delihiveryCosting[1]
737
                        return delEstCostObj
738
                    else:
739
                        considerCost = considerCost -10
740
                        eligibleProviders = logsiticsCosting.get(considerCost)
741
                        costingDetails = providerCostingMap.get(eligibleProviders[0])
742
                        delEstCostObj = DeliveryEstimateAndCosting()
743
                        delEstCostObj.logistics_provider_id = eligibleProviders[0]
744
                        delEstCostObj.pincode = pincode
745
                        delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, eligibleProviders[0], warehouse_location][0]
746
                        delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, eligibleProviders[0], warehouse_location][1]
747
                        delEstCostObj.codAllowed = serviceability[eligibleProviders[0]][2]
748
                        delEstCostObj.otgAvailable = serviceability[eligibleProviders[0]][3]
749
                        delEstCostObj.logisticsCost = costingDetails[0]-costingDetails[1]
750
                        delEstCostObj.codCollectionCharges = costingDetails[1]
751
                        return delEstCostObj
752
                else:
753
                    costingListOrder = sorted(costingListOrder)
754
                    eligibleProviders = logsiticsCosting.get(costingListOrder[0])
755
                    costingDetails = providerCostingMap.get(eligibleProviders[0])
756
                    delEstCostObj = DeliveryEstimateAndCosting()
757
                    delEstCostObj.logistics_provider_id = eligibleProviders[0]
758
                    delEstCostObj.pincode = pincode
759
                    delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, eligibleProviders[0], warehouse_location][0]
760
                    delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, eligibleProviders[0], warehouse_location][1]
761
                    delEstCostObj.codAllowed = serviceability[eligibleProviders[0]][2]
762
                    delEstCostObj.otgAvailable = serviceability[eligibleProviders[0]][3]
763
                    delEstCostObj.logisticsCost = costingDetails[0]-costingDetails[1]
764
                    delEstCostObj.codCollectionCharges = costingDetails[1]
765
                    return delEstCostObj
766
 
767
        else:
768
            allEligibleProviders = deliveryEstimate.get(allSla[0])
769
            secondBestEligibleProviders = deliveryEstimate.get(allSla[1])
770
            for providerId in secondBestEligibleProviders:
771
                allEligibleProviders.append(providerId)
772
 
773
            costingListOrder = []
774
            for providerId in allEligibleProviders:
775
                costingDetails = providerCostingMap.get(allEligibleProviders[0])
776
                if costingDetails[0] not in costingListOrder:
777
                    costingListOrder.append(costingDetails[0])
778
 
779
            if DELHIVERY in allEligibleProviders:
780
                delihiveryCosting = providerCostingMap.get(DELHIVERY)
781
                considerCost = min(min(costingListOrder)+10, delihiveryCosting[0])
782
                if considerCost == delihiveryCosting[0]:
783
                    delEstCostObj = DeliveryEstimateAndCosting()
784
                    delEstCostObj.logistics_provider_id = DELHIVERY
785
                    delEstCostObj.pincode = pincode
786
                    delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, DELHIVERY, warehouse_location][0]
787
                    delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, DELHIVERY, warehouse_location][1]
788
                    delEstCostObj.codAllowed = serviceability[DELHIVERY][2]
789
                    delEstCostObj.otgAvailable = serviceability[DELHIVERY][3]
790
                    delEstCostObj.logisticsCost = delihiveryCosting[0]-delihiveryCosting[1]
791
                    delEstCostObj.codCollectionCharges = delihiveryCosting[1]
792
                    return delEstCostObj
793
                else:
794
                    considerCost = considerCost -10
795
                    eligibleProviders = logsiticsCosting.get(considerCost)
796
                    costingDetails = providerCostingMap.get(eligibleProviders[0])
797
                    delEstCostObj = DeliveryEstimateAndCosting()
798
                    delEstCostObj.logistics_provider_id = eligibleProviders[0]
799
                    delEstCostObj.pincode = pincode
800
                    delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, eligibleProviders[0], warehouse_location][0]
801
                    delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, eligibleProviders[0], warehouse_location][1]
802
                    delEstCostObj.codAllowed = serviceability[eligibleProviders[0]][2]
803
                    delEstCostObj.otgAvailable = serviceability[eligibleProviders[0]][3]
804
                    delEstCostObj.logisticsCost = costingDetails[0]-costingDetails[1]
805
                    delEstCostObj.codCollectionCharges = costingDetails[1]
806
                    return delEstCostObj
807
            else:
808
                costingListOrder = sorted(costingListOrder)
809
                eligibleProviders = logsiticsCosting.get(costingListOrder[0])
810
                costingDetails = providerCostingMap.get(eligibleProviders[0])
811
                delEstCostObj = DeliveryEstimateAndCosting()
812
                delEstCostObj.logistics_provider_id = eligibleProviders[0]
813
                delEstCostObj.pincode = pincode
814
                delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, eligibleProviders[0], warehouse_location][0]
815
                delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, eligibleProviders[0], warehouse_location][1]
816
                delEstCostObj.codAllowed = serviceability[eligibleProviders[0]][2]
817
                delEstCostObj.otgAvailable = serviceability[eligibleProviders[0]][3]
818
                delEstCostObj.logisticsCost = costingDetails[0]-costingDetails[1]
819
                delEstCostObj.codCollectionCharges = costingDetails[1]
820
                return delEstCostObj