Subversion Repositories SmartDukaan

Rev

Rev 7589 | Rev 7627 | 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
 
7
from shop2020.logistics.service.impl import DataService
644 chandransh 8
from shop2020.logistics.service.impl.DataService import Awb, AwbUpdate, Provider, \
3218 rajveer 9
     DeliveryEstimate, WarehouseAllocation, \
5555 rajveer 10
    PublicHolidays, ServiceableLocationDetails, PickupStore
3044 chandransh 11
from shop2020.thriftpy.logistics.ttypes import LogisticsServiceException,\
12
    DeliveryType
442 rajveer 13
from shop2020.utils.Utils import log_entry, to_py_date, to_java_date
5964 amar.kumar 14
from sqlalchemy.sql import or_
442 rajveer 15
from elixir import session
1730 ankur.sing 16
import datetime, time
1504 ankur.sing 17
import sys
3355 chandransh 18
import logging
7293 anupam.sin 19
from shop2020.clients.CatalogClient import CatalogClient
3355 chandransh 20
logging.basicConfig(level=logging.DEBUG)
442 rajveer 21
 
3217 rajveer 22
warehouse_allocation_cache = {}
23
serviceable_location_cache = {}
24
delivery_estimate_cache = {}
6370 rajveer 25
 
3218 rajveer 26
'''
27
This class is for only data transfer. Never used outside this module.
28
'''
29
class _DeliveryEstimateObject:
6537 rajveer 30
    def __init__(self, delivery_time, delivery_delay, provider_id, codAllowed, otgAvailable):
3218 rajveer 31
        self.delivery_time = delivery_time
6537 rajveer 32
        self.delivery_delay = delivery_delay
3218 rajveer 33
        self.provider_id = provider_id
4866 rajveer 34
        self.codAllowed = codAllowed
6524 rajveer 35
        self.otgAvailable = otgAvailable
3218 rajveer 36
 
3187 rajveer 37
def initialize(dbname="logistics", db_hostname="localhost"):
442 rajveer 38
    log_entry("initialize@DataAccessor", "Initializing data service")
3187 rajveer 39
    DataService.initialize(dbname, db_hostname)
3218 rajveer 40
    print "Starting cache population at: " + str(datetime.datetime.now())
3217 rajveer 41
    __cache_warehouse_allocation_table()
42
    __cache_serviceable_location_details_table()
43
    __cache_delivery_estimate_table()
44
    close_session()
3218 rajveer 45
    print "Done cache population at: " + str(datetime.datetime.now())
442 rajveer 46
 
3217 rajveer 47
def __cache_delivery_estimate_table():
48
    delivery_estimates = DeliveryEstimate.query.all()
49
    for delivery_estimate in delivery_estimates:
5692 rajveer 50
        delivery_estimate_cache[delivery_estimate.destination_pin, delivery_estimate.provider_id]\
6537 rajveer 51
        =delivery_estimate.delivery_time, delivery_estimate.delivery_delay
3217 rajveer 52
 
53
def __cache_serviceable_location_details_table():
5964 amar.kumar 54
    serviceable_locations = ServiceableLocationDetails.query.filter(or_("exp!=0","cod!=0"))
3217 rajveer 55
    for serviceable_location in serviceable_locations:
56
        try:
57
            provider_pincodes = serviceable_location_cache[serviceable_location.provider_id]
58
        except:
59
            provider_pincodes = {}
60
            serviceable_location_cache[serviceable_location.provider_id] = provider_pincodes 
7489 rajveer 61
        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
3217 rajveer 62
 
63
def __cache_warehouse_allocation_table():
64
    warehouse_allocations = WarehouseAllocation.query.all()
65
    for warehouse_allocation in warehouse_allocations:
66
        warehouse_allocation_cache[warehouse_allocation.pincode]=warehouse_allocation.primary_warehouse_location
67
 
644 chandransh 68
def get_provider(provider_id):
766 rajveer 69
    provider =  Provider.get_by(id=provider_id)
