Subversion Repositories SmartDukaan

Rev

Rev 28178 | Rev 28554 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5944 mandeep.dh 1
'''
2
Created on 23-Mar-2010
3
 
4
@author: ashish
5
'''
6
from elixir import *
7
from functools import partial
6531 vikram.rag 8
from shop2020.clients.CatalogClient import CatalogClient
19413 amit.gupta 9
from shop2020.clients.LogisticsClient import LogisticsClient
5944 mandeep.dh 10
from shop2020.clients.TransactionClient import TransactionClient
11
from shop2020.model.v1.inventory.impl import DataService
6531 vikram.rag 12
from shop2020.model.v1.inventory.impl.Convertors import to_t_warehouse, \
19413 amit.gupta 13
    to_t_itemidwarehouseid, to_t_state, to_t_item_location_availability
5944 mandeep.dh 14
from shop2020.model.v1.inventory.impl.DataService import Warehouse, \
15
    ItemInventoryHistory, CurrentInventorySnapshot, VendorItemPricing, \
16
    VendorItemMapping, Vendor, MissedInventoryUpdate, BadInventorySnapshot, \
19413 amit.gupta 17
    VendorHolidays, ItemAvailabilityCache, CurrentReservationSnapshot, \
18
    IgnoredInventoryUpdateItems, ItemStockPurchaseParams, OOSStatus, \
19
    AmazonInventorySnapshot, StateMaster, HoldInventoryDetail, \
20
    AmazonFbaInventorySnapshot, SnapdealInventorySnapshot, FlipkartInventorySnapshot, \
21
    SnapdealStockAtEOD, FlipkartStockAtEOD, StockWeightedNlcInfo, \
22
    ItemLocationAvailabilityCache
23446 amit.gupta 23
from shop2020.thriftpy.logistics.ttypes import LocationInfo, PickUpType
6531 vikram.rag 24
from shop2020.thriftpy.model.v1.inventory.ttypes import \
23446 amit.gupta 25
    InventoryServiceException, HolidayType, InventoryType, WarehouseType, \
19413 amit.gupta 26
    ItemLocationAvailability, ItemPincodeAvailability
23316 amit.gupta 27
from shop2020.thriftpy.model.v1.order.ttypes import AlertType, TransactionStatus
6531 vikram.rag 28
from shop2020.thriftpy.purchase.ttypes import PurchaseServiceException
5944 mandeep.dh 29
from shop2020.utils import EmailAttachmentSender
30
from shop2020.utils.EmailAttachmentSender import mail
6821 amar.kumar 31
from shop2020.utils.Utils import to_py_date, to_java_date
23446 amit.gupta 32
from shop2020.utils.caching.SimpleCaching import memoized
5944 mandeep.dh 33
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
7410 amar.kumar 34
from sqlalchemy.sql import or_
12363 kshitij.so 35
from sqlalchemy.sql.expression import and_, func, distinct, desc
6531 vikram.rag 36
from sqlalchemy.sql.functions import count
5944 mandeep.dh 37
import calendar
38
import datetime
23446 amit.gupta 39
import json
19413 amit.gupta 40
import math
5944 mandeep.dh 41
import sys
42
import threading
43
 
10687 rajveer 44
to_addresses = ["khushal.bhatia@shop2020.in", "chaitnaya.vats@shop2020.in", "chandan.kumar@shop2020.in",'manoj.kumar@shop2020.in']
6029 rajveer 45
mail_user = "cnc.center@shop2020.in"
46
mail_password = "5h0p2o2o"
5944 mandeep.dh 47
skippedItems = { 175 : [27, 2160, 2175, 2163, 2158, 7128, 26, 2154],
48
                 193 : [5839] }
49
 
19413 amit.gupta 50
pincodePricingServiceabilityMap = {}
51
warehouseMap = {}
52
 
6821 amar.kumar 53
OOS_CALCULATION_TIME = 23
22991 amit.gupta 54
 
55
#right now these warehouse ids are ignored.
23029 amit.gupta 56
#physicalWarehouseIdsForFofo = [7678, 7681]
57
physicalWarehouseIdsForFofo = []
25468 amit.gupta 58
vendorWarehouseIdsForFofo = []
6498 vikram.rag 59
 
19413 amit.gupta 60
last_date = datetime.date.today()
61
adjusted_dates={}
62
 
23446 amit.gupta 63
partnerMap = {}
23442 amit.gupta 64
 
23446 amit.gupta 65
 
23937 amit.gupta 66
default_virtual_vendor = 290 
23446 amit.gupta 67
virtualVendorWarehouses = {}
23475 amit.gupta 68
billingVendorWarehouses = {}
23446 amit.gupta 69
 
5944 mandeep.dh 70
def initialize(dbname='inventory', db_hostname="localhost"):
71
    DataService.initialize(dbname, db_hostname)
19413 amit.gupta 72
    __populateWarehouseMap()
23446 amit.gupta 73
 
74
@memoized(3600)   
19413 amit.gupta 75
def __populateWarehouseMap():
76
    warehouses = Warehouse.query.filter(Warehouse.warehouseType.in_(['OURS', 'THIRD_PARTY'])).filter(Warehouse.inventoryType == 'GOOD').all()
77
    for warehouse in warehouses:
78
        warehouseMap[warehouse.id] = warehouse
23503 amit.gupta 79
        print warehouse.id, warehouse.vendor
23483 amit.gupta 80
        if warehouse.vendor.id==default_virtual_vendor and warehouse.warehouseType == 'THIRD_PARTY':
23606 amit.gupta 81
            virtualVendorWarehouses[warehouse.state_id] = warehouse 
23503 amit.gupta 82
        if warehouse.vendor.id==default_virtual_vendor and warehouse.warehouseType == 'OURS':
83
            billingVendorWarehouses[warehouse.state_id] = warehouse.billingWarehouseId
25468 amit.gupta 84
 
85
        if warehouse.billingWarehouseId in physicalWarehouseIdsForFofo:
86
            vendorWarehouseIdsForFofo.append(warehouse.id)
25481 amit.gupta 87
        warehouse.expunge()
27448 amit.gupta 88
    #for punjab map to delhi
89
    virtualVendorWarehouses[9] = virtualVendorWarehouses[0]
28553 amit.gupta 90
    virtualVendorWarehouses[10] = virtualVendorWarehouses[0] 
24000 amit.gupta 91
    print "billingVendorWarehouses", billingVendorWarehouses
92
    print "virtualVendorWarehouses", virtualVendorWarehouses 
19413 amit.gupta 93
 
5944 mandeep.dh 94
def get_Warehouse(warehouse_id):
95
    return Warehouse.get_by(id=warehouse_id)
96
 
97
def get_vendor(vendorId):
98
    return Vendor.get_by(id=vendorId)
99
 
7410 amar.kumar 100
def get_state(stateId):
101
    return StateMaster.get_by(id=stateId)
102
 
5944 mandeep.dh 103
def get_all_warehouses_by_status(status):
104
    return Warehouse.query.all()
105
 
106
def get_all_items_for_warehouse(warehouse_id):
107
    warehouse = get_Warehouse(warehouse_id)
108
    if not warehouse:
109
        raise InventoryServiceException(108, "bad warehouse")
110
    return warehouse.all_items
111
 
112
def add_warehouse(warehouse):
113
    if not warehouse:
114
        raise InventoryServiceException(108, "Bad warehouse")
115
    if get_Warehouse(warehouse.id):
116
        #warehouse is already present.
117
        raise InventoryServiceException(101, "Warehouse already present")
118
 
119
    ds_warehouse = Warehouse()
120
    ds_warehouse.location = warehouse.location
121
    ds_warehouse.status = 3
122
    ds_warehouse.addedOn = datetime.datetime.now()
123
    ds_warehouse.lastCheckedOn = datetime.datetime.now()
124
    ds_warehouse.tinNumber = warehouse.tinNumber
125
    ds_warehouse.pincode = warehouse.pincode
126
    ds_warehouse.billingType = warehouse.billingType
127
    ds_warehouse.billingWarehouseId = warehouse.billingWarehouseId
128
    ds_warehouse.displayName = warehouse.displayName
129
    ds_warehouse.inventoryType = InventoryType._VALUES_TO_NAMES[warehouse.inventoryType]
130
    ds_warehouse.isAvailabilityMonitored = warehouse.isAvailabilityMonitored
131
    ds_warehouse.logisticsLocation = warehouse.logisticsLocation
132
    ds_warehouse.shippingWarehouseId = warehouse.shippingWarehouseId
133
    ds_warehouse.transferDelayInHours = warehouse.transferDelayInHours
134
    ds_warehouse.vendor = get_vendor(warehouse.vendor.id)
7410 amar.kumar 135
    ds_warehouse.state = get_state(warehouse.stateId)
5944 mandeep.dh 136
    ds_warehouse.warehouseType = WarehouseType._VALUES_TO_NAMES[warehouse.warehouseType]    
137
    if warehouse.vendorString:
138
        ds_warehouse.vendorString = warehouse.vendorString
139
    session.commit()
140
    return ds_warehouse.id
141
 
6498 vikram.rag 142
def get_ignored_items(warehouse_id): 
6531 vikram.rag 143
    Ignored_inventory_items = IgnoredInventoryUpdateItems.query.filter_by(warehouse_id=warehouse_id).all()
6498 vikram.rag 144
    negativeItems = []
145
    for Ignored_inventory_item in Ignored_inventory_items:
146
        try:
147
            item_id = Ignored_inventory_item.item_id
148
            negativeItems.append(item_id)
149
        except:
150
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
151
    return negativeItems
152
 
22630 amit.gupta 153
def get_ignored_warehouses(item_id):
154
    warehouses = []
155
    #No item availability cache for Hotspot Specific Store
156
    #No virtual is allowed
6539 amit.gupta 157
    Ignored_inventory_items = IgnoredInventoryUpdateItems.query.filter_by(item_id=item_id).all()
6510 rajveer 158
    for Ignored_inventory_item in Ignored_inventory_items:
159
        warehouses.append(Ignored_inventory_item.warehouse_id)
25459 amit.gupta 160
    return warehouses
6510 rajveer 161
 
5944 mandeep.dh 162
def update_inventory_history(warehouse_id, timestamp, availability):
163
    warehouse = get_Warehouse(warehouse_id)
164
    if not warehouse:
165
        raise InventoryServiceException(107, "Warehouse? Where?")
166
    vendor = warehouse.vendor
167
    time = datetime.datetime.now()
168
    for item_key, quantity in availability.iteritems():
169
        try:
170
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
5960 mandeep.dh 171
            item_id = vendor_item_mapping.item_id
5944 mandeep.dh 172
        except:
6531 vikram.rag 173
            continue  
5944 mandeep.dh 174
        try:
6510 rajveer 175
            item_inventory_history = ItemInventoryHistory()
176
            item_inventory_history.warehouse = warehouse
177
            item_inventory_history.item_id = item_id
178
            item_inventory_history.timestamp = time
179
            item_inventory_history.availability = quantity
5944 mandeep.dh 180
        except:
181
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
182
    session.commit()
183
 
184
def update_inventory(warehouse_id, timestamp, availability):
185
    warehouse = get_Warehouse(warehouse_id)
186
    if not warehouse:
187
        raise InventoryServiceException(107, "Warehouse? Where?")
6510 rajveer 188
 
5944 mandeep.dh 189
    time = datetime.datetime.now()
190
    warehouse.lastCheckedOn = time
191
    warehouse.vendorString = timestamp
192
    vendor = warehouse.vendor
193
    item_ids = []
194
    for item_key, quantity in availability.iteritems():
195
        try:
196
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
197
            item_id = vendor_item_mapping.item_id
6510 rajveer 198
            item_ids.append(item_id)
5944 mandeep.dh 199
        except:
200
            print 'Skipping update for ' + item_key + ' quantity ' + str(quantity) + ' warehouse id: ' + str(warehouse_id)
201
            __send_mail_for_missing_key(item_key, quantity, warehouse_id)
202
            continue
203
        try:
204
            current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=item_id, warehouse=warehouse)
205
            if not current_inventory_snapshot:
206
                current_inventory_snapshot = CurrentInventorySnapshot()
207
                current_inventory_snapshot.item_id = item_id
208
                current_inventory_snapshot.warehouse = warehouse
209
                current_inventory_snapshot.availability = 0
210
                current_inventory_snapshot.reserved = 0
8204 amar.kumar 211
                current_inventory_snapshot.held = 0
5944 mandeep.dh 212
            # added the difference in the current inventory    
213
            current_inventory_snapshot.availability = current_inventory_snapshot.availability + quantity
214
            item = __get_item_from_master(item_id)
215
            try:
216
                if quantity > 0 and __get_item_reserved(item_id) > 0:
217
                    cl = TransactionClient().get_client()
218
                    #FIXME hardcoding for warehouse id 
219
                    cl.addAlert(AlertType.NEW_INVENTORY_ALERT, 5, "Inventory received for item " + item.brand + " " + item.modelName + " " + item.modelNumber + " " +  item.color)
220
            except:
221
                print "Not able to raise alert for incoming inventory" 
