Subversion Repositories SmartDukaan

Rev

Rev 19474 | Rev 19481 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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