70
    return provider
644 chandransh 71
 
72
def get_providers():
5387 rajveer 73
    providers = Provider.query.filter_by(isActive = 1).all()
766 rajveer 74
    return providers 
644 chandransh 75
 
7608 rajveer 76
def get_logistics_estimation(destination_pin, item_selling_price, weight, type, billingWarehouseId):
5692 rajveer 77
    logging.info("Getting logistics estimation for pincode:" + destination_pin )
1504 ankur.sing 78
 
7608 rajveer 79
    provider_id, codAllowed, otgAvailable = __get_logistics_provider_for_destination_pincode(destination_pin, item_selling_price, weight, type, billingWarehouseId)
3064 chandransh 80
 
3217 rajveer 81
    if not provider_id:
5692 rajveer 82
        raise LogisticsServiceException(101, "No provider assigned for pincode: " + str(destination_pin))
644 chandransh 83
    try:
5692 rajveer 84
        delivery_time = delivery_estimate_cache[destination_pin, provider_id][0]
6537 rajveer 85
        delivery_delay = delivery_estimate_cache[destination_pin, provider_id][1]
86
        delivery_estimate = _DeliveryEstimateObject(delivery_time, delivery_delay, provider_id, codAllowed, otgAvailable)
3218 rajveer 87
        return delivery_estimate
1504 ankur.sing 88
    except Exception as ex:
89
        print ex
644 chandransh 90
        raise LogisticsServiceException(103, "No Logistics partner listed for this destination pincode and the primary warehouse")
3150 rajveer 91
 
7608 rajveer 92
def __get_logistics_provider_for_destination_pincode(destination_pin, item_selling_price, weight, type, billingWarehouseId):
93
    if billingWarehouseId != 12 and serviceable_location_cache.get(6).has_key(destination_pin):
94
        if weight < 480 and serviceable_location_cache.get(3).has_key(destination_pin) and (type == DeliveryType.PREPAID or item_selling_price < 3000):
95
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit = serviceable_location_cache.get(3).get(destination_pin)
96
            iscod = iscod and item_selling_price <= websiteCodLimit
97
            otgAvailable = otgAvailable and item_selling_price >= 2000
98
            return 3, iscod, otgAvailable
99
        else:
100
            dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit = serviceable_location_cache.get(6).get(destination_pin)
101
            iscod = iscod and item_selling_price <= websiteCodLimit
102
            otgAvailable = otgAvailable and item_selling_price >= 2000
103
            return 6, iscod, otgAvailable
104
 
5692 rajveer 105
    if serviceable_location_cache.get(3).has_key(destination_pin):
7489 rajveer 106
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit = serviceable_location_cache.get(3).get(destination_pin)
107
        iscod = iscod and item_selling_price <= websiteCodLimit
6524 rajveer 108
        otgAvailable = otgAvailable and item_selling_price >= 2000
109
        return 3, iscod, otgAvailable
6370 rajveer 110
 
4866 rajveer 111
    if serviceable_location_cache.get(1).has_key(destination_pin):
7489 rajveer 112
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit = serviceable_location_cache.get(1).get(destination_pin)
113
        iscod = iscod and item_selling_price <= websiteCodLimit
6524 rajveer 114
        otgAvailable = otgAvailable and item_selling_price >= 2000
115
        return 1, iscod, otgAvailable
4866 rajveer 116
    else:
7442 vikram.rag 117
        return None, False, False    
5278 rajveer 118
 
6017 amar.kumar 119
def get_destination_code(providerId, pinCode):
120
    serviceableLocationDetail = ServiceableLocationDetails.query.filter_by(provider_id = providerId, dest_pincode = pinCode).one()
121
    return serviceableLocationDetail.dest_code
122
 
644 chandransh 123
def add_empty_AWBs(numbers, provider_id, type):
442 rajveer 124
    for number in numbers:
