Subversion Repositories SmartDukaan

Rev

Rev 7567 | Rev 7608 | 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
 
7589 rajveer 76
def get_logistics_estimation(destination_pin, item_selling_price, weight, type):
5692 rajveer 77
    logging.info("Getting logistics estimation for pincode:" + destination_pin )
1504 ankur.sing 78
 
7589 rajveer 79
    provider_id, codAllowed, otgAvailable = __get_logistics_provider_for_destination_pincode(destination_pin, item_selling_price, weight, type)
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
 
7589 rajveer 92
def __get_logistics_provider_for_destination_pincode(destination_pin, item_selling_price, weight, type):
93
    if serviceable_location_cache.get(6).has_key(destination_pin):
7489 rajveer 94
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit = serviceable_location_cache.get(6).get(destination_pin)
95
        iscod = iscod and item_selling_price <= websiteCodLimit
7021 rajveer 96
        otgAvailable = otgAvailable and item_selling_price >= 2000
7589 rajveer 97
        if weight >= 480 or (type == DeliveryType.COD and item_selling_price >= 3000):
98
            return 6, iscod, otgAvailable    
99
 
5692 rajveer 100
    if serviceable_location_cache.get(3).has_key(destination_pin):
7489 rajveer 101
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit = serviceable_location_cache.get(3).get(destination_pin)
102
        iscod = iscod and item_selling_price <= websiteCodLimit
6524 rajveer 103
        otgAvailable = otgAvailable and item_selling_price >= 2000
104
        return 3, iscod, otgAvailable
6370 rajveer 105
 
4866 rajveer 106
    if serviceable_location_cache.get(1).has_key(destination_pin):
7489 rajveer 107
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit = serviceable_location_cache.get(1).get(destination_pin)
108
        iscod = iscod and item_selling_price <= websiteCodLimit
6524 rajveer 109
        otgAvailable = otgAvailable and item_selling_price >= 2000
110
        return 1, iscod, otgAvailable
4866 rajveer 111
    else:
7442 vikram.rag 112
        return None, False, False    
5278 rajveer 113
 
6017 amar.kumar 114
def get_destination_code(providerId, pinCode):
115
    serviceableLocationDetail = ServiceableLocationDetails.query.filter_by(provider_id = providerId, dest_pincode = pinCode).one()
116
    return serviceableLocationDetail.dest_code
117
 
644 chandransh 118
def add_empty_AWBs(numbers, provider_id, type):
442 rajveer 119
    for number in numbers:
644 chandransh 120
        query = Awb.query.filter_by(awb_number = number, provider_id = provider_id)
444 rajveer 121
        try:
122
            query.one()
123
        except:    
644 chandransh 124
            awb = Awb()
444 rajveer 125
            awb.awb_number = number
644 chandransh 126
            awb.provider_id = provider_id
444 rajveer 127
            awb.is_available = True
644 chandransh 128
            awb.type = type
129
    session.commit()
442 rajveer 130
 
444 rajveer 131
def set_AWB_as_used(awb_number):
644 chandransh 132
    query = Awb.query.filter_by(awb_number = awb_number)
444 rajveer 133
    awb = query.one() 
134
    awb.is_available=False
135
    session.commit()
136
 
3044 chandransh 137
def get_empty_AWB(provider_id, type = DeliveryType.PREPAID):
2342 chandransh 138
    query = Awb.query.with_lockmode("update").filter_by(provider_id = provider_id, is_available = True)  #check the provider thing
3044 chandransh 139
    if type == DeliveryType.PREPAID:
140
        query = query.filter_by(type="Prepaid")
141
    if type == DeliveryType.COD:
142
        query = query.filter_by(type="COD")
143
 
442 rajveer 144
    try:
644 chandransh 145
        awb = query.first()
146
        awb.is_available = False
147
        session.commit()
444 rajveer 148
        return awb.awb_number
442 rajveer 149
    except:
644 chandransh 150
        raise LogisticsServiceException(103, "Unable to get an AWB for the given Provider: " + str(provider_id))
1137 chandransh 151
 
3103 chandransh 152
def get_free_awb_count(provider_id, type):
153
    count = Awb.query.filter_by(provider_id = provider_id, is_available = True, type=type).count()
1137 chandransh 154
    if count == None:
155
        count = 0
156
    return count
442 rajveer 157
 
644 chandransh 158
def get_shipment_info(awb_number, provider_id):
159
    awb = Awb.get_by(awb_number = awb_number, provider_id = provider_id)
160
    query = AwbUpdate.query.filter_by(awb = awb)
766 rajveer 161
    info = query.all()
162
    return info
163
 
6643 rajveer 164
def store_shipment_info(update):
165
    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()
166
    if not updates:
167
        dupdate = AwbUpdate()
168
        dupdate.providerId = update.providerId
169
        dupdate.awbNumber  = update.awbNumber
170
        dupdate.location = update.location
171
        dupdate.date = to_py_date(update.date)
172
        dupdate.status = update.status
173
        dupdate.description = update.description
174
        session.commit()
175
 
1730 ankur.sing 176
def get_holidays(start_date, end_date):
177
    query = PublicHolidays.query
178
    if start_date != -1:
179
        query = query.filter(PublicHolidays.date >= to_py_date(start_date))
