Subversion Repositories SmartDukaan

Rev

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