644 chandransh 125
        query = Awb.query.filter_by(awb_number = number, provider_id = provider_id)
444 rajveer 126
        try:
127
            query.one()
128
        except:    
644 chandransh 129
            awb = Awb()
444 rajveer 130
            awb.awb_number = number
644 chandransh 131
            awb.provider_id = provider_id
444 rajveer 132
            awb.is_available = True
644 chandransh 133
            awb.type = type
134
    session.commit()
442 rajveer 135
 
444 rajveer 136
def set_AWB_as_used(awb_number):
644 chandransh 137
    query = Awb.query.filter_by(awb_number = awb_number)
444 rajveer 138
    awb = query.one() 
139
    awb.is_available=False
140
    session.commit()
141
 
3044 chandransh 142
def get_empty_AWB(provider_id, type = DeliveryType.PREPAID):
2342 chandransh 143
    query = Awb.query.with_lockmode("update").filter_by(provider_id = provider_id, is_available = True)  #check the provider thing
3044 chandransh 144
    if type == DeliveryType.PREPAID:
145
        query = query.filter_by(type="Prepaid")
146
    if type == DeliveryType.COD:
147
        query = query.filter_by(type="COD")
148
 
442 rajveer 149
    try:
644 chandransh 150
        awb = query.first()
151
        awb.is_available = False
152
        session.commit()
444 rajveer 153
        return awb.awb_number
442 rajveer 154
    except:
644 chandransh 155
        raise LogisticsServiceException(103, "Unable to get an AWB for the given Provider: " + str(provider_id))
1137 chandransh 156
 
3103 chandransh 157
def get_free_awb_count(provider_id, type):
158
    count = Awb.query.filter_by(provider_id = provider_id, is_available = True, type=type).count()
1137 chandransh 159
    if count == None:
160
        count = 0
161
    return count
442 rajveer 162
 
644 chandransh 163
def get_shipment_info(awb_number, provider_id):
164
    awb = Awb.get_by(awb_number = awb_number, provider_id = provider_id)
165
    query = AwbUpdate.query.filter_by(awb = awb)
766 rajveer 166
    info = query.all()
167
    return info
168
 
6643 rajveer 169
def store_shipment_info(update):
170
    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()
171
    if not updates:
172
        dupdate = AwbUpdate()
173
        dupdate.providerId = update.providerId
174
        dupdate.awbNumber  = update.awbNumber
175
        dupdate.location = update.location
176
        dupdate.date = to_py_date(update.date)
177
        dupdate.status = update.status
178
        dupdate.description = update.description
179
        session.commit()
180
 
1730 ankur.sing 181
def get_holidays(start_date, end_date):
182
    query = PublicHolidays.query
183
    if start_date != -1:
184
        query = query.filter(PublicHolidays.date >= to_py_date(start_date))
185
    if end_date != -1:
186
        query = query.filter(PublicHolidays.date <= to_py_date(end_date))
187
    holidays = query.all()
188
    holiday_dates = [to_java_date(datetime.datetime(*time.strptime(str(holiday.date), '%Y-%m-%d')[:3])) for holiday in holidays] 
189
    return holiday_dates
190
 
5527 anupam.sin 191
def get_provider_for_pickup_type(pickUp):
192
    return Provider.query.filter(Provider.pickup == pickUp).first().id
193
 
766 rajveer 194
def close_session():
195
    if session.is_active:
196
        print "session is active. closing it."
2823 chandransh 197
        session.close()
3376 rajveer 198
 
199
def is_alive():
200
    try:
201
        session.query(Awb.id).limit(1).one()
202
        return True
203
    except:
5555 rajveer 204
        return False
205
 
206
def get_all_pickup_stores():
5572 anupam.sin 207
    pickupStores = PickupStore.query.all()
208
    return pickupStores
5555 rajveer 209
 
210
def get_pickup_store(storeId):
5719 rajveer 211
    return PickupStore.query.filter_by(id = storeId).one()