180
    if end_date != -1:
181
        query = query.filter(PublicHolidays.date <= to_py_date(end_date))
182
    holidays = query.all()
183
    holiday_dates = [to_java_date(datetime.datetime(*time.strptime(str(holiday.date), '%Y-%m-%d')[:3])) for holiday in holidays] 
184
    return holiday_dates
185
 
5527 anupam.sin 186
def get_provider_for_pickup_type(pickUp):
187
    return Provider.query.filter(Provider.pickup == pickUp).first().id
188
 
766 rajveer 189
def close_session():
190
    if session.is_active:
191
        print "session is active. closing it."
2823 chandransh 192
        session.close()
3376 rajveer 193
 
194
def is_alive():
195
    try:
196
        session.query(Awb.id).limit(1).one()
197
        return True
198
    except:
5555 rajveer 199
        return False
200
 
201
def get_all_pickup_stores():
5572 anupam.sin 202
    pickupStores = PickupStore.query.all()
203
    return pickupStores
5555 rajveer 204
 
205
def get_pickup_store(storeId):
5719 rajveer 206
    return PickupStore.query.filter_by(id = storeId).one()
207
 
208
def get_pickup_store_by_hotspot_id(hotspotId):
209
    return PickupStore.query.filter_by(hotspotId = hotspotId).one()
6322 amar.kumar 210
 
6524 rajveer 211
def add_pincode(provider, pincode, destCode, exp, cod, stationType, otgAvailable):
6322 amar.kumar 212
    provider = Provider().query.filter_by(id = provider).one()
213
    serviceableLocationDetails = ServiceableLocationDetails()
214
    serviceableLocationDetails.provider = provider
215
    serviceableLocationDetails.dest_pincode = pincode
216
    serviceableLocationDetails.dest_code = destCode
217
    serviceableLocationDetails.exp = exp
218
    serviceableLocationDetails.cod = cod
219
    serviceableLocationDetails.station_type = stationType
6524 rajveer 220
    serviceableLocationDetails.otgAvailable = otgAvailable
7489 rajveer 221
    if provider == 1:
222
        limit = 10000
223
    elif provider == 3:
224
        limit = 25000
225
    elif provider == 6:
226
        limit = 25000
227
    serviceableLocationDetails.providerCodLimit = limit
228
    serviceableLocationDetails.websiteCodLimit = limit
229
    serviceableLocationDetails.websiteCodLimit = limit
6322 amar.kumar 230
    session.commit()
231
 
6524 rajveer 232
def update_pincode(providerId, pincode, exp, cod, otgAvailable):
6615 amar.kumar 233
    serviceableLocationDetails = ServiceableLocationDetails.get_by(provider_id = providerId, dest_pincode = pincode)
6322 amar.kumar 234
    serviceableLocationDetails.exp = exp
235
    serviceableLocationDetails.cod = cod
6524 rajveer 236
    serviceableLocationDetails.otgAvailable = otgAvailable
7256 rajveer 237
    session.commit()
7567 rajveer 238
 
239
def add_new_awbs(provider_id, isCod, awbs):
240
    provider = get_provider(provider_id)
241
    if isCod:
242
        dtype = 'Cod'
243
    else:
244
        dtype = 'Prepaid'
245
    for awb in awbs:
246
        a = Awb()
247
        a.type =  dtype
248
        a.is_available = True
249
        a.awb_number = awb
250
        a.provider = provider 
251
    session.commit()
7256 rajveer 252
 
253
def adjust_delivery_time(start_time, delivery_days):
254
    '''
255
    Returns the actual no. of days which will pass while 'delivery_days'
256
    no. of business days will pass since 'order_time'. 
257
    '''
258
    start_date = start_time.date()
259
    end_date = start_date + datetime.timedelta(days = delivery_days)
7272 amit.gupta 260
    holidays = get_holidays(to_java_date(start_time), -1)
7256 rajveer 261
    holidays = [to_py_date(holiday).date() for holiday in holidays]
262
 
263
    while start_date <= end_date:
264
        if start_date.weekday() == 6 or start_date in holidays:
265
            delivery_days = delivery_days + 1
266
            end_date = end_date + datetime.timedelta(days = 1)
267
        start_date = start_date + datetime.timedelta(days = 1)
268
 
269
    return delivery_days
7275 rajveer 270
 
271
def get_min_advance_amount(itemId, destination_pin, providerId, codAllowed):
272
    client = CatalogClient().get_client()
273
    sp = client.getStorePricing(itemId)
274
 
275
    if codAllowed:
276
        return sp.minAdvancePrice, True
277
    else:
7489 rajveer 278
        dest_code, exp, iscod, otgAvailable, websiteCodLimit, storeCodLimit = serviceable_location_cache.get(providerId).get(destination_pin)
7275 rajveer 279
        if iscod:
280
            if providerId == 6:
7489 rajveer 281
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 282
            if providerId == 3:
7489 rajveer 283
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 284
            if providerId == 1:
7489 rajveer 285
                return max(sp.minAdvancePrice, sp.recommendedPrice - storeCodLimit), True
7275 rajveer 286
        else:
7425 rajveer 287
            return sp.recommendedPrice, False
7275 rajveer 288
 
289
 
290