222
            if current_inventory_snapshot.availability < 0:
223
                __send_alert_for_negative_availability(item, current_inventory_snapshot.availability, warehouse)
224
        except:
225
            print "Some unforeseen error while updating inventory:", sys.exc_info()[0]
226
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
227
    session.commit()
228
 
229
    #**Update item availability cache**#
230
    for item_id in item_ids:
5978 rajveer 231
        clear_item_availability_cache(item_id)
5944 mandeep.dh 232
 
233
def __send_alert_for_negative_reserved(item, reserved, warehouse):
234
    itemName = " ".join([str(item.id), str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
10253 manish.sha 235
    EmailAttachmentSender.mail(mail_user, mail_password, 'manish.sharma@shop2020.in', 'Negative reserved: ' + str(reserved) + ' for Item Id: ' + itemName + ' warehouse id: ' + str(warehouse.id), None)
5944 mandeep.dh 236
 
237
def __send_alert_for_negative_availability(item, availability, warehouse):
238
    itemName = " ".join([str(item.id), str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
5964 amar.kumar 239
    # EmailAttachmentSender.mail('cnc.center@shop2020.in', '5h0p2o2o', 'amar.kumar@shop2020.in', 'Negative availability ' + str(availability) + ' for Item id: ' + itemName + ' warehouse id: ' + str(warehouse.id), None)
5944 mandeep.dh 240
 
241
def __send_mail_for_missing_key(item_key, quantity, warehouse_id):
242
    missedInventoryUpdate = MissedInventoryUpdate.get_by(itemKey = item_key, warehouseId = warehouse_id)
243
    # One email per product key mismatch
244
    if not missedInventoryUpdate:
245
        missedInventoryUpdate = MissedInventoryUpdate()
246
        missedInventoryUpdate.itemKey = item_key
247
        missedInventoryUpdate.quantity = quantity
248
        missedInventoryUpdate.isIgnored = 1
249
        missedInventoryUpdate.timestamp = datetime.datetime.now()
250
        missedInventoryUpdate.warehouseId = warehouse_id
251
        session.commit()
6232 rajveer 252
        try:
8214 amar.kumar 253
            EmailAttachmentSender.mail(mail_user, mail_password, ['chaitnaya.vats@shop2020.in', 'chandan.kumar@shop2020.in', 'khushal.bhatia@shop2020.in', 'manoj.kumar@shop2020.in'], 'Skipped inventory update for ' + item_key + ' quantity ' + str(quantity) + ' warehouse id: ' + str(warehouse_id), None)
6232 rajveer 254
        except:
255
            print "Not able to send email. No issues, we can continue with updates."
5944 mandeep.dh 256
    else:
257
        missedInventoryUpdate.quantity += quantity
258
        session.commit()
259
 
19989 kshitij.so 260
def add_inventory(itemId, warehouseId, quantity, skipAddition=False):
5944 mandeep.dh 261
    current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
262
    if not current_inventory_snapshot:
263
        current_inventory_snapshot = CurrentInventorySnapshot()
264
        current_inventory_snapshot.item_id = itemId
265
        current_inventory_snapshot.warehouse_id = warehouseId
266
        current_inventory_snapshot.availability = 0
267
        current_inventory_snapshot.reserved = 0
8204 amar.kumar 268
        current_inventory_snapshot.held = 0
19989 kshitij.so 269
    # added the difference in the current inventory
270
    if skipAddition is None or not skipAddition:    
271
        current_inventory_snapshot.availability = current_inventory_snapshot.availability + quantity
272
    else:
273
        current_inventory_snapshot.availability = quantity
5944 mandeep.dh 274
    session.commit()
275
    #**Update item availability cache**#
20849 amit.gupta 276
    clear_item_availability_cache(itemId)
5944 mandeep.dh 277
    if current_inventory_snapshot.availability < 0:
278
        item = __get_item_from_master(itemId)
5978 rajveer 279
        __send_alert_for_negative_availability(item, current_inventory_snapshot.availability, get_Warehouse(warehouseId)) 
5944 mandeep.dh 280
 
281
def add_bad_inventory(itemId, warehouseId, quantity):
282
    bad_inventory_snapshot = BadInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
283
    if not bad_inventory_snapshot:
284
        bad_inventory_snapshot = BadInventorySnapshot()
285
        bad_inventory_snapshot.item_id = itemId
286
        bad_inventory_snapshot.warehouse_id = warehouseId
287
        bad_inventory_snapshot.availability = 0
288
    # added the difference in the current inventory    
289
    bad_inventory_snapshot.availability += quantity
290
    session.commit()
291
    if bad_inventory_snapshot.availability < 0:
292
        item = __get_item_from_master(itemId)
293
        __send_alert_for_negative_availability(item, bad_inventory_snapshot.availability, get_Warehouse(warehouseId))
294
 
295
def get_item_inventory_by_item_id(item_id):
296
    return CurrentInventorySnapshot.query.filter_by(item_id=item_id).all()
297
 
298
def retire_warehouse(warehouse_id):
299
    if not warehouse_id:
300
        raise InventoryServiceException(101, "Bad warehouse id")
301
    warehouse = get_Warehouse(warehouse_id)
302
    if not warehouse:
303
        raise InventoryServiceException(108, "warehouse id not present")
304
    warehouse.status = 0;
305
    session.commit()
306
 
307
def get_item_availability_for_warehouse(warehouse_id, item_id):
6545 rajveer 308
    ignore = IgnoredInventoryUpdateItems.query.filter_by(item_id=item_id).filter_by(warehouse_id = warehouse_id).all()
6544 rajveer 309
    if ignore:
310
        return 0
5944 mandeep.dh 311
 
312
    try:
6544 rajveer 313
        current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id).filter_by(item_id = item_id).one()
15958 amit.gupta 314
        return current_inventory_snapshot.availability - current_inventory_snapshot.reserved - current_inventory_snapshot.held
5944 mandeep.dh 315
    except:
316
        return 0
317
 
6484 amar.kumar 318
def get_item_availability_for_our_warehouses(item_ids):
7699 amar.kumar 319
    our_warehouses = Warehouse.query.filter_by(warehouseType = 'OURS', inventoryType = 'GOOD').all()
320
    our_thirdparty_warehouses = Warehouse.query.filter_by(warehouseType = 'OURS_THIRDPARTY').all()
6484 amar.kumar 321
    warehouse_ids = []
7699 amar.kumar 322
    for warehouse in our_warehouses :
6484 amar.kumar 323
        warehouse_ids.append(warehouse.id)
10170 amar.kumar 324
    #for warehouse in our_thirdparty_warehouses :
325
    #    warehouse_ids.append(warehouse.id)
7699 amar.kumar 326
 
6484 amar.kumar 327
    availability_map = dict()
328
 
329
    try :
330
        for item_id in item_ids :
331
            total_availability = 0
332
            for current_inventory_snapshot in CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).filter_by(item_id = item_id).all():
333
                total_availability += current_inventory_snapshot.availability
334
            if total_availability >0:
335
                availability_map[item_id] = total_availability
336
    except Exception as e:
337
        print e
338
        raise PurchaseServiceException(101, 'Exception while fetching availability of items in our warehouses')
339
 
340
    return availability_map
341
 
22991 amit.gupta 342
#As of now as warehouse can be managed independently we just need to return itemavailability cache for the item ids provided
22719 amit.gupta 343
def get_fofo_availability(item_ids):
344
    returnMap = {}
345
    if not item_ids:
346
        return returnMap
22991 amit.gupta 347
    for item_id in item_ids:
348
        returnMap[item_id] = get_item_availability_for_location(item_id, 1)[4]
22719 amit.gupta 349
    return returnMap
350
 
22721 amit.gupta 351
def get_fofo_fulfilment_warehouse_map(itemIds):
352
    returnMap = {}
22722 amit.gupta 353
    snapshots = CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(vendorWarehouseIdsForFofo)).filter(CurrentInventorySnapshot.item_id.in_(itemIds)).all()
22721 amit.gupta 354
    for snapshot in snapshots:
355
        availability = snapshot.availability - snapshot.reserved - snapshot.held
356
        if availability > 0:
357
            if not returnMap.has_key(snapshot.item_id):
358
                returnMap[snapshot.item_id] = to_t_warehouse(snapshot.warehouse)
359
    return returnMap 
360
 
361
 
362
 
5944 mandeep.dh 363
'''
364
This method returns quantity of a particular item across all warehouses whose ids is provided
365
if warehouse_ids is null it checks for inventory in all warehouses.
366
'''
367
def __get_item_availability(item, warehouse_ids):
368
    if warehouse_ids is None:
369
        all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
370
        availability = 0
371
        reserved = 0
372
        for currInv in all_inventory:
373
            availability = availability + currInv.availability
374
            reserved = reserved + currInv.reserved
375
        return availability - reserved
376
    else:
377
        total_availability = 0
378
        for current_inventory_snapshot in CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).filter_by(item_id = item.id).all():
379
            total_availability += current_inventory_snapshot.availability - current_inventory_snapshot.reserved
380
        return total_availability 
381
 
382
def __get_item_reserved(item_id):
383
    all_inventory = CurrentInventorySnapshot.query.filter_by(item_id = item_id).all()
384
    reserved = 0
385
    for currInv in all_inventory:
386
        reserved = reserved + currInv.reserved
387
    return reserved
5966 rajveer 388
 
389
def __get_item_availability_at_warehouse(warehouse_id, item_id):
390
    inventory = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).one()
391
    return inventory.availability
392
 
393
def is_order_billable(item_id, warehouse_id, source_id, order_id):
394
    reservations = CurrentReservationSnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).order_by(CurrentReservationSnapshot.promised_shipping_timestamp).order_by(CurrentReservationSnapshot.created_timestamp).all()
395
    availability = __get_item_availability_at_warehouse(warehouse_id, item_id)
396
    for reservation in reservations:
397
        availability = availability - reservation.reserved
398
        if reservation.order_id == order_id and reservation.source_id == source_id:
399
            break
400
    if availability < 0:
401
        return False
402
    return True
5944 mandeep.dh 403
 
19989 kshitij.so 404
def reserve_item_in_warehouse(item_id, warehouse_id, source_id, order_id, created_timestamp, promised_shipping_timestamp, quantity):
405
 
5944 mandeep.dh 406
    if not warehouse_id:
407
        raise InventoryServiceException(101, "bad warehouse_id")
408
 
409
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
410
    try:
411
        current_inventory_snapshot = query.one()
412
    except:
413
        current_inventory_snapshot = CurrentInventorySnapshot()
414
        current_inventory_snapshot.warehouse_id = warehouse_id
415
        current_inventory_snapshot.item_id = item_id
416
        current_inventory_snapshot.availability = 0
417
        current_inventory_snapshot.reserved = 0
8204 amar.kumar 418
        current_inventory_snapshot.held = 0
5944 mandeep.dh 419
 
420
    current_inventory_snapshot.reserved = current_inventory_snapshot.reserved + quantity
5966 rajveer 421
 
422
    reservation = CurrentReservationSnapshot()
423
    reservation.item_id = item_id
424
    reservation.warehouse_id = warehouse_id
425
    reservation.source_id = source_id
426
    reservation.order_id = order_id
5990 rajveer 427
    reservation.created_timestamp = to_py_date(created_timestamp)
428
    reservation.promised_shipping_timestamp = to_py_date(promised_shipping_timestamp)
5966 rajveer 429
    reservation.reserved = quantity
430
 
8720 amar.kumar 431
    session.commit()
8182 amar.kumar 432
 
433
    try:
434
        order_client = TransactionClient().get_client()
435
        order = order_client.getOrder(order_id)
9574 amar.kumar 436
        if order.source:
437
            holdInventoryDetail = HoldInventoryDetail.query.filter_by(item_id = item_id, warehouse_id = warehouse_id, source = order.source).first()
9694 amar.kumar 438
            if holdInventoryDetail is None or holdInventoryDetail.held<=0:
439
                holdInventoryDetails = HoldInventoryDetail.query.filter_by(item_id = item_id, source = order.source).all()
440
                if holdInventoryDetails:
441
                    for hID in holdInventoryDetails:
442
                        if hID.held>0:
443
                            holdInventoryDetail = hID
9574 amar.kumar 444
            if holdInventoryDetail is not None and holdInventoryDetail.held>0:
445
                previousHeld = holdInventoryDetail.held
446
                holdInventoryDetail.held = max(0, holdInventoryDetail.held -quantity)
447
                diff = previousHeld-holdInventoryDetail.held 
9770 amar.kumar 448
                current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=item_id, warehouse_id=holdInventoryDetail.warehouse_id)
9574 amar.kumar 449
                if current_inventory_snapshot is not None:
450
                    current_inventory_snapshot.held = max(0, current_inventory_snapshot.held - diff)
451
                session.commit()
8182 amar.kumar 452
    except:
453
        print "Unable to release hold Inventory for item_id " + str(item_id) + " warehouse_id " + str(warehouse_id) + " source " + str(source_id)
8720 amar.kumar 454
    #session.commit()
5944 mandeep.dh 455
    #**Update item availability cache**#
