Subversion Repositories SmartDukaan

Rev

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