212
 
213
def get_pickup_store_by_hotspot_id(hotspotId):
214
    return PickupStore.query.filter_by(hotspotId = hotspotId).one()
6322 amar.kumar 215
 
6524 rajveer 216
def add_pincode(provider, pincode, destCode, exp, cod, stationType, otgAvailable):
6322 amar.kumar 217
    provider = Provider().query.filter_by(id = provider).one()
218
    serviceableLocationDetails = ServiceableLocationDetails()
219
    serviceableLocationDetails.provider = provider
220
    serviceableLocationDetails.dest_pincode = pincode
221
    serviceableLocationDetails.dest_code = destCode
222
    serviceableLocationDetails.exp = exp
223
    serviceableLocationDetails.cod = cod
224
    serviceableLocationDetails.station_type = stationType
6524 rajveer 225
    serviceableLocationDetails.otgAvailable = otgAvailable
7489 rajveer 226
    if provider == 1:
227
        limit = 10000
228
    elif provider == 3:
229
        limit = 25000
230
    elif provider == 6:
231
        limit = 25000
232
    serviceableLocationDetails.providerCodLimit = limit
233
    serviceableLocationDetails.websiteCodLimit = limit
234
    serviceableLocationDetails.websiteCodLimit = limit
6322 amar.kumar 235
    session.commit()
236
 
6524 rajveer 237
def update_pincode(providerId, pincode, exp, cod, otgAvailable):
6615 amar.kumar 238
    serviceableLocationDetails = ServiceableLocationDetails.get_by(provider_id = providerId, dest_pincode = pincode)
6322 amar.kumar 239
    serviceableLocationDetails.exp = exp
240
    serviceableLocationDetails.cod = cod
6524 rajveer 241
    serviceableLocationDetails.otgAvailable = otgAvailable
7256 rajveer 242
    session.commit()
7567 rajveer 243
 
244
def add_new_awbs(provider_id, isCod, awbs):
245
    provider = get_provider(provider_id)
246
    if isCod:
247
        dtype = 'Cod'
248
    else:
249
        dtype = 'Prepaid'
250
    for awb in awbs:
251
        a = Awb()
252
        a.type =  dtype
253
        a.is_available = True
254
        a.awb_number = awb
255
        a.provider = provider 
256
    session.commit()
7608 rajveer 257
    return True
7256 rajveer 258
 
259
def adjust_delivery_time(start_time, delivery_days):
260
    '''
261
    Returns the actual no. of days which will pass while 'delivery_days'
262
    no. of business days will pass since 'order_time'. 
263
    '''
264
    start_date = start_time.date()
265
    end_date = start_date + datetime.timedelta(days = delivery_days)
7272 amit.gupta 266
    holidays = get_holidays(to_java_date(start_time), -1)
7256 rajveer 267
    holidays = [to_py_date(holiday).date() for holiday in holidays]
268
 
269
    while start_date <= end_date:
270
        if start_date.weekday() == 6 or start_date in holidays:
271
            delivery_days = delivery_days + 1
272
            end_date = end_date + datetime.timedelta(days = 1)
273
        start_date = start_date + datetime.timedelta(days = 1)
274
 
275
    return delivery_days
7275 rajveer 276
 
277
def get_min_advance_amount(itemId, destination_pin, providerId, codAllowed):
278
    client = CatalogClient().get_client()
279
    sp = client.getStorePricing(itemId)
280
 
281
    if codAllowed:
282
        return sp.minAdvancePrice, True
283
    else:
7489 rajveer 284
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit = serviceable_location_cache.get(providerId).get(destination_pin)
7275 rajveer 285
        if iscod:
286
            if providerId == 6:
7489 rajveer 287
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 288
            if providerId == 3:
7489 rajveer 289
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 290
            if providerId == 1:
7489 rajveer 291
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 292
        else:
7425 rajveer 293
            return sp.recommendedPrice, False
7275 rajveer 294
 
295
 
296