5978 rajveer 456
    clear_item_availability_cache(item_id)
5944 mandeep.dh 457
    return True
458
 
7968 amar.kumar 459
def update_reservation_for_order(item_id, warehouse_id, source_id, order_id, created_timestamp, promised_shipping_timestamp, quantity):    
460
    if not warehouse_id:
461
        raise InventoryServiceException(101, "bad warehouse_id")
23516 amit.gupta 462
    warehouse = get_Warehouse(warehouse_id)
463
    '''item_pricing = get_item_pricing(item_id, warehouse.vendor.id)
464
    if not item_pricing:
465
        raise InventoryServiceException(101, "No Pricing Info found for vendor and Item")'''
466
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
467
    try:
468
        new_current_inventory_snapshot = query.one()
469
    except:
470
        new_current_inventory_snapshot = CurrentInventorySnapshot()
471
        new_current_inventory_snapshot.warehouse_id = warehouse_id
472
        new_current_inventory_snapshot.item_id = item_id
473
        new_current_inventory_snapshot.availability = 0
474
        new_current_inventory_snapshot.reserved = 0
7968 amar.kumar 475
 
23516 amit.gupta 476
    new_current_inventory_snapshot.reserved = new_current_inventory_snapshot.reserved + quantity
7968 amar.kumar 477
 
478
    new_reservation = CurrentReservationSnapshot()
479
    new_reservation.item_id = item_id
480
    new_reservation.warehouse_id = warehouse_id
481
    new_reservation.source_id = source_id
482
    new_reservation.order_id = order_id
483
    new_reservation.created_timestamp = to_py_date(created_timestamp)
484
    new_reservation.promised_shipping_timestamp = to_py_date(promised_shipping_timestamp)
485
    new_reservation.reserved = quantity
486
 
8182 amar.kumar 487
    try:
488
        order_client = TransactionClient().get_client()
489
        order = order_client.getOrder(order_id)
9574 amar.kumar 490
        if order.source:
491
            holdInventoryDetail = HoldInventoryDetail.query.filter_by(item_id = item_id, warehouse_id = warehouse_id, source = order.source).first()
9694 amar.kumar 492
            if holdInventoryDetail is None or holdInventoryDetail.held<=0:
493
                holdInventoryDetails = HoldInventoryDetail.query.filter_by(item_id = item_id, source = order.source).all()
494
                if holdInventoryDetails:
495
                    for hID in holdInventoryDetails:
496
                        if hID.held>0:
497
                            holdInventoryDetail = hID
9574 amar.kumar 498
            if holdInventoryDetail is not None and holdInventoryDetail.held>0:
499
                previousHeld = holdInventoryDetail.held
500
                holdInventoryDetail.held = max(0, holdInventoryDetail.held -quantity)
501
                diff = previousHeld-holdInventoryDetail.held 
9770 amar.kumar 502
                current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=item_id, warehouse_id=holdInventoryDetail.warehouse_id)
9574 amar.kumar 503
                if current_inventory_snapshot is not None:
504
                    current_inventory_snapshot.held = max(0, current_inventory_snapshot.held - diff)
505
                session.commit()
8182 amar.kumar 506
    except:
507
        print "Unable to release hold Inventory for item_id " + str(item_id) + " warehouse_id " + str(warehouse_id) + " source " + str(source_id)
508
 
7968 amar.kumar 509
    order_client = TransactionClient().get_client()
510
    order = order_client.getOrder(order_id)
511
    for lineitem in order.lineitems:
512
        query = CurrentInventorySnapshot.query.filter_by(warehouse_id = order.fulfilmentWarehouseId, item_id = lineitem.item_id)
513
        try:
514
            current_inventory_snapshot = query.one()
515
            current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
516
 
517
            reservation = CurrentReservationSnapshot.query.filter_by(warehouse_id = order.fulfilmentWarehouseId, item_id = lineitem.item_id, source_id = source_id, order_id = order_id).one()
518
            if reservation.reserved == quantity:
519
                reservation.delete()
520
            else:
521
                reservation.reserved -= quantity
522
 
523
            clear_item_availability_cache(lineitem.item_id)
524
            session.commit()
525
            try:
526
                if current_inventory_snapshot.reserved < 0:
527
                    item = __get_item_from_master(lineitem.item_id)
528
                    __send_alert_for_negative_reserved(item, current_inventory_snapshot.reserved, get_Warehouse(order.fulfilmentWarehouseId))
529
            except:
8182 amar.kumar 530
                print "Error in sending negative reserved alert:", sys.exc_info()[0]
7968 amar.kumar 531
                return False
532
        except:
533
            print "Error in reducing reservation for item:", sys.exc_info()[0]
534
            return False
535
    session.commit()
536
    #**Update item availability cache**#
537
    clear_item_availability_cache(item_id)
538
    return True
539
 
19419 amit.gupta 540
def get_item_pincode_availability(itemPricingMap, pin_code):
19413 amit.gupta 541
    returnMap = {}
542
    missingItemPricingList = []
543
    for item_id, pricing in itemPricingMap.iteritems():
544
        if not pricing:
545
            missingItemPricingList.append(item_id)
20641 amit.gupta 546
    if missingItemPricingList:
547
        cc = CatalogClient().get_client()
548
        items = cc.getItems(missingItemPricingList)
549
        lc = LogisticsClient().get_client()
550
        #Consider selling price if its missing in itempricing
551
        for item in items:
552
            itemPricingMap[item.id] = item.sellingPrice
19413 amit.gupta 553
    pricingLocationInfoMap = __getLocationInfoMap(pin_code, itemPricingMap)    
554
    if pricingLocationInfoMap == -1:
555
        returnMap = {"pincode_serviceable":False}    
556
    else:
557
        #for item_id, sellingPrice in itemPricingMap.iteritems():
558
        allLocations = pricingLocationInfoMap[1].keys()    
559
        itemLocationAvailabilityList = __get_item_location_availability_bulk(itemPricingMap.keys(), allLocations)
560
        pricingLocationsMap = {}
561
        for itemLocationAvailability in itemLocationAvailabilityList:
562
            sellingPrice = itemPricingMap[itemLocationAvailability.item_id]
563
            if pricingLocationInfoMap[sellingPrice] == -1:
564
                continue
565
            if not pricingLocationsMap.has_key(sellingPrice):
566
                pricingLocationsMap[sellingPrice] = pricingLocationInfoMap[sellingPrice].keys() 
567
 
568
            if itemLocationAvailability.location_id not in pricingLocationsMap[sellingPrice]:
569
                continue
570
            if not returnMap.has_key(itemLocationAvailability.item_id):
571
                returnMap[itemLocationAvailability.item_id] = ItemPincodeAvailability(vatQty = 0, totalQty = 0, minDeliveryDate=-1)
572
            itemPincodeAvailability = ItemPincodeAvailability()
573
            itemPincodeAvailability = returnMap[itemLocationAvailability.item_id]
574
            locationInfo = LocationInfo()
575
            locationInfo = pricingLocationInfoMap[sellingPrice][itemLocationAvailability.location_id]
576
            locationQty = itemLocationAvailability.virtual_availability + itemLocationAvailability.physical_availability
577
            if locationInfo.sameState:
578
                itemPincodeAvailability.vatQty += locationQty
579
            itemPincodeAvailability.totalQty += locationQty
580
            itemPincodeAvailability.isCod = itemPincodeAvailability.isCod or locationInfo.isCod 
581
            itemPincodeAvailability.isOtg = itemPincodeAvailability.isOtg or locationInfo.isOtg 
582
            if itemPincodeAvailability.minDeliveryDate == -1:
583
                itemPincodeAvailability.minDeliveryDate = itemLocationAvailability.min_transfer_delay + locationInfo.minDelay 
584
                itemPincodeAvailability.maxDeliveryDate = itemLocationAvailability.max_transfer_delay + locationInfo.maxDelay
585
            else:
586
                itemPincodeAvailability.minDeliveryDate = min(itemPincodeAvailability.minDeliveryDate, itemLocationAvailability.min_transfer_delay + locationInfo.minDelay) 
587
                itemPincodeAvailability.maxDeliveryDate = max(itemPincodeAvailability.maxDeliveryDate, itemLocationAvailability.max_transfer_delay + locationInfo.maxDelay)
588
        for itemId, itemPincodeAvailability in returnMap.iteritems():
589
            sellingPrice = itemPricingMap[itemId]
590
            locationsMap = pricingLocationsMap[sellingPrice]
591
            minDay = math.ceil(itemPincodeAvailability.minDeliveryDate)
592
            maxDay = math.ceil(itemPincodeAvailability.maxDeliveryDate)
593
            itemPincodeAvailability.minDeliveryDate, itemPincodeAvailability.maxDeliveryDate = __getDeliveryDate(minDay, itemPincodeAvailability.isCod, maxDay)
594
 
595
    return json.dumps(returnMap)
596
 
597
 
598
def __getLocationInfoMap(pin_code, itemPricingMap):
20641 amit.gupta 599
    priceSet = set(itemPricingMap.values() + [1])
19413 amit.gupta 600
    if not pincodePricingServiceabilityMap.has_key(pin_code):
601
        pincodePricingServiceabilityMap[pin_code] = {}
602
    pricingMap = pincodePricingServiceabilityMap[pin_code]
603
    if pricingMap != -1: 
20641 amit.gupta 604
        missingInMap = list(priceSet - set(pricingMap.keys())) 
605
        if missingInMap:
606
            lc = LogisticsClient().get_client()
607
            priceLocationInfoMap = lc.getLocationInfoMap(pin_code, missingInMap)
608
            if not priceLocationInfoMap:
609
                pricingMap = pincodePricingServiceabilityMap[pin_code] = -1
610
            else:
611
                for sellingPrice in missingInMap:
612
                    if priceLocationInfoMap[sellingPrice] == {}:
613
                        pricingMap[sellingPrice] = -1
614
                    else:
615
                        pricingMap[sellingPrice] = priceLocationInfoMap[sellingPrice]
19413 amit.gupta 616
 
617
    return pricingMap
618
 
619
def __getDeliveryDate(minDays, isCod, maxDays=None):
620
    curTime = datetime.datetime.now()
621
    if maxDays is None:
622
        maxDays = minDays 
623
    if isCod and curTime.hour < 15:
624
        maxDays = maxDays + 1
625
    return __getAdjustedDate(minDays), __getAdjustedDate(maxDays) 
7968 amar.kumar 626
 
19413 amit.gupta 627
def __getAdjustedDate(days):
628
    curDate = datetime.date.today()
629
    if curDate == last_date:
630
        if adjusted_dates.has_key(days):
631
            return adjusted_dates[days]
632
    else:
633
        adjusted_dates = {}
634
    lc = LogisticsClient().get_client()
635
    adjusted_day = lc.adjustDeliveryDays(datetime.datetime.now(), to_java_date(days))
636
 
637
    adjusted_date = to_java_date(datetime.datetime.combine(curDate, datetime.datetime.min.time()) + datetime.timedelta(days=adjusted_day))
638
    adjusted_dates[days] = adjusted_date
639
    return adjusted_date
640
 
5966 rajveer 641
def reduce_reservation_count(item_id, warehouse_id, source_id, order_id, quantity):
5944 mandeep.dh 642
    if not warehouse_id:
643
        raise InventoryServiceException(101, "bad warehouse_id")
644
 
645
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
646
    try:
647
        current_inventory_snapshot = query.one()
648
        current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
5966 rajveer 649
 
650
        reservation = CurrentReservationSnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id, source_id = source_id, order_id = order_id).one()
651
        if reservation.reserved == quantity:
652
            reservation.delete()
653
        else:
654
            reservation.reserved -= quantity
5944 mandeep.dh 655
        session.commit()
656
        #**Update item availability cache**#
5978 rajveer 657
        clear_item_availability_cache(item_id)
5944 mandeep.dh 658
        if current_inventory_snapshot.reserved < 0:
659
            item = __get_item_from_master(item_id)
660
            __send_alert_for_negative_reserved(item, current_inventory_snapshot.reserved, get_Warehouse(warehouse_id))
661
        return True
662
    except:
663
        print "Unexpected error:", sys.exc_info()[0]
664
        return False
665
 
12976 amit.gupta 666
#This is not the source as in snapdeal or website, this source is to incorporate different pricing depending upon source id.
22566 amit.gupta 667
#i.e. if user visiting to our site has specific source he would see pricing on that source basis. Default source is 1.
22719 amit.gupta 668
# Have to add another source id 2 for fofo warehouses
23442 amit.gupta 669
 
23446 amit.gupta 670
def get_item_availability_for_state(itemId, sourceId, stateId):
671
    __populateWarehouseMap()
23442 amit.gupta 672
    currentInventorySnapshots = get_item_inventory_by_item_id(itemId)
23446 amit.gupta 673
    totalAvailability = 0
674
    expectedDelay = 0
23442 amit.gupta 675
    if len(currentInventorySnapshots) > 0:
676
        for currentInventorySnapshot in currentInventorySnapshots:
23630 amit.gupta 677
            if currentInventorySnapshot.warehouse.state_id == stateId:
