Subversion Repositories SmartDukaan

Rev

Rev 19535 | Rev 19663 | 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
    '''        
19533 manish.sha 252
    if serviceable_location_cache.has_key(3) and 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):
19533 manish.sha 260
        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 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
19533 manish.sha 272
 
273
    if billingWarehouseId not in [12,13] and serviceable_location_cache.has_key(46) and serviceable_location_cache.get(46).has_key(destination_pin):
274
        if item_selling_price < 3000 and serviceable_location_cache.has_key(1) and serviceable_location_cache.get(1).has_key(destination_pin):
275
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit, providerCodLimit = serviceable_location_cache.get(1).get(destination_pin)
276
            if item_selling_price <= providerPrepaidLimit:
277
                iscod = iscod and item_selling_price <= websiteCodLimit
278
                otgAvailable = otgAvailable and item_selling_price >= 2000
279
                return 1, iscod, otgAvailable
280
        else:
281
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit, providerCodLimit = serviceable_location_cache.get(46).get(destination_pin)
282
            if item_selling_price <= providerPrepaidLimit:
283
                iscod = iscod and item_selling_price <= websiteCodLimit
284
                otgAvailable = otgAvailable and item_selling_price >= 2000
285
                return 46, iscod, otgAvailable
8575 rajveer 286
 
19533 manish.sha 287
    if serviceable_location_cache.has_key(1) and serviceable_location_cache.get(1).has_key(destination_pin):
19476 manish.sha 288
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit, providerCodLimit = serviceable_location_cache.get(1).get(destination_pin)
7627 rajveer 289
        if item_selling_price <= providerPrepaidLimit:
7608 rajveer 290
            iscod = iscod and item_selling_price <= websiteCodLimit
291
            otgAvailable = otgAvailable and item_selling_price >= 2000
7627 rajveer 292
            return 1, iscod, otgAvailable
7981 rajveer 293
 
10185 amit.gupta 294
    return None, False, False    
5278 rajveer 295
 
6017 amar.kumar 296
def get_destination_code(providerId, pinCode):
297
    serviceableLocationDetail = ServiceableLocationDetails.query.filter_by(provider_id = providerId, dest_pincode = pinCode).one()
298
    return serviceableLocationDetail.dest_code
299
 
644 chandransh 300
def add_empty_AWBs(numbers, provider_id, type):
442 rajveer 301
    for number in numbers:
644 chandransh 302
        query = Awb.query.filter_by(awb_number = number, provider_id = provider_id)
444 rajveer 303
        try:
304
            query.one()
305
        except:    
644 chandransh 306
            awb = Awb()
444 rajveer 307
            awb.awb_number = number
644 chandransh 308
            awb.provider_id = provider_id
444 rajveer 309
            awb.is_available = True
644 chandransh 310
            awb.type = type
311
    session.commit()
19413 amit.gupta 312
 
313
def get_pincode_item_serviceability():
314
    pass
442 rajveer 315
 
444 rajveer 316
def set_AWB_as_used(awb_number):
644 chandransh 317
    query = Awb.query.filter_by(awb_number = awb_number)
444 rajveer 318
    awb = query.one() 
319
    awb.is_available=False
320
    session.commit()
321
 
3044 chandransh 322
def get_empty_AWB(provider_id, type = DeliveryType.PREPAID):
2342 chandransh 323
    query = Awb.query.with_lockmode("update").filter_by(provider_id = provider_id, is_available = True)  #check the provider thing
3044 chandransh 324
    if type == DeliveryType.PREPAID:
325
        query = query.filter_by(type="Prepaid")
326
    if type == DeliveryType.COD:
327
        query = query.filter_by(type="COD")
328
 
13158 manish.sha 329
    additionalQuery = query
330
    query = query.filter_by(awbUsedFor=0)
331
 
442 rajveer 332
    try:
644 chandransh 333
        awb = query.first()
13158 manish.sha 334
        if awb is None:
335
            additionalQuery = additionalQuery.filter_by(awbUsedFor=2)
336
            awb = additionalQuery.first()
644 chandransh 337
        awb.is_available = False
338
        session.commit()
444 rajveer 339
        return awb.awb_number
442 rajveer 340
    except:
644 chandransh 341
        raise LogisticsServiceException(103, "Unable to get an AWB for the given Provider: " + str(provider_id))
1137 chandransh 342
 
3103 chandransh 343
def get_free_awb_count(provider_id, type):
344
    count = Awb.query.filter_by(provider_id = provider_id, is_available = True, type=type).count()
1137 chandransh 345
    if count == None:
346
        count = 0
347
    return count
442 rajveer 348
 
644 chandransh 349
def get_shipment_info(awb_number, provider_id):
350
    awb = Awb.get_by(awb_number = awb_number, provider_id = provider_id)
351
    query = AwbUpdate.query.filter_by(awb = awb)
766 rajveer 352
    info = query.all()
353
    return info
354
 
6643 rajveer 355
def store_shipment_info(update):
356
    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()
357
    if not updates:
358
        dupdate = AwbUpdate()
359
        dupdate.providerId = update.providerId
360
        dupdate.awbNumber  = update.awbNumber
361
        dupdate.location = update.location
362
        dupdate.date = to_py_date(update.date)
363
        dupdate.status = update.status
364
        dupdate.description = update.description
365
        session.commit()
366
 
1730 ankur.sing 367
def get_holidays(start_date, end_date):
368
    query = PublicHolidays.query
369
    if start_date != -1:
370
        query = query.filter(PublicHolidays.date >= to_py_date(start_date))
371
    if end_date != -1:
372
        query = query.filter(PublicHolidays.date <= to_py_date(end_date))
373
    holidays = query.all()
374
    holiday_dates = [to_java_date(datetime.datetime(*time.strptime(str(holiday.date), '%Y-%m-%d')[:3])) for holiday in holidays] 
375
    return holiday_dates
376
 
5527 anupam.sin 377
def get_provider_for_pickup_type(pickUp):
378
    return Provider.query.filter(Provider.pickup == pickUp).first().id
379
 
766 rajveer 380
def close_session():
381
    if session.is_active:
382
        print "session is active. closing it."
2823 chandransh 383
        session.close()
3376 rajveer 384
 
385
def is_alive():
386
    try:
387
        session.query(Awb.id).limit(1).one()
388
        return True
389
    except:
5555 rajveer 390
        return False
391
 
392
def get_all_pickup_stores():
5572 anupam.sin 393
    pickupStores = PickupStore.query.all()
394
    return pickupStores
5555 rajveer 395
 
396
def get_pickup_store(storeId):
5719 rajveer 397
    return PickupStore.query.filter_by(id = storeId).one()
398
 
399
def get_pickup_store_by_hotspot_id(hotspotId):
400
    return PickupStore.query.filter_by(hotspotId = hotspotId).one()
6322 amar.kumar 401
 
6524 rajveer 402
def add_pincode(provider, pincode, destCode, exp, cod, stationType, otgAvailable):
7914 rajveer 403
    provider = Provider.query.filter_by(id = provider).one()
6322 amar.kumar 404
    serviceableLocationDetails = ServiceableLocationDetails()
405
    serviceableLocationDetails.provider = provider
406
    serviceableLocationDetails.dest_pincode = pincode
407
    serviceableLocationDetails.dest_code = destCode
408
    serviceableLocationDetails.exp = exp
409
    serviceableLocationDetails.cod = cod
410
    serviceableLocationDetails.station_type = stationType
6524 rajveer 411
    serviceableLocationDetails.otgAvailable = otgAvailable
7733 manish.sha 412
    if provider.id == 1:
7627 rajveer 413
        codlimit = 10000
414
        prepaidlimit = 50000
7733 manish.sha 415
    elif provider.id == 3:
7627 rajveer 416
        codlimit = 25000
417
        prepaidlimit = 100000
7733 manish.sha 418
    elif provider.id == 6:
7627 rajveer 419
        codlimit = 25000
420
        prepaidlimit = 100000
421
    serviceableLocationDetails.providerPrepaidLimit = prepaidlimit
422
    serviceableLocationDetails.providerCodLimit = codlimit
423
    serviceableLocationDetails.websiteCodLimit = codlimit
424
    serviceableLocationDetails.storeCodLimit = codlimit
6322 amar.kumar 425
    session.commit()
426
 
6524 rajveer 427
def update_pincode(providerId, pincode, exp, cod, otgAvailable):
6615 amar.kumar 428
    serviceableLocationDetails = ServiceableLocationDetails.get_by(provider_id = providerId, dest_pincode = pincode)
6322 amar.kumar 429
    serviceableLocationDetails.exp = exp
430
    serviceableLocationDetails.cod = cod
6524 rajveer 431
    serviceableLocationDetails.otgAvailable = otgAvailable
7256 rajveer 432
    session.commit()
7567 rajveer 433
 
13146 manish.sha 434
def add_new_awbs(provider_id, isCod, awbs, awbUsedFor):
7567 rajveer 435
    provider = get_provider(provider_id)
436
    if isCod:
437
        dtype = 'Cod'
438
    else:
439
        dtype = 'Prepaid'
440
    for awb in awbs:
441
        a = Awb()
442
        a.type =  dtype
443
        a.is_available = True
444
        a.awb_number = awb
13146 manish.sha 445
        a.awbUsedFor = awbUsedFor
7567 rajveer 446
        a.provider = provider 
447
    session.commit()
7608 rajveer 448
    return True
7256 rajveer 449
 
450
def adjust_delivery_time(start_time, delivery_days):
451
    '''
