Subversion Repositories SmartDukaan

Rev

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