23446 amit.gupta 678
                availability = currentInventorySnapshot.availability - currentInventorySnapshot.reserved
679
                if availability > 0:
23482 amit.gupta 680
                    warehouse = currentInventorySnapshot.warehouse
23446 amit.gupta 681
                totalAvailability += availability 
682
    if totalAvailability <= 0:
23611 amit.gupta 683
        warehouse = virtualVendorWarehouses.get(stateId)
23446 amit.gupta 684
        expectedDelay = 2
25469 amit.gupta 685
    warehouseId = warehouse.id
23446 amit.gupta 686
    ia = get_item_availability_for_location(itemId, sourceId)
25469 amit.gupta 687
    return [warehouseId, expectedDelay, billingVendorWarehouses[stateId], ia[3], totalAvailability, ia[5]]
23442 amit.gupta 688
 
689
 
5978 rajveer 690
def get_item_availability_for_location(item_id, source_id):
691
    item_availability = ItemAvailabilityCache.get_by(itemId=item_id, sourceId = source_id)
5944 mandeep.dh 692
    if item_availability:
23839 amit.gupta 693
        print "Selling Price",  item_availability.sellingPrice
24741 amit.gupta 694
        if item_availability.sellingPrice is None:
695
            item_availability.sellingPrice = 100000
696
        print "[item_availability.warehouseId, item_availability.expectedDelay, item_availability.billingWarehouseId, item_availability.sellingPrice, item_availability.totalAvailability, item_availability.weight]"
697
        print item_availability.warehouseId, item_availability.expectedDelay, item_availability.billingWarehouseId, item_availability.sellingPrice, item_availability.totalAvailability, item_availability.weight
7589 rajveer 698
        return [item_availability.warehouseId, item_availability.expectedDelay, item_availability.billingWarehouseId, item_availability.sellingPrice, item_availability.totalAvailability, item_availability.weight]
20641 amit.gupta 699
        #return [item_availability.warehouseId, item_availability.expectedDelay, item_availability.billingWarehouseId, item_availability.sellingPrice, 0, item_availability.weight]
5944 mandeep.dh 700
    else:
5978 rajveer 701
        __update_item_availability_cache(item_id, source_id)
702
            ##Check risky status for the source
703
        __check_risky_item(item_id, source_id)
704
        return get_item_availability_for_location(item_id, source_id)
5944 mandeep.dh 705
 
19413 amit.gupta 706
def get_item_location_availability(item_id, locations=[]):
707
    if locations:
708
        newLocations = locations + [-1]
709
        itemisedItemLocationAvailability = ItemLocationAvailabilityCache.filter_by(itemId=item_id).filter(ItemLocationAvailability.locationId.in_(newLocations)).all()
710
    else:
711
        itemisedItemLocationAvailability = ItemLocationAvailabilityCache.filter_by(itemId=item_id).all()
712
    if not itemisedItemLocationAvailability:
713
        __update_item_location(item_id)
714
        return get_item_location_availability(item_id, locations)
715
    else:
716
        thriftList = []
717
        for itemLocationAvailability in itemisedItemLocationAvailability:
718
            if itemLocationAvailability.location_id == -1:
719
                itemisedItemLocationAvailability
720
            else:
721
                thriftList.append(to_t_item_location_availability(itemLocationAvailability))
722
        return thriftList
723
 
724
def __get_item_location_availability_bulk(item_ids, locations=[]):
725
 
726
    query = ItemLocationAvailabilityCache.query.filter(ItemLocationAvailabilityCache.item_id.in_(item_ids))
727
    allPopulated = query.filter(ItemLocationAvailabilityCache.location_id==-1).all()
728
    if len(item_ids) > len(allPopulated):
729
        for item_id in allPopulated:
730
            if item_id not in item_ids:
731
                __update_item_location(item_id)
732
    if locations:
733
        query.filter(ItemLocationAvailabilityCache.location_id.in_(locations)).all()
734
    return query.all()
735
 
736
 
737
def clear_item_location_availability_cache(item_id, locations=[]):
738
    if type(item_id)==list:
739
        ItemLocationAvailabilityCache.query.filter(ItemLocationAvailabilityCache.itemId.in_(item_id)).delete(synchronize_session='fetch')
740
        session.commit()
741
        t = threading.Thread(target=_task_update_item_availability_cache, args=(item_id,))
742
        t.start()
743
    elif item_id:
744
        ItemLocationAvailabilityCache.query.filter_by(itemId = item_id).delete()
745
    session.commit()
746
 
5978 rajveer 747
def clear_item_availability_cache(item_id = None):
13150 manish.sha 748
    print item_id
13149 manish.sha 749
    if type(item_id)==list:
13150 manish.sha 750
        ItemAvailabilityCache.query.filter(ItemAvailabilityCache.itemId.in_(item_id)).delete(synchronize_session='fetch')
13149 manish.sha 751
        session.commit()
13493 amit.gupta 752
        t = threading.Thread(target=_task_update_item_availability_cache, args=(item_id,))
753
        t.start()
754
 
13520 amit.gupta 755
    elif item_id:
5978 rajveer 756
        ItemAvailabilityCache.query.filter_by(itemId = item_id).delete()
12963 amit.gupta 757
        session.commit()
13493 amit.gupta 758
 
759
def _task_update_item_availability_cache(item_ids):
760
    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
761
    items = client.getItems(item_ids)
762
    for item_id in item_ids:
763
        item_availability = ItemAvailabilityCache.get_by(itemId=item_id, sourceId=1)
764
        if not item_availability:
765
            try:
17974 amit.gupta 766
                __update_item_availability_cache(item_id, 1, items[item_id])
767
                __check_risky_item(item_id, 1)
13493 amit.gupta 768
            except:
769
                print "Could not update cache for "
770
                continue
17990 kshitij.so 771
    return True   
5944 mandeep.dh 772
 
19413 amit.gupta 773
def __update_item_location(item_id):
774
    ignoredWhs = get_ignored_warehouses(item_id)
775
 
776
    itemsnapshot = CurrentInventorySnapshot.query.filter_by(item_id = item_id).all()
777
    locationsMap = {}
778
    for row in itemsnapshot:
779
        warehouse = warehouseMap[row.warehouse_id]
780
        if row.warehouse_id in ignoredWhs:
781
            continue 
782
 
783
        location = warehouse.logisticsLocation
784
        if not locationsMap.has_key(location):
785
            locationsMap[location] = {"physicalQty":0, "virtualQty":0,    "minTransferDelay":100, "maxTransferDelay":0}
786
        locationMap = locationsMap[location]
787
        if warehouse.type == 'THIRD_PARTY':
788
            locationMap["virtualQty"] += max(0, row.availability - row.reserverd - row.held)
789
            locationMap["minTransferDelay"] = min(locationMap["minTransferDelay"], row.transferDelayInHours/24)
790
            locationMap["maxTransferDelay"] = max(locationMap["maxTransferDelay"], row.transferDelayInHours/24)
791
        else:
792
            locationMap["physicalQty"] += max(0, row.availability - row.reserverd - row.held)
793
            locationMap["minTransferDelay"] = 0
794
    for location, locationMap in locationsMap.iteritems():
795
        if locationMap["virtualQty"] > 0 or locationMap["physicalQty"] > 0: 
796
            itemLocationAvailability = ItemLocationAvailabilityCache()
797
            itemLocationAvailability.item_id = item_id
798
            itemLocationAvailability.location_id = location
799
            itemLocationAvailability.max_transfer_delay = locationMap["maxTransferDelay"]
800
            itemLocationAvailability.min_transfer_delay = locationMap["minTransferDelay"]
801
            itemLocationAvailability.virtual_availability = locationMap["virtualQty"]
802
            itemLocationAvailability.physical_availability = locationMap["physicalQty"]
803
    #Add location -1 for each item
804
    itemLocationAvailability = ItemLocationAvailabilityCache()
805
    itemLocationAvailability.item_id = item_id
806
    itemLocationAvailability.location_id = -1
807
    session.commit()
808
 
809
 
810
 
811
 
812
 
12963 amit.gupta 813
def __update_item_availability_cache(item_id, source_id, item=None):
5944 mandeep.dh 814
    """
22719 amit.gupta 815
    Then how shoud we handle virtual because for both source virtual gonna mark
816
    """
817
    """
8954 vikram.rag 818
    Determines the warehouse that should be used to fulfil an order for the given item.
5944 mandeep.dh 819
    Algorithm explained at https://sites.google.com/a/shop2020.in/virtual-w-h-and-inventory/technical-details
820
 
821
    It will be ensured that every item has either a preferred vendor specified or at least for one vendor its transfer price should be defined.
822
    This is needed to associate an item with at least one vendor so that in default case when its available no where, we know from where to procure it.
823
 
824
    if item available at any OUR-GOOD warehouse
825
        // OUR-GOOD warehouses have inventory risk; So, we empty them first! 
826
        // We can start with minimum transfer price criterion but down the line we can also bring in Inventory age 
827
        assign OUR-GOOD warehouse with minimum transfer price
828
    else
829
        if Preferred vendor is specified and marked Sticky
830
            // Always purchase from Preferred if its marked sticky
831
            assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
832
        else 
833
            if item available in a THIRDPARTY GOOD/VIRTUAL warehouse
834
                assign THIRDPARTY GOOD/VIRTUAL warehouse where item is available with minimal transfer delay followed by minimum transfer price
835
            else 
836
                // Item not available at any warehouse, OURS or THIRDPARTY
837
                If Preferred vendor is specified
838
                    assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
839
                else
840
                    assign THIRDPARTY GOOD/VIRTUAL warehouse with minimum transfer price
841
 
842
    Returns an ordered list of size 4 with following elements in the given order:
843
    1. Logistics location of the warehouse which was finally picked up to ship the order.
844
    2. Expected delay added by the category manager.
845
    3. Id of the warehouse which was finally picked up.
846
 
847
    Parameters:
848
     - itemId
849
    """
12963 amit.gupta 850
    if item is None:
851
        item = __get_item_from_source(item_id, source_id)
5944 mandeep.dh 852
    item_pricing = {}
853
    for vendorItemPricing in VendorItemPricing.query.filter_by(item_id=item_id).all():
854
        item_pricing[vendorItemPricing.vendor_id] = vendorItemPricing
855
 
6510 rajveer 856
    ignoredWhs = get_ignored_warehouses(item_id)
857
 
5944 mandeep.dh 858
    warehouses = {}
859
    ourGoodWarehouses = {}
860
    thirdpartyWarehouses = {}
861
    preferredThirdpartyWarehouses = {}
862
    for warehouse in Warehouse.query.all():
7410 amar.kumar 863
        if (warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.BAD] or warehouse.warehouseType == WarehouseType._VALUES_TO_NAMES[WarehouseType.OURS_THIRDPARTY]):
5944 mandeep.dh 864
            continue
865
        warehouses[warehouse.id] = warehouse
866
        if warehouse.warehouseType == WarehouseType._VALUES_TO_NAMES[WarehouseType.OURS]:
867
            if warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
868
                ourGoodWarehouses[warehouse.id] = warehouse
869
        else:
870
            thirdpartyWarehouses[warehouse.id] = warehouse
871
            if item.preferredVendor == warehouse.vendor_id and warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
872
                preferredThirdpartyWarehouses[warehouse.id] = warehouse
873
 
874
    warehouse_retid = -1
875
    total_availability = 0
876
 
6540 rajveer 877
    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(ourGoodWarehouses, ignoredWhs, item_id, item_pricing, False)
5944 mandeep.dh 878
    if warehouse_retid == -1:
879
        if item.preferredVendor and item.isWarehousePreferenceSticky:
6540 rajveer 880
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(preferredThirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 881
            if warehouse_retid == -1:
882
                warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
883
        else:
6540 rajveer 884
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 885
            if warehouse_retid == -1:
886
                if item.preferredVendor:
887
                    warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
888
                else:
6540 rajveer 889
                    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing, True)
24741 amit.gupta 890
    print "I am able to reach here wih warehouse_retid", warehouse_retid
5944 mandeep.dh 891
    warehouse = warehouses[warehouse_retid]
892
    billingWarehouseId = warehouse.billingWarehouseId
893
 
894
    # Fetching billing warehouse of a Good billable warehouse corresponding to the virtual one
895
    if not warehouse.billingWarehouseId:
21152 amit.gupta 896
        for w in Warehouse.query.filter_by(vendor_id = warehouse.vendor_id, inventoryType = InventoryType._VALUES_TO_NAMES[InventoryType.GOOD], state_id=warehouse.state_id).all():
5944 mandeep.dh 897
            if w.billingWarehouseId:
898
                billingWarehouseId = w.billingWarehouseId
899
                break
900
 
901
    expectedDelay = item.expectedDelay 
902
    if expectedDelay is None:
903
        print 'expectedDelay field for this item was Null. Resetting it to 0'
904
        expectedDelay = 0
905
    else:
906
        expectedDelay = int(item.expectedDelay)
907
 
908
    if total_availability <= 0:
8026 amar.kumar 909
        if item.preferredVendor in [1, 5]:
