Subversion Repositories SmartDukaan

Rev

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