Subversion Repositories SmartDukaan

Rev

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