452
    Returns the actual no. of days which will pass while 'delivery_days'
453
    no. of business days will pass since 'order_time'. 
454
    '''
455
    start_date = start_time.date()
456
    end_date = start_date + datetime.timedelta(days = delivery_days)
7272 amit.gupta 457
    holidays = get_holidays(to_java_date(start_time), -1)
7256 rajveer 458
    holidays = [to_py_date(holiday).date() for holiday in holidays]
459
 
460
    while start_date <= end_date:
461
        if start_date.weekday() == 6 or start_date in holidays:
462
            delivery_days = delivery_days + 1
463
            end_date = end_date + datetime.timedelta(days = 1)
464
        start_date = start_date + datetime.timedelta(days = 1)
465
 
466
    return delivery_days
7275 rajveer 467
 
468
def get_min_advance_amount(itemId, destination_pin, providerId, codAllowed):
469
    client = CatalogClient().get_client()
470
    sp = client.getStorePricing(itemId)
471
 
472
    if codAllowed:
473
        return sp.minAdvancePrice, True
474
    else:
7857 rajveer 475
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit = serviceable_location_cache.get(providerId).get(destination_pin)
7275 rajveer 476
        if iscod:
477
            if providerId == 6:
7489 rajveer 478
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 479
            if providerId == 3:
7489 rajveer 480
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 481
            if providerId == 1:
7489 rajveer 482
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 483
        else:
7425 rajveer 484
            return sp.recommendedPrice, False
7733 manish.sha 485
#Start:- Added by Manish Sharma for Multiple Pincode Updation on 05-Jul-2013
486
 
7786 manish.sha 487
def run_Logistics_Location_Info_Update(logisticsLocationInfoList, runCompleteUpdate):
488
    if runCompleteUpdate == True :
489
        serviceableLocationDetails = ServiceableLocationDetails.query.all()
490
        for serviceableLocationDetail in serviceableLocationDetails:
7841 manish.sha 491
            serviceableLocationDetail.exp = False
492
            serviceableLocationDetail.cod = False
7786 manish.sha 493
    for logisticsLocationInfo in logisticsLocationInfoList:
7841 manish.sha 494
        serviceableLocationDetail = ServiceableLocationDetails.get_by(provider_id = logisticsLocationInfo.providerId, dest_pincode = logisticsLocationInfo.pinCode)
7914 rajveer 495
        provider = Provider.query.filter_by(id = logisticsLocationInfo.providerId).one()
7841 manish.sha 496
        if serviceableLocationDetail:
497
            serviceableLocationDetail.exp = logisticsLocationInfo.expAvailable
498
            serviceableLocationDetail.cod = logisticsLocationInfo.codAvailable
499
            serviceableLocationDetail.otgAvailable = logisticsLocationInfo.otgAvailable
500
            serviceableLocationDetail.providerCodLimit = logisticsLocationInfo.codLimit
501
            serviceableLocationDetail.providerPrepaidLimit = logisticsLocationInfo.prepaidLimit
502
            serviceableLocationDetail.storeCodLimit = logisticsLocationInfo.codLimit
8219 manish.sha 503
            serviceableLocationDetail.websiteCodLimit = min(26000,logisticsLocationInfo.codLimit)
7841 manish.sha 504
        else:
505
            serviceableLocationDetail= ServiceableLocationDetails()
506
            serviceableLocationDetail.provider = provider
507
            serviceableLocationDetail.dest_pincode = logisticsLocationInfo.pinCode
508
            serviceableLocationDetail.dest_code = logisticsLocationInfo.destinationCode
509
            serviceableLocationDetail.exp = logisticsLocationInfo.expAvailable
510
            serviceableLocationDetail.cod = logisticsLocationInfo.codAvailable
511
            serviceableLocationDetail.station_type = 0
512
            serviceableLocationDetail.otgAvailable = logisticsLocationInfo.otgAvailable
513
            serviceableLocationDetail.providerCodLimit = logisticsLocationInfo.codLimit
514
            serviceableLocationDetail.providerPrepaidLimit = logisticsLocationInfo.prepaidLimit
515
            serviceableLocationDetail.storeCodLimit = logisticsLocationInfo.codLimit
8219 manish.sha 516
            serviceableLocationDetail.websiteCodLimit = min(26000,logisticsLocationInfo.codLimit)
7841 manish.sha 517
 
7870 rajveer 518
        deliveryEstimate = DeliveryEstimate.get_by(provider_id = logisticsLocationInfo.providerId, destination_pin = logisticsLocationInfo.pinCode, warehouse_location = logisticsLocationInfo.warehouseId) 
7841 manish.sha 519
        if deliveryEstimate:
520
            deliveryEstimate.warehouse_location= logisticsLocationInfo.warehouseId
521
            deliveryEstimate.delivery_time= logisticsLocationInfo.deliveryTime
522
            deliveryEstimate.delivery_delay= logisticsLocationInfo.delivery_delay
19421 manish.sha 523
            deliveryEstimate.providerZoneCode = logisticsLocationInfo.zoneCode
7841 manish.sha 524
        else:
525
            deliveryEstimate = DeliveryEstimate()
526
            deliveryEstimate.destination_pin= logisticsLocationInfo.pinCode
527
            deliveryEstimate.provider = provider
528
            deliveryEstimate.warehouse_location= logisticsLocationInfo.warehouseId
529
            deliveryEstimate.delivery_time= logisticsLocationInfo.deliveryTime
530
            deliveryEstimate.delivery_delay= logisticsLocationInfo.delivery_delay
19421 manish.sha 531
            deliveryEstimate.providerZoneCode = logisticsLocationInfo.zoneCode
7733 manish.sha 532
    session.commit()
7786 manish.sha 533
 
7733 manish.sha 534
#End:- Added by Manish Sharma for Multiple Pincode Updation on 05-Jul-2013             
7275 rajveer 535
 
12895 manish.sha 536
def get_first_delivery_estimate_for_wh_location(pincode, whLocation):
537
    delEstimate = DeliveryEstimate.query.filter(DeliveryEstimate.destination_pin == pincode).filter(DeliveryEstimate.warehouse_location == whLocation).first()
538
    if delEstimate is None:
539
        return -1
540
    else:
541
        return 1
13146 manish.sha 542
 
543
def get_provider_limit_details_for_pincode(provider, pincode):
544
    serviceAbleDetails = ServiceableLocationDetails.get_by(provider_id = provider, dest_pincode = pincode)
545
    returnDataMap = {}
546
    if serviceAbleDetails:
547
        returnDataMap["websiteCodLimit"] = str(serviceAbleDetails.websiteCodLimit)
19230 manish.sha 548
        returnDataMap["providerCodLimit"] = str(serviceAbleDetails.providerCodLimit)
13146 manish.sha 549
        returnDataMap["providerPrepaidLimit"] = str(serviceAbleDetails.providerPrepaidLimit)
550
 
551
    return returnDataMap
552
 
553
def get_new_empty_awb(providerId, type, orderQuantity):
554
    query = Awb.query.with_lockmode("update").filter_by(provider_id = providerId, is_available = True)  #check the provider thing
555
    if type == DeliveryType.PREPAID:
556
        query = query.filter_by(type="Prepaid")
557
    if type == DeliveryType.COD:
558
        query = query.filter_by(type="COD")
559
 
560
    additionalQuery = query
561
    if orderQuantity == 1:
562
        query = query.filter_by(awbUsedFor=0)
563
    if orderQuantity >1:
564
        query = query.filter_by(awbUsedFor=1) 
565
 
566
    try:
567
        awb = query.first()
568
        if awb is None:
569
            additionalQuery = additionalQuery.filter_by(awbUsedFor=2)
570
            awb = additionalQuery.first()
571
        awb.is_available = False
572
        session.commit()
573
        return awb.awb_number
574
    except:
575
        raise LogisticsServiceException(103, "Unable to get an AWB for the given Provider: " + str(providerId))
19421 manish.sha 576
 
19474 manish.sha 577
def get_costing_and_delivery_estimate_for_pincode(pincode, transactionAmount, isCod, weight, billingWarehouseId, isCompleteTxn):
578
    print pincode, transactionAmount, isCod, weight, billingWarehouseId
19421 manish.sha 579
    deliveryEstimate = {}
580
    logsiticsCosting = {}
581
    providerCostingMap = {}
582
    serviceability = {}
583
 
584
    for providerId in serviceable_location_cache.keys():
585
        if serviceable_location_cache.has_key(providerId) and serviceable_location_cache.get(providerId).has_key(pincode):
19474 manish.sha 586
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit, providerPrepaidLimit, providerCodLimit = serviceable_location_cache.get(providerId).get(pincode)
19421 manish.sha 587
            if isCod and iscod:
19474 manish.sha 588
                if not isCompleteTxn:
589
                    if transactionAmount <= providerCodLimit:
590
                        serviceability[providerId] = serviceable_location_cache.get(providerId).get(pincode)
591
                    else:
592
                        continue
593
                else:
594
                    serviceability[providerId] = serviceable_location_cache.get(providerId).get(pincode)
19421 manish.sha 595
            elif isCod and not iscod:
596
                continue
597
            else:
19474 manish.sha 598
                if not isCompleteTxn:
599
                    if transactionAmount <= providerPrepaidLimit:
600
                        serviceability[providerId] = serviceable_location_cache.get(providerId).get(pincode)
601
                    else:
602
                        continue
603
                else:
604
                    serviceability[providerId] = serviceable_location_cache.get(providerId).get(pincode)
19421 manish.sha 605
 
606
    warehouse_location = warehouse_location_cache.get(billingWarehouseId)
607
    if warehouse_location is None:
608
        warehouse_location = 0
609
 
610
    noCostFoundCount = 0
611
    if len(serviceability)>0:
612
        for providerId, serviceableDetails in serviceability.items():
613
            delivery_time = delivery_estimate_cache[pincode, providerId, warehouse_location][0]
614
            delivery_delay = delivery_estimate_cache[pincode, providerId, warehouse_location][1]
615
            zoneCode = delivery_estimate_cache[pincode, providerId, warehouse_location][2]
616
            sla = delivery_time + delivery_delay
617
            if deliveryEstimate.has_key(sla):
618
                estimate = deliveryEstimate.get(sla)
619
                estimate.append(providerId)
620
                deliveryEstimate[sla] = estimate
621
            else:
622
                estimate = []
623
                estimate.append(providerId)
624
                deliveryEstimate[sla] = estimate
625
 
626
            logisticsCost = 0
627
            codCollectionCharges = 0    
628
            logisticsCostObj = None 
629
            if provider_costing_sheet.has_key(providerId) and provider_costing_sheet.get(providerId).has_key(zoneCode):
630
                logisticsCostObj = provider_costing_sheet.get(providerId).get(zoneCode)
631
                logisticsCost = logisticsCostObj.initialLogisticsCost
632
                if weight > logisticsCostObj.initialWeightUpperLimit:
633
                    additionalWeight = weight-logisticsCostObj.initialWeightUpperLimit
19662 manish.sha 634
                    additionalWeight = round(additionalWeight,2)
19483 manish.sha 635
                    additionalCostMultiplier = math.ceil(additionalWeight/logisticsCostObj.additionalUnitWeight)
19421 manish.sha 636
                    additionalCost = additionalCostMultiplier*logisticsCostObj.additionalUnitLogisticsCost
637
                    logisticsCost = logisticsCost + additionalCost
638
                if isCod:
639
                    if logisticsCostObj.codCollectionFactor:
19474 manish.sha 640
                        codCollectionCharges = max(logisticsCostObj.minimumCodCollectionCharges, (transactionAmount*logisticsCostObj.codCollectionFactor)/100)
641
                        logisticsCost = logisticsCost + max(logisticsCostObj.minimumCodCollectionCharges, (transactionAmount*logisticsCostObj.codCollectionFactor)/100)
19421 manish.sha 642
                    else:
643
                        codCollectionCharges = logisticsCostObj.minimumCodCollectionCharges
644
                        logisticsCost = logisticsCost + logisticsCostObj.minimumCodCollectionCharges
645
 
19474 manish.sha 646
                if logsiticsCosting.has_key(round(logisticsCost,0)):
647
                    costingList = logsiticsCosting.get(round(logisticsCost,0))
19421 manish.sha 648
                    costingList.append(providerId)
19474 manish.sha 649
                    logsiticsCosting[round(logisticsCost,0)] = costingList
19421 manish.sha 650
                else:
651
                    costingList = []
652
                    costingList.append(providerId)
19474 manish.sha 653
                    logsiticsCosting[round(logisticsCost,0)] = costingList                    
19421 manish.sha 654
 
655
                providerCostingMap[providerId] = [logisticsCost,codCollectionCharges]
656
            else:
657
                noCostFoundCount = noCostFoundCount +1
658
                continue
659
    else:
19474 manish.sha 660
        print "No provider assigned for pincode: " + str(pincode)
19535 manish.sha 661
        raise LogisticsServiceException(103, "Unable to get Provider for given pincode: " + str(pincode)+" Amount:- "+str(transactionAmount)+" Weight:- "+ str(weight))
19421 manish.sha 662
 
663
 
664
    if noCostFoundCount == len(serviceability):
19474 manish.sha 665
        print "No Costing Found for this pincode: " + str(pincode) +" for any of the provider"
19535 manish.sha 666
        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 667
 
668
    allSla = sorted(deliveryEstimate.keys())
669
    if len(allSla)==1:
670
        allEligibleProviders = deliveryEstimate.get(allSla[0])
671
        if len(allEligibleProviders)==1:
19474 manish.sha 672
            try:
19421 manish.sha 673
                costingDetails = providerCostingMap.get(allEligibleProviders[0])
674
                delEstCostObj = DeliveryEstimateAndCosting()
675
                delEstCostObj.logistics_provider_id = allEligibleProviders[0]
676
                delEstCostObj.pincode = pincode
677
                delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, allEligibleProviders[0], warehouse_location][0]
678
                delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, allEligibleProviders[0], warehouse_location][1]
679
                delEstCostObj.codAllowed = serviceability[allEligibleProviders[0]][2]
680
                delEstCostObj.otgAvailable = serviceability[allEligibleProviders[0]][3]
681
                delEstCostObj.logisticsCost = costingDetails[0]-costingDetails[1]
682
                delEstCostObj.codCollectionCharges = costingDetails[1]
683
                return delEstCostObj
19474 manish.sha 684
            except:
19535 manish.sha 685
                raise LogisticsServiceException(103, "Unable to get Provider for given pincode: " + str(pincode)+" Amount:- "+str(transactionAmount)+" Weight:- "+ str(weight)+".")
19421 manish.sha 686
        else:
687
            costingListOrder = []
688
            for providerId in allEligibleProviders:
19474 manish.sha 689
                costingDetails = providerCostingMap.get(providerId)
690
                if costingDetails and costingDetails[0] not in costingListOrder:
691
                    costingListOrder.append(round(costingDetails[0],0))
692
 
693
            costingListOrder = sorted(costingListOrder)
694
            eligibleProviders = logsiticsCosting.get(costingListOrder[0])
695
            for providerId in eligibleProviders:
696
                if providerCostingMap.has_key(providerId):
697
                    costingDetails = providerCostingMap.get(providerId)
19421 manish.sha 698
                    delEstCostObj = DeliveryEstimateAndCosting()
19474 manish.sha 699
                    delEstCostObj.logistics_provider_id = providerId
19421 manish.sha 700
                    delEstCostObj.pincode = pincode
19474 manish.sha 701
                    delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, providerId, warehouse_location][0]
702
                    delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, providerId, warehouse_location][1]
703
                    delEstCostObj.codAllowed = serviceability[providerId][2]
704
                    delEstCostObj.otgAvailable = serviceability[providerId][3]
19421 manish.sha 705
                    delEstCostObj.logisticsCost = costingDetails[0]-costingDetails[1]
706
                    delEstCostObj.codCollectionCharges = costingDetails[1]
707
                    return delEstCostObj
19474 manish.sha 708
                else:
709
                    continue
19535 manish.sha 710
            raise LogisticsServiceException(103, "Unable to get Provider for given pincode: " + str(pincode)+" Amount:- "+str(transactionAmount)+" Weight:- "+ str(weight)+".")
19474 manish.sha 711
    else:
712
        allEligibleProviders = []
713
        virtualDelayCostMap = {}
714
        virtualCommercialsCostMap = {} 
715
        for sla in allSla:
716
            if sla-allSla[0]<=1:
717
                consideredProviders = deliveryEstimate.get(sla)
718
                for providerId in consideredProviders:
719
                    if isCod and providerId in [7,46]:
720
                        virtualCommercialsCostMap[providerId] = 10
721
                    if providerId not in allEligibleProviders:
722
                        allEligibleProviders.append(providerId)
723
                    virtualDelayCostMap[providerId] = 0
724
            elif sla-allSla[0]==2:
725
                consideredProviders = deliveryEstimate.get(sla)
726
                for providerId in consideredProviders:
727
                    if isCod and providerId in [7,46]:
728
                        virtualCommercialsCostMap[providerId] = 10
729
                    if providerId not in allEligibleProviders:
730
                        allEligibleProviders.append(providerId)
731
                    virtualDelayCostMap[providerId] = 20+round((0.3*transactionAmount)/100,0)
732
            elif sla-allSla[0]==3:
733
                consideredProviders = deliveryEstimate.get(sla)
734
                for providerId in consideredProviders:
735
                    if isCod and providerId in [7,46]:
736
                        virtualCommercialsCostMap[providerId] = 10
737
                    if providerId not in allEligibleProviders:
738
                        allEligibleProviders.append(providerId)
739
                    virtualDelayCostMap[providerId] = 40+round((0.6*transactionAmount)/100,0)
740
 
741
        costingListOrder = []
742
        costingListMap = {}
743
        for providerId in allEligibleProviders:
744
            costingDetails = providerCostingMap.get(providerId)
745
            if costingDetails:
746
                cost = round(costingDetails[0],0)
747
                if virtualDelayCostMap.has_key(providerId):
748
                    cost = cost + virtualDelayCostMap.get(providerId)
749
                if virtualCommercialsCostMap.has_key(providerId):
750
                    cost = cost + virtualCommercialsCostMap.get(providerId)
751
                if costingListMap.has_key(cost):
752
                    providers = costingListMap.get(cost)
753
                    providers.append(providerId)                       
754
                    costingListMap[cost] = providers 
755
                else:
756
                    providers = []
757
                    providers.append(providerId)                       
758
                    costingListMap[cost] = providers  
759
                if cost not in costingListOrder:
760
                    costingListOrder.append(cost)
761
 
762
        costingListOrder = sorted(costingListOrder)
763
 
764
        print costingListMap
765
        eligibleProviders = costingListMap.get(costingListOrder[0])
766
        for providerId in eligibleProviders:
767
            if providerCostingMap.has_key(providerId):
768
                costingDetails = providerCostingMap.get(providerId)
19421 manish.sha 769
                delEstCostObj = DeliveryEstimateAndCosting()
19474 manish.sha 770
                delEstCostObj.logistics_provider_id = providerId
19421 manish.sha 771
                delEstCostObj.pincode = pincode
19474 manish.sha 772
                delEstCostObj.deliveryTime = delivery_estimate_cache[pincode, providerId, warehouse_location][0]
773
                delEstCostObj.delivery_delay = delivery_estimate_cache[pincode, providerId, warehouse_location][1]
774
                delEstCostObj.codAllowed = serviceability[providerId][2]
775
                delEstCostObj.otgAvailable = serviceability[providerId][3]
19421 manish.sha 776
                delEstCostObj.logisticsCost = costingDetails[0]-costingDetails[1]
777
                delEstCostObj.codCollectionCharges = costingDetails[1]
778
                return delEstCostObj
19474 manish.sha 779
            else:
780
                continue
19535 manish.sha 781
        raise LogisticsServiceException(103, "Unable to get Provider for given pincode: " + str(pincode)+" Amount:- "+str(transactionAmount)+" Weight:- "+ str(weight)+".")