Subversion Repositories SmartDukaan

Rev

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