6562 rajveer 910
            expectedDelay = expectedDelay + 3
911
        else:
912
            expectedDelay = expectedDelay + 2
6643 rajveer 913
    else:
914
        if warehouse.transferDelayInHours:
915
            expectedDelay = expectedDelay + warehouse.transferDelayInHours / 24
5944 mandeep.dh 916
 
18022 manish.sha 917
    if WarehouseType._NAMES_TO_VALUES[warehouse.warehouseType] == WarehouseType.THIRD_PARTY:
8491 rajveer 918
        expectedDelay = expectedDelay + __get_vendor_holiday_delay(warehouse.vendor_id, expectedDelay) 
919
 
5963 mandeep.dh 920
    total_availability = 0
16029 amit.gupta 921
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
6545 rajveer 922
        if entry.warehouse_id not in ignoredWhs:
16029 amit.gupta 923
            if entry.warehouse_id not in ourGoodWarehouses and entry.warehouse_id not in thirdpartyWarehouses:
16015 amit.gupta 924
                continue
925
            if entry.warehouse_id in ourGoodWarehouses and ourGoodWarehouses[entry.warehouse_id].billingWarehouseId == billingWarehouseId:
926
                total_availability += entry.availability - entry.reserved - entry.held
927
            elif entry.warehouse_id in thirdpartyWarehouses:
928
                vendorId = thirdpartyWarehouses[entry.warehouse_id].vendor_id
929
                for goodWarehouse in ourGoodWarehouses.values():
21152 amit.gupta 930
                    if goodWarehouse.vendor_id==vendorId and goodWarehouse.billingWarehouseId == billingWarehouseId and warehouse.state_id==goodWarehouse.state_id:
16015 amit.gupta 931
                        total_availability += entry.availability - entry.reserved - entry.held
932
                        break
5963 mandeep.dh 933
 
5978 rajveer 934
    item_availability_cache = ItemAvailabilityCache.get_by(itemId=item_id, sourceId=source_id)
5944 mandeep.dh 935
    if item_availability_cache is None:
936
        item_availability_cache = ItemAvailabilityCache()
937
        item_availability_cache.itemId = item_id
5978 rajveer 938
        item_availability_cache.sourceId = source_id
5944 mandeep.dh 939
    item_availability_cache.warehouseId = int(warehouse_retid)
940
    item_availability_cache.expectedDelay = expectedDelay
941
    item_availability_cache.billingWarehouseId = billingWarehouseId
942
    item_availability_cache.sellingPrice = item.sellingPrice
943
    item_availability_cache.totalAvailability = total_availability
16029 amit.gupta 944
    #item_availability_cache.location = warehouse.logisticsLocation 
7589 rajveer 945
    item_availability_cache.weight = 1000*item.weight if item.weight else 300
5944 mandeep.dh 946
    session.commit()
947
 
6540 rajveer 948
def __get_warehouse_with_min_transfer_price(warehouses, ignoredWhs, item_id, item_pricing, ignoreAvailability):
5944 mandeep.dh 949
    warehouse_retid = -1
950
    minTransferPrice = None
951
    total_availability = 0
6013 amar.kumar 952
    availabilityForBillingWarehouses = {}
953
    warehousesAvailability = {}
954
    availability = 0
955
    billing_warehouse_retid = None
5944 mandeep.dh 956
 
957
    if not ignoreAvailability:
958
        for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 959
            entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 960
            entry.held = max(entry.held, 0)
6013 amar.kumar 961
            #if entry.availability > entry.reserved:
8182 amar.kumar 962
            warehousesAvailability[entry.warehouse_id] = [entry.availability, entry.reserved, entry.held] 
5944 mandeep.dh 963
 
6540 rajveer 964
    if len(ignoredWhs) > 0:
965
        for whid in ignoredWhs:
966
            if warehousesAvailability.has_key(whid):
6542 rajveer 967
                warehousesAvailability[whid][0] = 0
6683 rajveer 968
                warehousesAvailability[whid][1] = 0
8182 amar.kumar 969
                warehousesAvailability[whid][2] = 0
6540 rajveer 970
 
5944 mandeep.dh 971
    for warehouse in warehouses.values():
972
        if not ignoreAvailability:
6013 amar.kumar 973
            #TODO Mistake no entry for this warehouse.id in warehouseswithAvailab
974
            if warehouse.id not in warehousesAvailability:
975
                continue
976
            entry = warehousesAvailability[warehouse.id]
977
            if warehouse.billingWarehouseId in availabilityForBillingWarehouses:
978
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
8182 amar.kumar 979
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = availabilityForBillingWarehouses[warehouse.billingWarehouseId] + entry[0] - entry[1] - entry[2]  
5944 mandeep.dh 980
            else:
6013 amar.kumar 981
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
8182 amar.kumar 982
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = entry[0] - entry[1] - entry[2]
983
            if entry[0] <= (entry[1] + entry[2]):
5944 mandeep.dh 984
                continue
8182 amar.kumar 985
            total_availability += entry[0] - entry[1] - entry[2]
5944 mandeep.dh 986
 
987
        # Missing transfer price cases should not impact warehouse assignment
988
        transferPrice = None
989
        if item_pricing.has_key(warehouse.vendor_id):
6778 rajveer 990
            transferPrice = item_pricing[warehouse.vendor_id].nlc
5944 mandeep.dh 991
        if minTransferPrice is None or (transferPrice and minTransferPrice > transferPrice):
992
            warehouse_retid = warehouse.id
6013 amar.kumar 993
            billing_warehouse_retid = warehouse.billingWarehouseId
5944 mandeep.dh 994
            minTransferPrice = transferPrice
6013 amar.kumar 995
 
996
 
997
    if billing_warehouse_retid in availabilityForBillingWarehouses: 
998
        availability = availabilityForBillingWarehouses[billing_warehouse_retid]
999
    else:
1000
        availability = total_availability
1001
 
24741 amit.gupta 1002
    print "[warehouse_retid, availability]", warehouse_retid, availability
6013 amar.kumar 1003
    return [warehouse_retid, availability]
5944 mandeep.dh 1004
 
6540 rajveer 1005
def __get_warehouse_with_min_transfer_delay(warehouses, ignoredWhs, item_id, item_pricing):
5944 mandeep.dh 1006
    minTransferDelay = None
1007
    minTransferDelayWarehouses = {}
1008
    total_availability = 0
1009
 
1010
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 1011
        entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 1012
        entry.held = max(entry.held, 0)
5944 mandeep.dh 1013
        if warehouses.has_key(entry.warehouse_id):
1014
            warehouse = warehouses[entry.warehouse_id]
6013 amar.kumar 1015
            #if entry.availability > entry.reserved:
6683 rajveer 1016
            if entry.warehouse_id not in ignoredWhs:
8182 amar.kumar 1017
                total_availability += entry.availability - entry.reserved - entry.held
1018
            if entry.availability - entry.reserved - entry.held <= 0:
6780 amar.kumar 1019
                continue
6013 amar.kumar 1020
            transferDelay = warehouse.transferDelayInHours
1021
            if minTransferDelay is None or minTransferDelay >= transferDelay:
1022
                if minTransferDelay != transferDelay:
1023
                    minTransferDelayWarehouses = {}
1024
                minTransferDelayWarehouses[warehouse.id] = warehouse
1025
                minTransferDelay = transferDelay
5944 mandeep.dh 1026
 
6540 rajveer 1027
    return [__get_warehouse_with_min_transfer_price(minTransferDelayWarehouses, ignoredWhs, item_id, item_pricing, False)[0], total_availability]
5944 mandeep.dh 1028
 
1029
def __get_warehouse_with_max_availability(warehouse_ids, item_id):
1030
    warehouse_retid = -1
1031
    max_availability = 0
1032
    total_availability = 0
1033
 
1034
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 1035
        entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 1036
        entry.held = max(entry.held, 0)
5944 mandeep.dh 1037
        if entry.warehouse_id in warehouse_ids:
1038
            availability = entry.availability - entry.reserved
1039
            if availability > max_availability:
1040
                warehouse_retid = entry.warehouse_id
1041
                max_availability = availability
1042
            total_availability += availability
1043
 
1044
    return [warehouse_retid, total_availability]
1045
 
8491 rajveer 1046
def __get_vendor_holiday_delay(vendor_id, expectedDelay):
1047
    ## If vendor is closed two days continuously
5944 mandeep.dh 1048
    holidayDelay = 0
8491 rajveer 1049
    currentDate = datetime.date.today()
1050
    expectedDate = currentDate + datetime.timedelta(days = expectedDelay)
1051
    holidays = VendorHolidays.query.filter(VendorHolidays.vendor_id == vendor_id).filter(VendorHolidays.date.between(currentDate, expectedDate)).all()
1052
    if holidays:
1053
        holidayDelay = holidayDelay + len(holidays)
5944 mandeep.dh 1054
    return holidayDelay 
1055
 
1056
def get_item_pricing(item_id, vendorId):
1057
    '''
1058
    if vendor id is -1 then we calculate an average transfer price to be populated
1059
    at the time of order creation. This will be later updated with actual transfer price
1060
    at the time of billing.
1061
    '''
1062
    if(vendorId == -1):
6778 rajveer 1063
        tp_total = 0
1064
        nlc_total = 0
5944 mandeep.dh 1065
        try:
1066
            item_pricings = []
1067
            item = __get_item_from_master(item_id)
1068
            if item.preferredVendor is not None:
1069
                item_pricing = VendorItemPricing.query.filter_by(item_id=item_id, vendor_id=item.preferredVendor).first()
1070
                if item_pricing:
1071
                    item_pricings.append(item_pricing)                    
1072
            else :
1073
                item_pricings = VendorItemPricing.query.filter_by(item_id=item_id).all()
1074
            if item_pricings:
1075
                for item_pricing in item_pricings:
6778 rajveer 1076
                    tp_total += item_pricing.transfer_price
1077
                    nlc_total += item_pricing.nlc
1078
                tp_avg = tp_total / len(item_pricings)
1079
                nlc_avg = nlc_total / len(item_pricings)
1080
                item_pricing.transfer_price = tp_avg
1081
                item_pricing.nlc = nlc_avg
5944 mandeep.dh 1082
            else:
1083
                item_pricing = VendorItemPricing()
1084
                item_pricing.transfer_price = item.sellingPrice
6778 rajveer 1085
                item_pricing.nlc = item.sellingPrice
5944 mandeep.dh 1086
                vendor = Vendor()
1087
                vendor.id = vendorId
1088
                item_pricing.vendor = vendor
1089
                item_pricing.item_id = item_id
1090
 
1091
            return item_pricing
1092
        except:
1093
            raise InventoryServiceException(101, "Item pricing not found ")
1094
    vendor = Vendor.get_by(id=vendorId)    
1095
    try:
1096
        item_pricing = VendorItemPricing.query.filter_by(vendor=vendor, item_id=item_id).one()
1097
        return item_pricing
1098
    except MultipleResultsFound:
1099
        raise InventoryServiceException(110, "Multiple pricing information present for Vendor: " + vendor.name + " and Item: " + str(item_id))
1100
    except NoResultFound:
1101
        raise InventoryServiceException(111, "Missing pricing information for Vendor: " + vendor.name + " and Item: " + str(item_id))
1102
 
1103
def get_all_item_pricing(item_id):
1104
    item_pricing = VendorItemPricing.query.filter_by(item_id=item_id).all()
1105
    return item_pricing
10126 amar.kumar 1106
def get_all_vendor_item_pricing(item_id, vendor_id):
1107
    query = VendorItemPricing.query
1108
    if item_id:
1109
        query = query.filter_by(item_id = item_id)
1110
    if item_id:
1111
        query = query.filter_by(vendor_id = vendor_id)
1112
    item_pricing = query.all()
1113
    return item_pricing
1114
 
5944 mandeep.dh 1115
def get_item_mappings(item_id):
1116
    item_mappings = VendorItemMapping.query.filter_by(item_id=item_id).all()
1117
    return item_mappings
1118
 
19247 kshitij.so 1119
def add_vendor_pricing(vendorItemPricing, sendMail = True):
5944 mandeep.dh 1120
    if not vendorItemPricing:
1121
        raise InventoryServiceException(108, "Bad vendorItemPricing in request")
1122
    vendorId = vendorItemPricing.vendorId
1123
    itemId = vendorItemPricing.itemId
1124
 
1125
    try:
1126
        vendor = Vendor.query.filter_by(id=vendorId).one()
1127
    except:
1128
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
1129
 
1130
    try:
1131
        item = __get_item_from_master(itemId)
1132
    except:
1133
        raise InventoryServiceException(101, "Item not found for itemId " + str(itemId))
1134
 
1135
    validate_vendor_prices(item, vendorItemPricing)
1136
 
1137
    try:
1138
        ds_vendorItemPricing = VendorItemPricing.query.filter(and_(VendorItemPricing.vendor==vendor, VendorItemPricing.item_id==itemId)).one()
1139
    except:
1140
        ds_vendorItemPricing = VendorItemPricing()
1141
        ds_vendorItemPricing.vendor = vendor
1142
        ds_vendorItemPricing.item_id = itemId
1143
 
1144
    subject = ""
1145
    message = ""
1146
    if vendorItemPricing.mop:
1147
        ds_vendorItemPricing.mop = vendorItemPricing.mop
1148
    if vendorItemPricing.dealerPrice:
1149
        ds_vendorItemPricing.dealerPrice = vendorItemPricing.dealerPrice
1150
    if vendorItemPricing.transferPrice:
26911 amit.gupta 1151
        #if vendorItemPricing.transferPrice != ds_vendorItemPricing.transfer_price:
1152
        #    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1153
        #    item = client.getItem(itemId)
1154
        #    message = "Transfer price for Item {0} {1} {2} {3} \nand Vendor:{4} is changed from {5} to {6}.".format(item.brand, item.modelName, item.modelNumber, item.color, vendor.name, ds_vendorItemPricing.transfer_price, vendorItemPricing.transferPrice)
1155
        #    subject = "Alert:Change in Transfer Price {0} {1} {2} {3} {4}".format(item.brand, item.modelName, item.modelNumber, item.color, itemId)
5944 mandeep.dh 1156
        ds_vendorItemPricing.transfer_price = vendorItemPricing.transferPrice
6751 amar.kumar 1157
    if vendorItemPricing.nlc:
26911 amit.gupta 1158
        #if vendorItemPricing.nlc != ds_vendorItemPricing.nlc:
1159
        #    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1160
        #    item = client.getItem(itemId)
1161
        #    message = message + "\nNLC for Item {0} {1} {2} {3} \nand Vendor:{4} is changed from {5} to {6}.".format(item.brand, item.modelName, item.modelNumber, item.color, vendor.name, ds_vendorItemPricing.nlc, vendorItemPricing.nlc)
1162
        #    subject = "Alert:Change in NLC {0} {1} {2} {3} {4}".format(item.brand, item.modelName, item.modelNumber, item.color, itemId)
6751 amar.kumar 1163
        ds_vendorItemPricing.nlc = vendorItemPricing.nlc
9895 vikram.rag 1164
    session.commit()    
26911 amit.gupta 1165
    #client = CatalogClient("catalog_service_server_host_staging", "catalog_service_server_port").get_client()
1166
    #client.updateNlcAtMarketplaces(itemId,vendorId,ds_vendorItemPricing.nlc)
1167
    #if subject and sendMail:
1168
    #    __send_mail(subject, message)
5944 mandeep.dh 1169
    return
1170
 
1171
def add_vendor_item_mapping(key, vendorItemMapping):
1172
    if not vendorItemMapping:
1173
        raise InventoryServiceException(108, "Bad vendorItemMapping in request")
1174
    vendorId = vendorItemMapping.vendorId
1175
    itemId = vendorItemMapping.itemId
1176
 
1177
    try:
1178
        vendor = Vendor.query.filter_by(id=vendorId).one()
1179
    except:
1180
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
1181
 
1182
    try:
1183
        ds_vendorItemMapping = VendorItemMapping.query.filter(and_(VendorItemMapping.vendor==vendor, VendorItemMapping.item_id==itemId, VendorItemMapping.item_key==key)).one()
1184
    except:
1185
        ds_vendorItemMapping = VendorItemMapping()
1186
        ds_vendorItemMapping.vendor = vendor
1187
        ds_vendorItemMapping.item_id = itemId
1188
    ds_vendorItemMapping.item_key = vendorItemMapping.itemKey
1189
 
1190
    session.commit()
1191
 
1192
    # Marking the missed inventory as not ignored as the catalog dashboard user has updated their key
1193
    for missedInventoryUpdate in MissedInventoryUpdate.query.filter_by(itemKey = vendorItemMapping.itemKey).all():
1194
        missedInventoryUpdate.isIgnored = 0
1195
    session.commit()
1196
 
1197
    return
1198
 
1199
def validate_vendor_prices(item, vendorPrices):
1200
    if item.mrp != None and item.mrp != "" and vendorPrices.mop != "" and item.mrp <  vendorPrices.mop:
1201
        print "[BAD MRP and MOP:] for {0} {1} {2} {3}. MRP={4}. MOP={5}, Vendor={6}".format(item.productGroup, item.brand, item.modelNumber, item.color, str(item.mrp), str(vendorPrices.mop), str(vendorPrices.vendorId))
1202
        raise InventoryServiceException(101, "[BAD MRP and MOP:] for {0} {1} {2} {3}. MRP={4}. MOP={5}, Vendor={6}".format(item.productGroup, item.brand, item.modelNumber, item.color, str(item.mrp), str(vendorPrices.mop), str(vendorPrices.vendorId)))
18460 kshitij.so 1203
    return
18459 kshitij.so 1204
    #if vendorPrices.mop != "" and vendorPrices.transferPrice != "" and vendorPrices.transferPrice > vendorPrices.mop:
18460 kshitij.so 1205
#         print "[BAD MOP and TP:] for {0} {1} {2} {3}. TP={4}. MOP={5}, Vendor={6}".format(item.productGroup, item.brand, item.modelNumber, item.color, str(vendorPrices.transferPrice), str(vendorPrices.mop), str(vendorPrices.vendorId))
1206
#         raise InventoryServiceException(101, "[BAD MOP and TP:] for {0} {1} {2} {3}. TP={4}. MOP={5}, Vendor={6}".format(item.productGroup, item.brand, item.modelNumber, item.color, str(vendorPrices.transferPrice), str(vendorPrices.mop), str(vendorPrices.vendorId)))
1207
    #return 
5944 mandeep.dh 1208
 
1209
def get_all_vendors():
1210
    return Vendor.query.all()
1211
 
1212
def get_pending_orders_inventory(vendor_id=1):
1213
    """
1214
    Returns a list of inventory stock for items for which there are pending orders.
1215
    """
1216
 
1217
    warehouse_ids = [warehouse.id for warehouse in Warehouse.query.filter_by(vendor_id = vendor_id)]
1218
    pending_items_inventory = []
1219
    if warehouse_ids:
1220
        pending_items_inventory = session.query(CurrentInventorySnapshot.item_id, func.sum(CurrentInventorySnapshot.availability), func.sum(CurrentInventorySnapshot.reserved)).filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).group_by(CurrentInventorySnapshot.item_id).having(func.sum(CurrentInventorySnapshot.reserved) > 0).all()
1221
    return pending_items_inventory
1222
 
7149 amar.kumar 1223
def get_billable_inventory_and_pending_orders():
1224
    """
1225
    Returns a list of inventory Availability and Reserved Count for items which either have real inventory
1226
    or have pending orders.
1227
    """
1228
 
1229
    warehouse_ids = [warehouse.id for warehouse in Warehouse.query.filter(Warehouse.isAvailabilityMonitored == 1).filter(or_(Warehouse.inventoryType == 'GOOD', Warehouse.warehouseType == 'OURS'))]
1230
    items_inventory = []
1231
    reserved_items_inventory = []
1232
    available_items_inventory = []
1233
    if warehouse_ids:
1234
        reserved_items_inventory = session.query(CurrentInventorySnapshot.item_id, func.sum(CurrentInventorySnapshot.availability), func.sum(CurrentInventorySnapshot.reserved)).filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).group_by(CurrentInventorySnapshot.item_id).having(func.sum(CurrentInventorySnapshot.reserved) > 0).all()
1235
        available_items_inventory = session.query(CurrentInventorySnapshot.item_id, func.sum(CurrentInventorySnapshot.availability), func.sum(CurrentInventorySnapshot.reserved)).filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).group_by(CurrentInventorySnapshot.item_id).having(func.sum(CurrentInventorySnapshot.availability) > 0).all()
1236
 
1237
    items_inventory.extend(reserved_items_inventory)
1238
    items_inventory.extend(available_items_inventory)
1239
    return items_inventory
1240
 
1241
 
5944 mandeep.dh 1242
def close_session():
1243
    if session.is_active:
1244
        print "session is active. closing it."
1245
        session.close()
1246
 
1247
def is_alive():
1248
    try:
1249
        session.query(Vendor.id).limit(1).one()
1250
        return True
1251
    except:
1252
        return False
1253
 
1254
def add_vendor(vendor):
1255
    if not vendor:
1256
        raise InventoryServiceException(108, "Bad vendor")
1257
    if get_vendor(vendor.id):
1258
        #vendor is already present.
1259
        raise InventoryServiceException(101, "Vendor already present")
1260
 
1261
    ds_vendor = Vendor()
1262
    ds_vendor.id = vendor.id
1263
    ds_vendor.name = vendor.name
1264
    session.commit()
1265
    return ds_vendor.id
1266
 
1267
def add_warehouse_vendor_mapping(warehouse_id, VendorId):
1268
    return True
1269
 
1270
def mark_missed_inventory_updates_as_processed(itemKey, warehouseId):
1271
    MissedInventoryUpdate.query.filter_by(itemKey = itemKey, warehouseId = warehouseId).delete()
1272
    session.commit()
1273
 
1274
def get_item_keys_to_be_processed(warehouseId):
1275
    return [i.itemKey for i in MissedInventoryUpdate.query.filter_by(warehouseId = warehouseId, isIgnored = 0)]
1276
 
1277
def reset_availability(itemKey, vendorId, quantity, warehouseId):
1278
    vendorItemMapping = VendorItemMapping.get_by(vendor_id = vendorId, item_key = itemKey)
1279
    if vendorItemMapping:
1280
        itemId = vendorItemMapping.item_id
1281
 
1282
        if skippedItems.has_key(warehouseId) and itemId in skippedItems[warehouseId]:
1283
            quantity = 0
1284
 
1285
        currentInventorySnapshot = CurrentInventorySnapshot.get_by(item_id = itemId, warehouse_id = warehouseId)
1286
        if currentInventorySnapshot:
1287
            currentInventorySnapshot.availability = quantity
5978 rajveer 1288
            clear_item_availability_cache(itemId) 
5944 mandeep.dh 1289
        else:
1290
            add_inventory(itemId, warehouseId, quantity)
1291
 
1292
    else:
1293
        raise InventoryServiceException(101, 'VendorMapping not found for: ' + itemKey)
1294
    session.commit()
1295
 
1296
def reset_availability_for_warehouse(warehouseId):
13149 manish.sha 1297
    itemIds = []
5944 mandeep.dh 1298
    for currentInventorySnapshot in CurrentInventorySnapshot.query.filter_by(warehouse_id=warehouseId).all():
1299
        currentInventorySnapshot.availability = 0
13149 manish.sha 1300
        itemIds.append(currentInventorySnapshot.item_id)
1301
    clear_item_availability_cache(itemIds) 
5944 mandeep.dh 1302
    session.commit()
1303
 
7718 amar.kumar 1304
def get_our_warehouse_id_for_vendor(vendor_id, billing_warehouse_id):
6467 amar.kumar 1305
    try:
7718 amar.kumar 1306
        warehouse = Warehouse.query.filter_by(vendor_id = vendor_id, warehouseType = 'OURS', inventoryType = 'GOOD', billingWarehouseId = billing_warehouse_id).first()
6467 amar.kumar 1307
        return warehouse.id
1308
    except Exception as e:
1309
        print e;
7755 amar.kumar 1310
        raise InventoryServiceException(101, 'No our warehouse found for vendorId: ' + str(vendor_id))
5944 mandeep.dh 1311
 
1312
def __send_mail(subject, message):
1313
    try:
6029 rajveer 1314
        thread = threading.Thread(target=partial(mail, mail_user, mail_password, to_addresses, subject, message))
5944 mandeep.dh 1315
        thread.start()
1316
    except Exception as ex:
1317
        print ex    
1318
 
1319
def get_shipping_locations():
1320
    shippingLocationIds = {}
1321
    warehouses = Warehouse.query.all()
1322
    for warehouse in warehouses:
1323
        if warehouse.shippingWarehouseId:
1324
            shippingLocationIds[warehouse.shippingWarehouseId] = 1
1325
 
1326
    shippingLocations = []
1327
    for shippingLocationId in shippingLocationIds:
1328
        shippingLocations.append(get_Warehouse(shippingLocationId))
1329
 
1330
    return shippingLocations
1331
 
1332
def get_inventory_snapshot(warehouseId):
1333
    query = CurrentInventorySnapshot.query
1334
 
1335
    if warehouseId:
1336
        query = query.filter_by(warehouse_id = warehouseId)
1337
 
1338
    itemInventoryMap = {}
1339
    for row in query.all():
1340
        if not itemInventoryMap.has_key(row.item_id):
1341
            itemInventoryMap[row.item_id] = []
1342
 
1343
        itemInventoryMap[row.item_id].append(row)
1344
 
1345
    return itemInventoryMap
1346
 
1347
def update_vendor_string(warehouseId, vendorString):
1348
    warehouse = get_Warehouse(warehouseId)
1349
    warehouse.vendorString = vendorString
1350
    session.commit()
1351
 
1352
def __get_item_from_master(item_id):
1353
    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
5978 rajveer 1354
    return client.getItem(item_id)
1355
 
1356
def __check_risky_item(item_id, source_id):
1357
    ## We should get the list of strings which will identify to the catalog servers
1358
    if source_id == 1:
1359
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1360
        client.validateRiskyStatus(item_id)
1361
    if source_id == 2:
1362
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
1363
        client.validateRiskyStatus(item_id)
1364
 
1365
def __get_item_from_source(item_id, source_id):
1366
    if source_id == 1:
1367
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1368
        return client.getItem(item_id)
1369
    if source_id == 2:
1370
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
6531 vikram.rag 1371
        return client.getItem(item_id)
1372
 
1373
def get_monitored_warehouses_for_vendors(vendorIds):
1374
    w = []
1375
    for wh in Warehouse.query.filter_by(isAvailabilityMonitored = 1).all():
1376
        if wh.vendor.id in (vendorIds):
1377
            w.append(to_t_warehouse(wh).id)
1378
    return w
1379
def get_ignored_warehouseids_and_itemids():
1380
    iw = []
1381
    for i in IgnoredInventoryUpdateItems.query.all():
1382
        iw.append(to_t_itemidwarehouseid(i)) 
1383
    return iw
1384
def insert_item_to_ignore_inventory_update_list(item_id,warehouse_id):
1385
    try:
1386
        ds_warehouse=IgnoredInventoryUpdateItems()
1387
        ds_warehouse.item_id=item_id
1388
        ds_warehouse.warehouse_id=warehouse_id
6532 amit.gupta 1389
        clear_item_availability_cache(item_id)
6531 vikram.rag 1390
        session.commit()
1391
        return True
1392
    except:
1393
        return False       
1394
def delete_item_from_ignore_inventory_update_list(item_id,warehouse_id):
1395
    try:
1396
        session.query(IgnoredInventoryUpdateItems).filter_by(item_id=item_id,warehouse_id=warehouse_id).delete()
6532 amit.gupta 1397
        clear_item_availability_cache(item_id)
6531 vikram.rag 1398
        session.commit()
1399
        return True
1400
    except:
1401
        return False           
1402
 
1403
def get_all_ignored_inventoryupdate_items_count():
1404
    return  session.query(func.count(distinct(IgnoredInventoryUpdateItems.item_id))).scalar()
1405
 
1406
def get_ignored_inventoryupdate_itemids(offset=0,limit=None):
1407
    itemIds = session.query(distinct(IgnoredInventoryUpdateItems.item_id))
1408
    '''if limit is not None:
1409
        itemIds = itemIds.limit(limit)'''
1410
    print itemIds.all()
1411
    return [id for (id, ) in itemIds.all()]
6821 amar.kumar 1412
 
1413
def update_item_stock_purchase_params(item_id, numOfDaysStock, minStockLevel):
1414
    if numOfDaysStock is None or minStockLevel is None:
1415
        raise InventoryServiceException(108, "Bad params : numOfDaysStock = " + str(numOfDaysStock) + "minStockLevel = " + str(minStockLevel))
1416
    itemStockPurchaseParams = ItemStockPurchaseParams.query.filter_by(item_id = item_id).first()
1417
    if itemStockPurchaseParams is None:
1418
        itemStockPurchaseParams = ItemStockPurchaseParams()
1419
    itemStockPurchaseParams.item_id = item_id
1420
    itemStockPurchaseParams.numOfDaysStock = numOfDaysStock
1421
    itemStockPurchaseParams.minStockLevel = minStockLevel
1422
    session.commit()
1423
 
1424
def get_item_stock_purchase_params(item_id):
1425
    return ItemStockPurchaseParams.query.filter_by(item_id = item_id).first()
1426
 
1427
def add_oos_status_for_item(oosStatusMap, date):
1428
 
1429
    oosDate = to_py_date(date)
1430
    oosDate.replace(second=0, microsecond=0)
1431
 
1432
    cartAdditionStartDate = oosDate - datetime.timedelta(days = 1)
1433
 
1434
    client = TransactionClient().get_client()
1435
 
1436
    #Gets physical orders in the last day
1437
    orders = client.getPhysicalOrders(to_java_date(cartAdditionStartDate), to_java_date(oosDate))
8019 amar.kumar 1438
    rtoOrders = client.getAllOrders([20], 0, 0, 0)
9665 rajveer 1439
    orderCountByItemIdSourceId = {}
1440
    rtoOrderCountByItemIdSourceId = {}
1441
 
6821 amar.kumar 1442
    for order in orders:
9665 rajveer 1443
        if not orderCountByItemIdSourceId.has_key(order.lineitems[0].item_id):
1444
            orderCountByItemIdSourceId[order.lineitems[0].item_id] = {}
1445
 
1446
        if orderCountByItemIdSourceId[order.lineitems[0].item_id].has_key(order.source):
18430 manish.sha 1447
            orderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = orderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] + order.lineitems[0].quantity
6821 amar.kumar 1448
        else:
18430 manish.sha 1449
            orderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = order.lineitems[0].quantity
9665 rajveer 1450
 
8019 amar.kumar 1451
 
1452
    for order in rtoOrders:
9665 rajveer 1453
        if not rtoOrderCountByItemIdSourceId.has_key(order.lineitems[0].item_id):
1454
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id] = {}
1455
 
1456
        if rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id].has_key(order.source):
18430 manish.sha 1457
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] + order.lineitems[0].quantity 
8019 amar.kumar 1458
        else:
18430 manish.sha 1459
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = order.lineitems[0].quantity
9665 rajveer 1460
 
1461
 
6821 amar.kumar 1462
    for itemId, status in oosStatusMap.iteritems():
9665 rajveer 1463
        total_order_count = 0 
9791 rajveer 1464
        total_rto_count = 0
13726 manish.sha 1465
        for sid in (1,3,4,6,7,8):
6821 amar.kumar 1466
            oosStatus = OOSStatus()
1467
            oosStatus.item_id = itemId
1468
            oosStatus.date = oosDate
9791 rajveer 1469
            oosStatus.sourceId  = sid
1470
            order_count = 0
1471
            rto_count = 0
1472
            if orderCountByItemIdSourceId.has_key(itemId) and orderCountByItemIdSourceId[itemId].has_key(sid):
1473
                order_count = orderCountByItemIdSourceId[itemId][sid]
1474
            if rtoOrderCountByItemIdSourceId.has_key(itemId) and rtoOrderCountByItemIdSourceId[itemId].has_key(sid):
18430 manish.sha 1475
                rto_count = rtoOrderCountByItemIdSourceId[itemId][sid]
9791 rajveer 1476
            oosStatus.num_orders = order_count
1477
            oosStatus.rto_orders = rto_count
9666 rajveer 1478
            oosStatus.is_oos = status
9791 rajveer 1479
            if oosStatus.is_oos and order_count > 0:
1480
                oosStatus.is_oos = False
1481
            total_order_count = total_order_count + order_count
1482
            total_rto_count = total_rto_count + rto_count
1483
        oosStatus = OOSStatus()
1484
        oosStatus.item_id = itemId
1485
        oosStatus.date = oosDate
1486
        oosStatus.sourceId  = 0
1487
        oosStatus.num_orders = total_order_count
1488
        oosStatus.rto_orders = total_rto_count
9804 rajveer 1489
        if itemId in orderCountByItemIdSourceId and 1 in orderCountByItemIdSourceId[itemId]:
1490
            order_count = orderCountByItemIdSourceId[itemId][1]
9791 rajveer 1491
        oosStatus.is_oos = status
1492
        if oosStatus.is_oos and order_count > 0:
1493
            oosStatus.is_oos = False
6821 amar.kumar 1494
 
9791 rajveer 1495
        session.commit()
1496
 
9861 rajveer 1497
 
1498
    itemCountMap = {}
1499
    oosDate = oosDate - datetime.timedelta(days = 1) - datetime.timedelta(hours = 1)
1500
    lines = session.query(OOSStatus.item_id, func.sum(OOSStatus.num_orders)/func.count(OOSStatus.num_orders)).filter(OOSStatus.date >= oosDate).filter(OOSStatus.sourceId == 1).filter(OOSStatus.is_oos == 0).group_by(OOSStatus.item_id).all()
1501
    for line in lines:
1502
        item_id = line[0]
9896 rajveer 1503
        quantity = int(math.ceil(max(1,2*line[1])))
9861 rajveer 1504
        itemCountMap[item_id] = quantity
9862 rajveer 1505
    cl = CatalogClient('catalog_service_server_host_prod','catalog_service_server_port').get_client()
9861 rajveer 1506
    cl.updateItemHoldInventory(itemCountMap)
9791 rajveer 1507
 
9665 rajveer 1508
def get_oos_statuses_for_x_days_for_item(itemId, sourceId, days):
6832 amar.kumar 1509
    timestamp = datetime.datetime.now()
9640 amar.kumar 1510
    timestamp = timestamp - datetime.timedelta(days = days)
9665 rajveer 1511
    return OOSStatus.query.filter_by(item_id = itemId).filter_by(sourceId = sourceId).filter(OOSStatus.date > timestamp).all()
6857 amar.kumar 1512
 
10126 amar.kumar 1513
def get_oos_statuses_for_x_days(sourceId, days):
1514
    timestamp = datetime.datetime.now()
1515
    timestamp = timestamp - datetime.timedelta(days = days)
1516
    if sourceId == -1:
1517
        return OOSStatus.query.filter(OOSStatus.date > timestamp).all()
1518
    else:
1519
        return OOSStatus.query.filter_by(sourceId = sourceId).filter(OOSStatus.date > timestamp).all()
1520
 
6857 amar.kumar 1521
def get_non_zero_item_stock_purchase_params():
7281 kshitij.so 1522
    return ItemStockPurchaseParams.query.filter(or_("numOfDaysStock!=0","minStockLevel!=0"))
1523
 
7972 amar.kumar 1524
def get_last_n_day_sale_for_item(itemId, numberOfDays):
1525
    lastNdaySale = ""
9685 rajveer 1526
    oosStatuses = get_oos_statuses_for_x_days_for_item(itemId, 0, numberOfDays)
7972 amar.kumar 1527
    for oosStatus in oosStatuses:
1528
        if oosStatus.is_oos == True:
1529
            lastNdaySale +="X-"
1530
        else:
1531
            lastNdaySale +=str(oosStatus.num_orders) + "-"
1532
    return lastNdaySale[:-1] 
1533
 
7281 kshitij.so 1534
def get_warehouse_name(warehouseId):
1535
    row = Warehouse.get_by(id = warehouseId)
1536
    return row.displayName
1537
 
1538
def get_amazon_inventory_for_item(amazonItemId):
1539
    inventory = AmazonInventorySnapshot.get_by(item_id=amazonItemId)
1540
    return inventory
1541
 
1542
def get_all_amazon_inventory():
1543
    return session.query(AmazonInventorySnapshot).all()
1544
 
10450 vikram.rag 1545
def add_or_update_amazon_inventory_for_item(amazoninventorysnapshot,time):
7281 kshitij.so 1546
    inventory = AmazonInventorySnapshot.get_by(item_id = amazoninventorysnapshot.item_id)
1547
    if inventory is None:
1548
        amazon_inventory = AmazonInventorySnapshot()
1549
        amazon_inventory.item_id = amazoninventorysnapshot.item_id
1550
        amazon_inventory.availability = amazoninventorysnapshot.availability
1551
        amazon_inventory.reserved = amazoninventorysnapshot.reserved
10450 vikram.rag 1552
        amazon_inventory.is_oos = amazoninventorysnapshot.is_oos
1553
        if time != 0:
1554
            amazon_inventory.lastUpdatedOnAmazon = to_py_date(time)
1555
    else: 
7281 kshitij.so 1556
        inventory.availability = amazoninventorysnapshot.availability
1557
        inventory.reserved = amazoninventorysnapshot.reserved
10450 vikram.rag 1558
        if not inventory.is_oos and (to_py_date(time) - inventory.lastUpdatedOnAmazon).days == 0:
1559
            pass
1560
        else:
1561
            inventory.is_oos = amazoninventorysnapshot.is_oos
1562
        if time != 0:    
1563
            inventory.lastUpdatedOnAmazon = to_py_date(time)      
7281 kshitij.so 1564
    session.commit()
1565
 
8182 amar.kumar 1566
def add_update_hold_inventory(itemId, warehouseId, holdQuantity, source):
9762 amar.kumar 1567
    if holdQuantity <0:
1568
        print "Negative holdQuantity : " + str(holdQuantity) + " is not allowed"
1569
        raise InventoryServiceException(108, "Negative heldQuantity is not allowed")
8197 amar.kumar 1570
    hold_inventory_detail = HoldInventoryDetail.get_by(item_id = itemId, warehouse_id=warehouseId, source = source)
1571
    if  hold_inventory_detail is None:
8182 amar.kumar 1572
        diffTobeAddedInCIS = holdQuantity
1573
        hold_inventory_detail = HoldInventoryDetail()
1574
        hold_inventory_detail.item_id = itemId 
1575
        hold_inventory_detail.warehouse_id = warehouseId 
1576
        hold_inventory_detail.held = holdQuantity 
1577
        hold_inventory_detail.source = source
1578
    else:
8497 amar.kumar 1579
        diffTobeAddedInCIS = holdQuantity - hold_inventory_detail.held
8182 amar.kumar 1580
        hold_inventory_detail.held = holdQuantity
1581
 
1582
    current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
1583
    if not current_inventory_snapshot:
1584
        current_inventory_snapshot = CurrentInventorySnapshot()
1585
        current_inventory_snapshot.item_id = itemId
1586
        current_inventory_snapshot.warehouse_id = warehouseId
1587
        current_inventory_snapshot.availability = 0
1588
        current_inventory_snapshot.reserved = 0
1589
        current_inventory_snapshot.held = 0
1590
    current_inventory_snapshot.held = current_inventory_snapshot.held + diffTobeAddedInCIS
1591
    session.commit()
1592
    #**Update item availability cache**#
1593
    clear_item_availability_cache(itemId)
8282 kshitij.so 1594
 
1595
def add_or_update_amazon_fba_inventory(amazonfbainventorysnapshot):
11173 vikram.rag 1596
    inventory = AmazonFbaInventorySnapshot.query.filter_by(item_id = amazonfbainventorysnapshot.item_id,location=amazonfbainventorysnapshot.location).first()
8282 kshitij.so 1597
    if inventory is None:
1598
        amazon_fba_inventory = AmazonFbaInventorySnapshot()
1599
        amazon_fba_inventory.item_id = amazonfbainventorysnapshot.item_id
1600
        amazon_fba_inventory.availability = amazonfbainventorysnapshot.availability
11173 vikram.rag 1601
        amazon_fba_inventory.location = amazonfbainventorysnapshot.location
1602
        amazon_fba_inventory.reserved = amazonfbainventorysnapshot.reserved
1603
        amazon_fba_inventory.inbound = amazonfbainventorysnapshot.inbound
1604
        amazon_fba_inventory.unfulfillable = amazonfbainventorysnapshot.unfulfillable
1605
 
8282 kshitij.so 1606
    else:
11173 vikram.rag 1607
        print 'updating'
8282 kshitij.so 1608
        inventory.availability = amazonfbainventorysnapshot.availability
11173 vikram.rag 1609
        inventory.location = amazonfbainventorysnapshot.location
1610
        inventory.reserved = amazonfbainventorysnapshot.reserved
1611
        inventory.inbound = amazonfbainventorysnapshot.inbound
1612
        inventory.unfulfillable = amazonfbainventorysnapshot.unfulfillable
8282 kshitij.so 1613
 
1614
 
1615
def get_amazon_fba_inventory(itemId):
11173 vikram.rag 1616
    return AmazonFbaInventorySnapshot.query.filter_by(item_id = itemId)
8282 kshitij.so 1617
 
8363 vikram.rag 1618
def get_all_amazon_fba_inventory():
1619
    return AmazonFbaInventorySnapshot.query.all() 
1620
 
12799 manish.sha 1621
def get_oursgood_warehouseids_for_location(stateId):
8363 vikram.rag 1622
    warehouseId=[]
12799 manish.sha 1623
    x= session.query(Warehouse.id).filter(Warehouse.id==Warehouse.billingWarehouseId).filter(Warehouse.warehouseType=='OURS').filter(Warehouse.state_id==stateId).all()
8363 vikram.rag 1624
    for id in x:
1625
        warehouseId.append(id[0])
1626
    return session.query(Warehouse.id).filter(Warehouse.inventoryType=='GOOD').filter(Warehouse.warehouseType=='OURS').filter(Warehouse.billingWarehouseId.in_(warehouseId)).all()
8954 vikram.rag 1627
 
1628
def get_holdinventorydetail_forItem_forWarehouseId_exceptsource(item_id,warehouse_id,source):
1629
    holddetails = HoldInventoryDetail.query.filter(HoldInventoryDetail.item_id == item_id).all()
1630
    print holddetails
1631
    hold = 0
1632
    for holddetail in holddetails:
1633
        if holddetail.source !=source and holddetail.warehouse_id == warehouse_id:
1634
            hold = hold + holddetail.held
9404 vikram.rag 1635
    return hold
1636
 
1637
def get_snapdeal_inventory_for_item(id):
1638
    print SnapdealInventorySnapshot.get_by(item_id = id)
1639
    return SnapdealInventorySnapshot.get_by(item_id = id)
1640
 
1641
def add_or_update_snapdeal_inventor_for_item(snapdealinventoryitem):
1642
    snapdeal_inventory_item = SnapdealInventorySnapshot.get_by(item_id = snapdealinventoryitem.item_id)
1643
    if snapdeal_inventory_item is None:
1644
        snapdeal_inventory_item = SnapdealInventorySnapshot()
1645
        snapdeal_inventory_item.item_id = snapdealinventoryitem.item_id
1646
        snapdeal_inventory_item.availability = snapdealinventoryitem.availability
9495 vikram.rag 1647
        snapdeal_inventory_item.pendingOrders = snapdealinventoryitem.pendingOrders
9404 vikram.rag 1648
        snapdeal_inventory_item.lastUpdatedOnSnapdeal = to_py_date(snapdealinventoryitem.lastUpdatedOnSnapdeal)
10450 vikram.rag 1649
        snapdeal_inventory_item.is_oos = snapdealinventoryitem.is_oos
9404 vikram.rag 1650
    else:
1651
        snapdeal_inventory_item.availability = snapdealinventoryitem.availability
9495 vikram.rag 1652
        snapdeal_inventory_item.pendingOrders = snapdealinventoryitem.pendingOrders
10450 vikram.rag 1653
        if not snapdeal_inventory_item.is_oos and (to_py_date(snapdealinventoryitem.lastUpdatedOnSnapdeal) - snapdeal_inventory_item.lastUpdatedOnSnapdeal).days == 0:
1654
            pass
1655
        else:
1656
            snapdeal_inventory_item.is_oos = snapdealinventoryitem.is_oos
9404 vikram.rag 1657
        snapdeal_inventory_item.lastUpdatedOnSnapdeal = to_py_date(snapdealinventoryitem.lastUpdatedOnSnapdeal)
1658
    session.commit()
8954 vikram.rag 1659
 
9404 vikram.rag 1660
def get_nlc_for_warehouse(warehouse_id,itemid):
1661
    warehouse = Warehouse.get_by(id=warehouse_id)
1662
    if warehouse is None:
1663
        return 0
1664
    vendoritempricing = VendorItemPricing.query.filter_by(item_id=itemid, vendor_id=warehouse.vendor_id).first()
1665
    '''vendoritempricing = VendorItemPricing.get_by(id=warehouse.vendor_id,item_id=itemid)'''
1666
    if vendoritempricing is None:
1667
        return 0
9456 vikram.rag 1668
    return vendoritempricing.nlc
1669
 
9495 vikram.rag 1670
def get_snapdeal_inventory_snapshot():
9640 amar.kumar 1671
    return SnapdealInventorySnapshot.query.all()
10050 vikram.rag 1672
 
9640 amar.kumar 1673
def get_held_inventory_map_for_item(itemId, warehouseId):
1674
    heldInventoryMap = {}
1675
    holdInventories = HoldInventoryDetail.query.filter_by(item_id= itemId, warehouse_id = warehouseId).all()
1676
    for holdInventory in holdInventories:
1677
        heldInventoryMap[holdInventory.source] = holdInventory.held
1678
    return heldInventoryMap 
10050 vikram.rag 1679
 
9761 amar.kumar 1680
def get_hold_inventory_details(itemId, warehouseId, source):
1681
    heldInventoryQuery = HoldInventoryDetail.query
1682
    if itemId:
1683
        heldInventoryQuery = heldInventoryQuery.filter_by(item_id = itemId)
1684
    if warehouseId:
1685
        heldInventoryQuery = heldInventoryQuery.filter_by(warehouse_id = warehouseId)
1686
    if source:
1687
        heldInventoryQuery = heldInventoryQuery.filter_by(source = source)
1688
    holdInventoryDetails = heldInventoryQuery.all()
1689
    return holdInventoryDetails
9896 rajveer 1690
 
10450 vikram.rag 1691
def add_or_update_flipkart_inventory_snapshot(flipkartInventorySnapshot,time):
10050 vikram.rag 1692
    for snapshot in flipkartInventorySnapshot:
1693
        flipkart_inventory = FlipkartInventorySnapshot.get_by(item_id = snapshot.item_id)
1694
        if flipkart_inventory is None:
1695
            flipkart_inventory = FlipkartInventorySnapshot()
1696
            flipkart_inventory.item_id = snapshot.item_id
1697
            flipkart_inventory.availability = snapshot.availability
1698
            flipkart_inventory.createdOrders = snapshot.createdOrders
1699
            flipkart_inventory.heldOrders = snapshot.heldOrders
10450 vikram.rag 1700
            flipkart_inventory.is_oos = snapshot.is_oos
1701
            flipkart_inventory.lastUpdatedOnFlipkart = to_py_date(time) 
10050 vikram.rag 1702
        else:
1703
            flipkart_inventory.availability = snapshot.availability
1704
            flipkart_inventory.createdOrders = snapshot.createdOrders
1705
            flipkart_inventory.heldOrders = snapshot.heldOrders
10450 vikram.rag 1706
            if not flipkart_inventory.is_oos and (to_py_date(time) - flipkart_inventory.lastUpdatedOnFlipkart).days == 0:
1707
                pass
1708
            else:
1709
                flipkart_inventory.is_oos = snapshot.is_oos
1710
            flipkart_inventory.lastUpdatedOnFlipkart = to_py_date(time) 
10050 vikram.rag 1711
    session.commit()
1712
 
1713
def get_flipkart_inventory_snapshot():
1714
    return FlipkartInventorySnapshot.query.all()     
1715
 
10097 kshitij.so 1716
def get_flipkart_inventory_for_Item(itemId):
10485 vikram.rag 1717
    return FlipkartInventorySnapshot.get_by(item_id = itemId)
1718
 
1719
def get_state_master():
1720
    stateIdNameMap = {} 
1721
    statemaster = StateMaster.query.all()
1722
    for state in statemaster:
12280 amit.gupta 1723
        stateIdNameMap[state.id] = to_t_state(state)
10544 vikram.rag 1724
    return stateIdNameMap    
1725
 
1726
def update_snapdeal_stock_at_eod(allsnapdealstock):
1727
    for stockitem in allsnapdealstock:
1728
        snapdealstockateod = SnapdealStockAtEOD()
1729
        snapdealstockateod.item_id = stockitem.item_id
1730
        snapdealstockateod.availability = stockitem.availability
1731
        snapdealstockateod.date =  to_py_date(stockitem.date)
1732
    session.commit()
1733
 
1734
def update_flipkart_stock_at_eod(allflipkartstock):
1735
    for stockitem in allflipkartstock:
1736
        snapdealstockateod = FlipkartStockAtEOD()
1737
        snapdealstockateod.item_id = stockitem.item_id
1738
        snapdealstockateod.availability = stockitem.availability
1739
        snapdealstockateod.date =  to_py_date(stockitem.date)
1740
    session.commit()
10687 rajveer 1741
 
12363 kshitij.so 1742
def get_wanlc_for_source(item_id,sourceId):
1743
    stockWanlc = StockWeightedNlcInfo.query.filter(StockWeightedNlcInfo.itemId==item_id).filter(StockWeightedNlcInfo.source==sourceId).order_by(desc(StockWeightedNlcInfo.updatedTimestamp)).limit(1).all()
1744
    if stockWanlc is None or len(stockWanlc)==0:
1745
        return 0.0
1746
    else:
1747
        return stockWanlc[0].avgWeightedNlc
1748
 
1749
def get_all_available_amazon_inventory():
19247 kshitij.so 1750
    return AmazonFbaInventorySnapshot.query.filter(AmazonFbaInventorySnapshot.availability>0).all()
1751
 
1752
def add_vendor_item_pricing_in_bulk(vendorItemPricingList):
1753
    exceptionItems = []
1754
    for vendorItemPricing in vendorItemPricingList:
1755
        try:
1756
            add_vendor_pricing(vendorItemPricing, False)
1757
        except:
1758
            exceptionItems.append(vendorItemPricing.itemId)
1759
    return exceptionItems
1760
 
1761
def add_inventory_in_bulk(bulkInventoryList):
1762
    for item in bulkInventoryList:
19989 kshitij.so 1763
        add_inventory(item.item_id, item.warehouse_id, item.inventory, True)
19247 kshitij.so 1764
 
1765
 
23316 amit.gupta 1766
 
1767
#from shop2020.clients.TransactionClient import TransactionClient
1768
#from shop2020.thriftpy.model.v1.order.ttypes import OrderType, OrderSource, TransactionStatus
1769
#from shop2020.thriftpy.logistics.ttypes import LocationInfo, PickUpType
1770
#tc = TransactionClient().get_client()
1771
#tc.changeTransactionStatus(1037182, TransactionStatus.COD_IN_PROCESS, 'Cod Payment Awaited', PickUpType.COURIER, OrderType.B2C, OrderSource.WEBSITE)