Subversion Repositories SmartDukaan

Rev

Rev 9640 | Rev 9666 | 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
5944 mandeep.dh 9
from shop2020.clients.TransactionClient import TransactionClient
10
from shop2020.model.v1.inventory.impl import DataService
6531 vikram.rag 11
from shop2020.model.v1.inventory.impl.Convertors import to_t_warehouse, \
12
    to_t_itemidwarehouseid
5944 mandeep.dh 13
from shop2020.model.v1.inventory.impl.DataService import Warehouse, \
14
    ItemInventoryHistory, CurrentInventorySnapshot, VendorItemPricing, \
15
    VendorItemMapping, Vendor, MissedInventoryUpdate, BadInventorySnapshot, \
8491 rajveer 16
    VendorHolidays, ItemAvailabilityCache, \
7410 amar.kumar 17
    CurrentReservationSnapshot, IgnoredInventoryUpdateItems, ItemStockPurchaseParams, \
9404 vikram.rag 18
    OOSStatus, AmazonInventorySnapshot, StateMaster, HoldInventoryDetail, AmazonFbaInventorySnapshot, \
19
    SnapdealInventorySnapshot
6531 vikram.rag 20
from shop2020.thriftpy.model.v1.inventory.ttypes import \
21
    InventoryServiceException, HolidayType, InventoryType, WarehouseType
5944 mandeep.dh 22
from shop2020.thriftpy.model.v1.order.ttypes import AlertType
6531 vikram.rag 23
from shop2020.thriftpy.purchase.ttypes import PurchaseServiceException
5944 mandeep.dh 24
from shop2020.utils import EmailAttachmentSender
25
from shop2020.utils.EmailAttachmentSender import mail
6821 amar.kumar 26
from shop2020.utils.Utils import to_py_date, to_java_date
5944 mandeep.dh 27
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
7410 amar.kumar 28
from sqlalchemy.sql import or_
6531 vikram.rag 29
from sqlalchemy.sql.expression import and_, func, distinct
30
from sqlalchemy.sql.functions import count
5944 mandeep.dh 31
import calendar
32
import datetime
33
import sys
34
import threading
35
 
6550 rajveer 36
to_addresses = ["khushal.bhatia@shop2020.in", "chaitnaya.vats@shop2020.in", "chandan.kumar@shop2020.in"]
6029 rajveer 37
mail_user = "cnc.center@shop2020.in"
38
mail_password = "5h0p2o2o"
5944 mandeep.dh 39
skippedItems = { 175 : [27, 2160, 2175, 2163, 2158, 7128, 26, 2154],
40
                 193 : [5839] }
41
 
6821 amar.kumar 42
OOS_CALCULATION_TIME = 23
6498 vikram.rag 43
 
5944 mandeep.dh 44
def initialize(dbname='inventory', db_hostname="localhost"):
45
    DataService.initialize(dbname, db_hostname)
46
 
47
def get_Warehouse(warehouse_id):
48
    return Warehouse.get_by(id=warehouse_id)
49
 
50
def get_vendor(vendorId):
51
    return Vendor.get_by(id=vendorId)
52
 
7410 amar.kumar 53
def get_state(stateId):
54
    return StateMaster.get_by(id=stateId)
55
 
5944 mandeep.dh 56
def get_all_warehouses_by_status(status):
57
    return Warehouse.query.all()
58
 
59
def get_all_items_for_warehouse(warehouse_id):
60
    warehouse = get_Warehouse(warehouse_id)
61
    if not warehouse:
62
        raise InventoryServiceException(108, "bad warehouse")
63
    return warehouse.all_items
64
 
65
def add_warehouse(warehouse):
66
    if not warehouse:
67
        raise InventoryServiceException(108, "Bad warehouse")
68
    if get_Warehouse(warehouse.id):
69
        #warehouse is already present.
70
        raise InventoryServiceException(101, "Warehouse already present")
71
 
72
    ds_warehouse = Warehouse()
73
    ds_warehouse.location = warehouse.location
74
    ds_warehouse.status = 3
75
    ds_warehouse.addedOn = datetime.datetime.now()
76
    ds_warehouse.lastCheckedOn = datetime.datetime.now()
77
    ds_warehouse.tinNumber = warehouse.tinNumber
78
    ds_warehouse.pincode = warehouse.pincode
79
    ds_warehouse.billingType = warehouse.billingType
80
    ds_warehouse.billingWarehouseId = warehouse.billingWarehouseId
81
    ds_warehouse.displayName = warehouse.displayName
82
    ds_warehouse.inventoryType = InventoryType._VALUES_TO_NAMES[warehouse.inventoryType]
83
    ds_warehouse.isAvailabilityMonitored = warehouse.isAvailabilityMonitored
84
    ds_warehouse.logisticsLocation = warehouse.logisticsLocation
85
    ds_warehouse.shippingWarehouseId = warehouse.shippingWarehouseId
86
    ds_warehouse.transferDelayInHours = warehouse.transferDelayInHours
87
    ds_warehouse.vendor = get_vendor(warehouse.vendor.id)
7410 amar.kumar 88
    ds_warehouse.state = get_state(warehouse.stateId)
5944 mandeep.dh 89
    ds_warehouse.warehouseType = WarehouseType._VALUES_TO_NAMES[warehouse.warehouseType]    
90
    if warehouse.vendorString:
91
        ds_warehouse.vendorString = warehouse.vendorString
92
    session.commit()
93
    return ds_warehouse.id
94
 
6498 vikram.rag 95
def get_ignored_items(warehouse_id): 
6531 vikram.rag 96
    Ignored_inventory_items = IgnoredInventoryUpdateItems.query.filter_by(warehouse_id=warehouse_id).all()
6498 vikram.rag 97
    negativeItems = []
98
    for Ignored_inventory_item in Ignored_inventory_items:
99
        try:
100
            item_id = Ignored_inventory_item.item_id
101
            negativeItems.append(item_id)
102
        except:
103
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
104
    return negativeItems
105
 
6510 rajveer 106
def get_ignored_warehouses(item_id): 
6539 amit.gupta 107
    Ignored_inventory_items = IgnoredInventoryUpdateItems.query.filter_by(item_id=item_id).all()
6510 rajveer 108
    warehouses = []
109
    for Ignored_inventory_item in Ignored_inventory_items:
110
        warehouses.append(Ignored_inventory_item.warehouse_id)
111
    return warehouses
112
 
5944 mandeep.dh 113
def update_inventory_history(warehouse_id, timestamp, availability):
114
    warehouse = get_Warehouse(warehouse_id)
115
    if not warehouse:
116
        raise InventoryServiceException(107, "Warehouse? Where?")
117
    vendor = warehouse.vendor
118
    time = datetime.datetime.now()
119
    for item_key, quantity in availability.iteritems():
120
        try:
121
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
5960 mandeep.dh 122
            item_id = vendor_item_mapping.item_id
5944 mandeep.dh 123
        except:
6531 vikram.rag 124
            continue  
5944 mandeep.dh 125
        try:
6510 rajveer 126
            item_inventory_history = ItemInventoryHistory()
127
            item_inventory_history.warehouse = warehouse
128
            item_inventory_history.item_id = item_id
129
            item_inventory_history.timestamp = time
130
            item_inventory_history.availability = quantity
5944 mandeep.dh 131
        except:
132
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
133
    session.commit()
134
 
135
def update_inventory(warehouse_id, timestamp, availability):
136
    warehouse = get_Warehouse(warehouse_id)
137
    if not warehouse:
138
        raise InventoryServiceException(107, "Warehouse? Where?")
6510 rajveer 139
 
5944 mandeep.dh 140
    time = datetime.datetime.now()
141
    warehouse.lastCheckedOn = time
142
    warehouse.vendorString = timestamp
143
    vendor = warehouse.vendor
144
    item_ids = []
145
    for item_key, quantity in availability.iteritems():
146
        try:
147
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
148
            item_id = vendor_item_mapping.item_id
6510 rajveer 149
            item_ids.append(item_id)
5944 mandeep.dh 150
        except:
151
            print 'Skipping update for ' + item_key + ' quantity ' + str(quantity) + ' warehouse id: ' + str(warehouse_id)
152
            __send_mail_for_missing_key(item_key, quantity, warehouse_id)
153
            continue
154
        try:
155
            current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=item_id, warehouse=warehouse)
156
            if not current_inventory_snapshot:
157
                current_inventory_snapshot = CurrentInventorySnapshot()
158
                current_inventory_snapshot.item_id = item_id
159
                current_inventory_snapshot.warehouse = warehouse
160
                current_inventory_snapshot.availability = 0
161
                current_inventory_snapshot.reserved = 0
8204 amar.kumar 162
                current_inventory_snapshot.held = 0
5944 mandeep.dh 163
            # added the difference in the current inventory    
164
            current_inventory_snapshot.availability = current_inventory_snapshot.availability + quantity
165
            item = __get_item_from_master(item_id)
166
            try:
167
                if quantity > 0 and __get_item_reserved(item_id) > 0:
168
                    cl = TransactionClient().get_client()
169
                    #FIXME hardcoding for warehouse id 
170
                    cl.addAlert(AlertType.NEW_INVENTORY_ALERT, 5, "Inventory received for item " + item.brand + " " + item.modelName + " " + item.modelNumber + " " +  item.color)
171
            except:
172
                print "Not able to raise alert for incoming inventory" 
173
            if current_inventory_snapshot.availability < 0:
174
                __send_alert_for_negative_availability(item, current_inventory_snapshot.availability, warehouse)
175
        except:
176
            print "Some unforeseen error while updating inventory:", sys.exc_info()[0]
177
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
178
    session.commit()
179
 
180
    #**Update item availability cache**#
181
    for item_id in item_ids:
5978 rajveer 182
        clear_item_availability_cache(item_id)
5944 mandeep.dh 183
 
184
def __send_alert_for_negative_reserved(item, reserved, warehouse):
185
    itemName = " ".join([str(item.id), str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
6029 rajveer 186
    EmailAttachmentSender.mail(mail_user, mail_password, 'amar.kumar@shop2020.in', 'Negative reserved: ' + str(reserved) + ' for Item Id: ' + itemName + ' warehouse id: ' + str(warehouse.id), None)
5944 mandeep.dh 187
 
188
def __send_alert_for_negative_availability(item, availability, warehouse):
189
    itemName = " ".join([str(item.id), str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
5964 amar.kumar 190
    # 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 191
 
192
def __send_mail_for_missing_key(item_key, quantity, warehouse_id):
193
    missedInventoryUpdate = MissedInventoryUpdate.get_by(itemKey = item_key, warehouseId = warehouse_id)
194
    # One email per product key mismatch
195
    if not missedInventoryUpdate:
196
        missedInventoryUpdate = MissedInventoryUpdate()
197
        missedInventoryUpdate.itemKey = item_key
198
        missedInventoryUpdate.quantity = quantity
199
        missedInventoryUpdate.isIgnored = 1
200
        missedInventoryUpdate.timestamp = datetime.datetime.now()
201
        missedInventoryUpdate.warehouseId = warehouse_id
202
        session.commit()
6232 rajveer 203
        try:
8214 amar.kumar 204
            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 205
        except:
206
            print "Not able to send email. No issues, we can continue with updates."
5944 mandeep.dh 207
    else:
208
        missedInventoryUpdate.quantity += quantity
209
        session.commit()
210
 
211
def add_inventory(itemId, warehouseId, quantity):
212
    current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
213
    if not current_inventory_snapshot:
214
        current_inventory_snapshot = CurrentInventorySnapshot()
215
        current_inventory_snapshot.item_id = itemId
216
        current_inventory_snapshot.warehouse_id = warehouseId
217
        current_inventory_snapshot.availability = 0
218
        current_inventory_snapshot.reserved = 0
8204 amar.kumar 219
        current_inventory_snapshot.held = 0
5944 mandeep.dh 220
    # added the difference in the current inventory    
221
    current_inventory_snapshot.availability = current_inventory_snapshot.availability + quantity
222
    session.commit()
223
    #**Update item availability cache**#
5978 rajveer 224
    clear_item_availability_cache(itemId)
5944 mandeep.dh 225
    if current_inventory_snapshot.availability < 0:
226
        item = __get_item_from_master(itemId)
5978 rajveer 227
        __send_alert_for_negative_availability(item, current_inventory_snapshot.availability, get_Warehouse(warehouseId)) 
5944 mandeep.dh 228
 
229
def add_bad_inventory(itemId, warehouseId, quantity):
230
    bad_inventory_snapshot = BadInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
231
    if not bad_inventory_snapshot:
232
        bad_inventory_snapshot = BadInventorySnapshot()
233
        bad_inventory_snapshot.item_id = itemId
234
        bad_inventory_snapshot.warehouse_id = warehouseId
235
        bad_inventory_snapshot.availability = 0
236
    # added the difference in the current inventory    
237
    bad_inventory_snapshot.availability += quantity
238
    session.commit()
239
    if bad_inventory_snapshot.availability < 0:
240
        item = __get_item_from_master(itemId)
241
        __send_alert_for_negative_availability(item, bad_inventory_snapshot.availability, get_Warehouse(warehouseId))
242
 
243
def get_item_inventory_by_item_id(item_id):
244
    return CurrentInventorySnapshot.query.filter_by(item_id=item_id).all()
245
 
246
def retire_warehouse(warehouse_id):
247
    if not warehouse_id:
248
        raise InventoryServiceException(101, "Bad warehouse id")
249
    warehouse = get_Warehouse(warehouse_id)
250
    if not warehouse:
251
        raise InventoryServiceException(108, "warehouse id not present")
252
    warehouse.status = 0;
253
    session.commit()
254
 
255
def get_item_availability_for_warehouse(warehouse_id, item_id):
6545 rajveer 256
    ignore = IgnoredInventoryUpdateItems.query.filter_by(item_id=item_id).filter_by(warehouse_id = warehouse_id).all()
6544 rajveer 257
    if ignore:
258
        return 0
5944 mandeep.dh 259
 
260
    try:
6544 rajveer 261
        current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id).filter_by(item_id = item_id).one()
5944 mandeep.dh 262
        return current_inventory_snapshot.availability - current_inventory_snapshot.reserved
263
    except:
264
        return 0
265
 
6484 amar.kumar 266
def get_item_availability_for_our_warehouses(item_ids):
7699 amar.kumar 267
    our_warehouses = Warehouse.query.filter_by(warehouseType = 'OURS', inventoryType = 'GOOD').all()
268
    our_thirdparty_warehouses = Warehouse.query.filter_by(warehouseType = 'OURS_THIRDPARTY').all()
6484 amar.kumar 269
    warehouse_ids = []
7699 amar.kumar 270
    for warehouse in our_warehouses :
6484 amar.kumar 271
        warehouse_ids.append(warehouse.id)
7699 amar.kumar 272
    for warehouse in our_thirdparty_warehouses :
273
        warehouse_ids.append(warehouse.id)
274
 
6484 amar.kumar 275
    availability_map = dict()
276
 
277
    try :
278
        for item_id in item_ids :
279
            total_availability = 0
280
            for current_inventory_snapshot in CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).filter_by(item_id = item_id).all():
281
                total_availability += current_inventory_snapshot.availability
282
            if total_availability >0:
283
                availability_map[item_id] = total_availability
284
    except Exception as e:
285
        print e
286
        raise PurchaseServiceException(101, 'Exception while fetching availability of items in our warehouses')
287
 
288
    return availability_map
289
 
5944 mandeep.dh 290
'''
291
This method returns quantity of a particular item across all warehouses whose ids is provided
292
if warehouse_ids is null it checks for inventory in all warehouses.
293
'''
294
def __get_item_availability(item, warehouse_ids):
295
    if warehouse_ids is None:
296
        all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
297
        availability = 0
298
        reserved = 0
299
        for currInv in all_inventory:
300
            availability = availability + currInv.availability
301
            reserved = reserved + currInv.reserved
302
        return availability - reserved
303
    else:
304
        total_availability = 0
305
        for current_inventory_snapshot in CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).filter_by(item_id = item.id).all():
306
            total_availability += current_inventory_snapshot.availability - current_inventory_snapshot.reserved
307
        return total_availability 
308
 
309
def __get_item_reserved(item_id):
310
    all_inventory = CurrentInventorySnapshot.query.filter_by(item_id = item_id).all()
311
    reserved = 0
312
    for currInv in all_inventory:
313
        reserved = reserved + currInv.reserved
314
    return reserved
5966 rajveer 315
 
316
def __get_item_availability_at_warehouse(warehouse_id, item_id):
317
    inventory = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).one()
318
    return inventory.availability
319
 
320
def is_order_billable(item_id, warehouse_id, source_id, order_id):
321
    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()
322
    availability = __get_item_availability_at_warehouse(warehouse_id, item_id)
323
    for reservation in reservations:
324
        availability = availability - reservation.reserved
325
        if reservation.order_id == order_id and reservation.source_id == source_id:
326
            break
327
    if availability < 0:
328
        return False
329
    return True
5944 mandeep.dh 330
 
5966 rajveer 331
def reserve_item_in_warehouse(item_id, warehouse_id, source_id, order_id, created_timestamp, promised_shipping_timestamp, quantity):    
5944 mandeep.dh 332
    if not warehouse_id:
333
        raise InventoryServiceException(101, "bad warehouse_id")
334
 
335
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
336
    try:
337
        current_inventory_snapshot = query.one()
338
    except:
339
        current_inventory_snapshot = CurrentInventorySnapshot()
340
        current_inventory_snapshot.warehouse_id = warehouse_id
341
        current_inventory_snapshot.item_id = item_id
342
        current_inventory_snapshot.availability = 0
343
        current_inventory_snapshot.reserved = 0
8204 amar.kumar 344
        current_inventory_snapshot.held = 0
5944 mandeep.dh 345
 
346
    current_inventory_snapshot.reserved = current_inventory_snapshot.reserved + quantity
5966 rajveer 347
 
348
    reservation = CurrentReservationSnapshot()
349
    reservation.item_id = item_id
350
    reservation.warehouse_id = warehouse_id
351
    reservation.source_id = source_id
352
    reservation.order_id = order_id
5990 rajveer 353
    reservation.created_timestamp = to_py_date(created_timestamp)
354
    reservation.promised_shipping_timestamp = to_py_date(promised_shipping_timestamp)
5966 rajveer 355
    reservation.reserved = quantity
356
 
8720 amar.kumar 357
    session.commit()
8182 amar.kumar 358
 
359
    try:
360
        order_client = TransactionClient().get_client()
361
        order = order_client.getOrder(order_id)
9574 amar.kumar 362
        if order.source:
363
            holdInventoryDetail = HoldInventoryDetail.query.filter_by(item_id = item_id, warehouse_id = warehouse_id, source = order.source).first()
364
            if holdInventoryDetail is not None and holdInventoryDetail.held>0:
365
                previousHeld = holdInventoryDetail.held
366
                holdInventoryDetail.held = max(0, holdInventoryDetail.held -quantity)
367
                diff = previousHeld-holdInventoryDetail.held 
368
                current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=item_id, warehouse_id=warehouse_id)
369
                if current_inventory_snapshot is not None:
370
                    current_inventory_snapshot.held = max(0, current_inventory_snapshot.held - diff)
371
                session.commit()
8182 amar.kumar 372
    except:
373
        print "Unable to release hold Inventory for item_id " + str(item_id) + " warehouse_id " + str(warehouse_id) + " source " + str(source_id)
8720 amar.kumar 374
    #session.commit()
5944 mandeep.dh 375
    #**Update item availability cache**#
5978 rajveer 376
    clear_item_availability_cache(item_id)
5944 mandeep.dh 377
    return True
378
 
7968 amar.kumar 379
def update_reservation_for_order(item_id, warehouse_id, source_id, order_id, created_timestamp, promised_shipping_timestamp, quantity):    
380
    if not warehouse_id:
381
        raise InventoryServiceException(101, "bad warehouse_id")
382
    warehouse = get_Warehouse(warehouse_id)
383
    item_pricing = get_item_pricing(item_id, warehouse.vendor.id)
384
    if not item_pricing:
385
        raise InventoryServiceException(101, "No Pricing Info found for vendor and Item")
386
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
387
    try:
388
        new_current_inventory_snapshot = query.one()
389
    except:
390
        new_current_inventory_snapshot = CurrentInventorySnapshot()
391
        new_current_inventory_snapshot.warehouse_id = warehouse_id
392
        new_current_inventory_snapshot.item_id = item_id
393
        new_current_inventory_snapshot.availability = 0
394
        new_current_inventory_snapshot.reserved = 0
395
 
396
    new_current_inventory_snapshot.reserved = new_current_inventory_snapshot.reserved + quantity
397
 
398
    new_reservation = CurrentReservationSnapshot()
399
    new_reservation.item_id = item_id
400
    new_reservation.warehouse_id = warehouse_id
401
    new_reservation.source_id = source_id
402
    new_reservation.order_id = order_id
403
    new_reservation.created_timestamp = to_py_date(created_timestamp)
404
    new_reservation.promised_shipping_timestamp = to_py_date(promised_shipping_timestamp)
405
    new_reservation.reserved = quantity
406
 
8182 amar.kumar 407
    try:
408
        order_client = TransactionClient().get_client()
409
        order = order_client.getOrder(order_id)
9574 amar.kumar 410
        if order.source:
411
            holdInventoryDetail = HoldInventoryDetail.query.filter_by(item_id = item_id, warehouse_id = warehouse_id, source = order.source).first()
412
            if holdInventoryDetail is not None and holdInventoryDetail.held>0:
413
                previousHeld = holdInventoryDetail.held
414
                holdInventoryDetail.held = max(0, holdInventoryDetail.held -quantity)
415
                diff = previousHeld-holdInventoryDetail.held 
416
                current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=item_id, warehouse_id=warehouse_id)
417
                if current_inventory_snapshot is not None:
418
                    current_inventory_snapshot.held = max(0, current_inventory_snapshot.held - diff)
419
                session.commit()
8182 amar.kumar 420
    except:
421
        print "Unable to release hold Inventory for item_id " + str(item_id) + " warehouse_id " + str(warehouse_id) + " source " + str(source_id)
422
 
7968 amar.kumar 423
    order_client = TransactionClient().get_client()
424
    order = order_client.getOrder(order_id)
425
    for lineitem in order.lineitems:
426
        query = CurrentInventorySnapshot.query.filter_by(warehouse_id = order.fulfilmentWarehouseId, item_id = lineitem.item_id)
427
        try:
428
            current_inventory_snapshot = query.one()
429
            current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
430
 
431
            reservation = CurrentReservationSnapshot.query.filter_by(warehouse_id = order.fulfilmentWarehouseId, item_id = lineitem.item_id, source_id = source_id, order_id = order_id).one()
432
            if reservation.reserved == quantity:
433
                reservation.delete()
434
            else:
435
                reservation.reserved -= quantity
436
 
437
            clear_item_availability_cache(lineitem.item_id)
438
            session.commit()
439
            try:
440
                if current_inventory_snapshot.reserved < 0:
441
                    item = __get_item_from_master(lineitem.item_id)
442
                    __send_alert_for_negative_reserved(item, current_inventory_snapshot.reserved, get_Warehouse(order.fulfilmentWarehouseId))
443
            except:
8182 amar.kumar 444
                print "Error in sending negative reserved alert:", sys.exc_info()[0]
7968 amar.kumar 445
                return False
446
        except:
447
            print "Error in reducing reservation for item:", sys.exc_info()[0]
448
            return False
449
    session.commit()
450
    #**Update item availability cache**#
451
    clear_item_availability_cache(item_id)
452
    return True
453
 
454
 
5966 rajveer 455
def reduce_reservation_count(item_id, warehouse_id, source_id, order_id, quantity):
5944 mandeep.dh 456
    if not warehouse_id:
457
        raise InventoryServiceException(101, "bad warehouse_id")
458
 
459
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
460
    try:
461
        current_inventory_snapshot = query.one()
462
        current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
5966 rajveer 463
 
464
        reservation = CurrentReservationSnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id, source_id = source_id, order_id = order_id).one()
465
        if reservation.reserved == quantity:
466
            reservation.delete()
467
        else:
468
            reservation.reserved -= quantity
5944 mandeep.dh 469
        session.commit()
470
        #**Update item availability cache**#
5978 rajveer 471
        clear_item_availability_cache(item_id)
5944 mandeep.dh 472
        if current_inventory_snapshot.reserved < 0:
473
            item = __get_item_from_master(item_id)
474
            __send_alert_for_negative_reserved(item, current_inventory_snapshot.reserved, get_Warehouse(warehouse_id))
475
        return True
476
    except:
477
        print "Unexpected error:", sys.exc_info()[0]
478
        return False
479
 
5978 rajveer 480
def get_item_availability_for_location(item_id, source_id):
481
    item_availability = ItemAvailabilityCache.get_by(itemId=item_id, sourceId = source_id)
5944 mandeep.dh 482
    if item_availability:
7589 rajveer 483
        return [item_availability.warehouseId, item_availability.expectedDelay, item_availability.billingWarehouseId, item_availability.sellingPrice, item_availability.totalAvailability, item_availability.weight]
5944 mandeep.dh 484
    else:
5978 rajveer 485
        __update_item_availability_cache(item_id, source_id)
486
            ##Check risky status for the source
487
        __check_risky_item(item_id, source_id)
488
        return get_item_availability_for_location(item_id, source_id)
5944 mandeep.dh 489
 
5978 rajveer 490
def clear_item_availability_cache(item_id = None):
491
    if item_id:
492
        ItemAvailabilityCache.query.filter_by(itemId = item_id).delete()
493
    else:
494
        ItemAvailabilityCache.query.delete()
5944 mandeep.dh 495
    session.commit()
496
 
5978 rajveer 497
def __update_item_availability_cache(item_id, source_id):
5944 mandeep.dh 498
    """
8954 vikram.rag 499
    Determines the warehouse that should be used to fulfil an order for the given item.
5944 mandeep.dh 500
    Algorithm explained at https://sites.google.com/a/shop2020.in/virtual-w-h-and-inventory/technical-details
501
 
502
    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.
503
    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.
504
 
505
    if item available at any OUR-GOOD warehouse
506
        // OUR-GOOD warehouses have inventory risk; So, we empty them first! 
507
        // We can start with minimum transfer price criterion but down the line we can also bring in Inventory age 
508
        assign OUR-GOOD warehouse with minimum transfer price
509
    else
510
        if Preferred vendor is specified and marked Sticky
511
            // Always purchase from Preferred if its marked sticky
512
            assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
513
        else 
514
            if item available in a THIRDPARTY GOOD/VIRTUAL warehouse
515
                assign THIRDPARTY GOOD/VIRTUAL warehouse where item is available with minimal transfer delay followed by minimum transfer price
516
            else 
517
                // Item not available at any warehouse, OURS or THIRDPARTY
518
                If Preferred vendor is specified
519
                    assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
520
                else
521
                    assign THIRDPARTY GOOD/VIRTUAL warehouse with minimum transfer price
522
 
523
    Returns an ordered list of size 4 with following elements in the given order:
524
    1. Logistics location of the warehouse which was finally picked up to ship the order.
525
    2. Expected delay added by the category manager.
526
    3. Id of the warehouse which was finally picked up.
527
 
528
    Parameters:
529
     - itemId
530
    """
5978 rajveer 531
    item = __get_item_from_source(item_id, source_id)
5944 mandeep.dh 532
    item_pricing = {}
533
    for vendorItemPricing in VendorItemPricing.query.filter_by(item_id=item_id).all():
534
        item_pricing[vendorItemPricing.vendor_id] = vendorItemPricing
535
 
6510 rajveer 536
    ignoredWhs = get_ignored_warehouses(item_id)
537
 
5944 mandeep.dh 538
    warehouses = {}
539
    ourGoodWarehouses = {}
540
    thirdpartyWarehouses = {}
541
    preferredThirdpartyWarehouses = {}
542
    for warehouse in Warehouse.query.all():
7410 amar.kumar 543
        if (warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.BAD] or warehouse.warehouseType == WarehouseType._VALUES_TO_NAMES[WarehouseType.OURS_THIRDPARTY]):
5944 mandeep.dh 544
            continue
545
        warehouses[warehouse.id] = warehouse
546
        if warehouse.warehouseType == WarehouseType._VALUES_TO_NAMES[WarehouseType.OURS]:
547
            if warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
548
                ourGoodWarehouses[warehouse.id] = warehouse
549
        else:
550
            thirdpartyWarehouses[warehouse.id] = warehouse
551
            if item.preferredVendor == warehouse.vendor_id and warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
552
                preferredThirdpartyWarehouses[warehouse.id] = warehouse
553
 
554
    warehouse_retid = -1
555
    total_availability = 0
556
 
6540 rajveer 557
    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(ourGoodWarehouses, ignoredWhs, item_id, item_pricing, False)
5944 mandeep.dh 558
    if warehouse_retid == -1:
559
        if item.preferredVendor and item.isWarehousePreferenceSticky:
6540 rajveer 560
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(preferredThirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 561
            if warehouse_retid == -1:
562
                warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
563
        else:
6540 rajveer 564
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 565
            if warehouse_retid == -1:
566
                if item.preferredVendor:
567
                    warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
568
                else:
6540 rajveer 569
                    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing, True)
5944 mandeep.dh 570
 
571
    warehouse = warehouses[warehouse_retid]
572
    billingWarehouseId = warehouse.billingWarehouseId
573
 
574
    # Fetching billing warehouse of a Good billable warehouse corresponding to the virtual one
575
    if not warehouse.billingWarehouseId:
576
        for w in Warehouse.query.filter_by(vendor_id = warehouse.vendor_id, inventoryType = InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]).all():
577
            if w.billingWarehouseId:
578
                billingWarehouseId = w.billingWarehouseId
579
                break
580
 
581
    expectedDelay = item.expectedDelay 
582
    if expectedDelay is None:
583
        print 'expectedDelay field for this item was Null. Resetting it to 0'
584
        expectedDelay = 0
585
    else:
586
        expectedDelay = int(item.expectedDelay)
587
 
588
    if total_availability <= 0:
8026 amar.kumar 589
        if item.preferredVendor in [1, 5]:
6562 rajveer 590
            expectedDelay = expectedDelay + 3
591
        else:
592
            expectedDelay = expectedDelay + 2
6643 rajveer 593
    else:
594
        if warehouse.transferDelayInHours:
595
            expectedDelay = expectedDelay + warehouse.transferDelayInHours / 24
5944 mandeep.dh 596
 
8491 rajveer 597
    if warehouse.warehouseType == WarehouseType.THIRD_PARTY:
598
        expectedDelay = expectedDelay + __get_vendor_holiday_delay(warehouse.vendor_id, expectedDelay) 
599
 
5963 mandeep.dh 600
    total_availability = 0
601
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
6545 rajveer 602
        if entry.warehouse_id not in ignoredWhs:
603
            total_availability += entry.availability - entry.reserved
5963 mandeep.dh 604
 
5978 rajveer 605
    item_availability_cache = ItemAvailabilityCache.get_by(itemId=item_id, sourceId=source_id)
5944 mandeep.dh 606
    if item_availability_cache is None:
607
        item_availability_cache = ItemAvailabilityCache()
608
        item_availability_cache.itemId = item_id
5978 rajveer 609
        item_availability_cache.sourceId = source_id
5944 mandeep.dh 610
    item_availability_cache.warehouseId = int(warehouse_retid)
611
    item_availability_cache.expectedDelay = expectedDelay
612
    item_availability_cache.billingWarehouseId = billingWarehouseId
613
    item_availability_cache.sellingPrice = item.sellingPrice
614
    item_availability_cache.totalAvailability = total_availability
7589 rajveer 615
    item_availability_cache.weight = 1000*item.weight if item.weight else 300
5944 mandeep.dh 616
    session.commit()
617
 
6540 rajveer 618
def __get_warehouse_with_min_transfer_price(warehouses, ignoredWhs, item_id, item_pricing, ignoreAvailability):
5944 mandeep.dh 619
    warehouse_retid = -1
620
    minTransferPrice = None
621
    total_availability = 0
6013 amar.kumar 622
    availabilityForBillingWarehouses = {}
623
    warehousesAvailability = {}
624
    availability = 0
625
    billing_warehouse_retid = None
5944 mandeep.dh 626
 
627
    if not ignoreAvailability:
628
        for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 629
            entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 630
            entry.held = max(entry.held, 0)
6013 amar.kumar 631
            #if entry.availability > entry.reserved:
8182 amar.kumar 632
            warehousesAvailability[entry.warehouse_id] = [entry.availability, entry.reserved, entry.held] 
5944 mandeep.dh 633
 
6540 rajveer 634
    if len(ignoredWhs) > 0:
635
        for whid in ignoredWhs:
636
            if warehousesAvailability.has_key(whid):
6542 rajveer 637
                warehousesAvailability[whid][0] = 0
6683 rajveer 638
                warehousesAvailability[whid][1] = 0
8182 amar.kumar 639
                warehousesAvailability[whid][2] = 0
6540 rajveer 640
 
5944 mandeep.dh 641
    for warehouse in warehouses.values():
642
        if not ignoreAvailability:
6013 amar.kumar 643
            #TODO Mistake no entry for this warehouse.id in warehouseswithAvailab
644
            if warehouse.id not in warehousesAvailability:
645
                continue
646
            entry = warehousesAvailability[warehouse.id]
647
            if warehouse.billingWarehouseId in availabilityForBillingWarehouses:
648
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
8182 amar.kumar 649
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = availabilityForBillingWarehouses[warehouse.billingWarehouseId] + entry[0] - entry[1] - entry[2]  
5944 mandeep.dh 650
            else:
6013 amar.kumar 651
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
8182 amar.kumar 652
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = entry[0] - entry[1] - entry[2]
653
            if entry[0] <= (entry[1] + entry[2]):
5944 mandeep.dh 654
                continue
8182 amar.kumar 655
            total_availability += entry[0] - entry[1] - entry[2]
5944 mandeep.dh 656
 
657
        # Missing transfer price cases should not impact warehouse assignment
658
        transferPrice = None
659
        if item_pricing.has_key(warehouse.vendor_id):
6778 rajveer 660
            transferPrice = item_pricing[warehouse.vendor_id].nlc
5944 mandeep.dh 661
        if minTransferPrice is None or (transferPrice and minTransferPrice > transferPrice):
662
            warehouse_retid = warehouse.id
6013 amar.kumar 663
            billing_warehouse_retid = warehouse.billingWarehouseId
5944 mandeep.dh 664
            minTransferPrice = transferPrice
6013 amar.kumar 665
 
666
 
667
    if billing_warehouse_retid in availabilityForBillingWarehouses: 
668
        availability = availabilityForBillingWarehouses[billing_warehouse_retid]
669
    else:
670
        availability = total_availability
671
 
672
    return [warehouse_retid, availability]
5944 mandeep.dh 673
 
6540 rajveer 674
def __get_warehouse_with_min_transfer_delay(warehouses, ignoredWhs, item_id, item_pricing):
5944 mandeep.dh 675
    minTransferDelay = None
676
    minTransferDelayWarehouses = {}
677
    total_availability = 0
678
 
679
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 680
        entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 681
        entry.held = max(entry.held, 0)
5944 mandeep.dh 682
        if warehouses.has_key(entry.warehouse_id):
683
            warehouse = warehouses[entry.warehouse_id]
6013 amar.kumar 684
            #if entry.availability > entry.reserved:
6683 rajveer 685
            if entry.warehouse_id not in ignoredWhs:
8182 amar.kumar 686
                total_availability += entry.availability - entry.reserved - entry.held
687
            if entry.availability - entry.reserved - entry.held <= 0:
6780 amar.kumar 688
                continue
6013 amar.kumar 689
            transferDelay = warehouse.transferDelayInHours
690
            if minTransferDelay is None or minTransferDelay >= transferDelay:
691
                if minTransferDelay != transferDelay:
692
                    minTransferDelayWarehouses = {}
693
                minTransferDelayWarehouses[warehouse.id] = warehouse
694
                minTransferDelay = transferDelay
5944 mandeep.dh 695
 
6540 rajveer 696
    return [__get_warehouse_with_min_transfer_price(minTransferDelayWarehouses, ignoredWhs, item_id, item_pricing, False)[0], total_availability]
5944 mandeep.dh 697
 
698
def __get_warehouse_with_max_availability(warehouse_ids, item_id):
699
    warehouse_retid = -1
700
    max_availability = 0
701
    total_availability = 0
702
 
703
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 704
        entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 705
        entry.held = max(entry.held, 0)
5944 mandeep.dh 706
        if entry.warehouse_id in warehouse_ids:
707
            availability = entry.availability - entry.reserved
708
            if availability > max_availability:
709
                warehouse_retid = entry.warehouse_id
710
                max_availability = availability
711
            total_availability += availability
712
 
713
    return [warehouse_retid, total_availability]
714
 
8491 rajveer 715
def __get_vendor_holiday_delay(vendor_id, expectedDelay):
716
    ## If vendor is closed two days continuously
5944 mandeep.dh 717
    holidayDelay = 0
8491 rajveer 718
    currentDate = datetime.date.today()
719
    expectedDate = currentDate + datetime.timedelta(days = expectedDelay)
720
    holidays = VendorHolidays.query.filter(VendorHolidays.vendor_id == vendor_id).filter(VendorHolidays.date.between(currentDate, expectedDate)).all()
721
    if holidays:
722
        holidayDelay = holidayDelay + len(holidays)
5944 mandeep.dh 723
    return holidayDelay 
724
 
725
def get_item_pricing(item_id, vendorId):
726
    '''
727
    if vendor id is -1 then we calculate an average transfer price to be populated
728
    at the time of order creation. This will be later updated with actual transfer price
729
    at the time of billing.
730
    '''
731
    if(vendorId == -1):
6778 rajveer 732
        tp_total = 0
733
        nlc_total = 0
5944 mandeep.dh 734
        try:
735
            item_pricings = []
736
            item = __get_item_from_master(item_id)
737
            if item.preferredVendor is not None:
738
                item_pricing = VendorItemPricing.query.filter_by(item_id=item_id, vendor_id=item.preferredVendor).first()
739
                if item_pricing:
740
                    item_pricings.append(item_pricing)                    
741
            else :
742
                item_pricings = VendorItemPricing.query.filter_by(item_id=item_id).all()
743
            if item_pricings:
744
                for item_pricing in item_pricings:
6778 rajveer 745
                    tp_total += item_pricing.transfer_price
746
                    nlc_total += item_pricing.nlc
747
                tp_avg = tp_total / len(item_pricings)
748
                nlc_avg = nlc_total / len(item_pricings)
749
                item_pricing.transfer_price = tp_avg
750
                item_pricing.nlc = nlc_avg
5944 mandeep.dh 751
            else:
752
                item_pricing = VendorItemPricing()
753
                item_pricing.transfer_price = item.sellingPrice
6778 rajveer 754
                item_pricing.nlc = item.sellingPrice
5944 mandeep.dh 755
                vendor = Vendor()
756
                vendor.id = vendorId
757
                item_pricing.vendor = vendor
758
                item_pricing.item_id = item_id
759
 
760
            return item_pricing
761
        except:
762
            raise InventoryServiceException(101, "Item pricing not found ")
763
    vendor = Vendor.get_by(id=vendorId)    
764
    try:
765
        item_pricing = VendorItemPricing.query.filter_by(vendor=vendor, item_id=item_id).one()
766
        return item_pricing
767
    except MultipleResultsFound:
768
        raise InventoryServiceException(110, "Multiple pricing information present for Vendor: " + vendor.name + " and Item: " + str(item_id))
769
    except NoResultFound:
770
        raise InventoryServiceException(111, "Missing pricing information for Vendor: " + vendor.name + " and Item: " + str(item_id))
771
 
772
def get_all_item_pricing(item_id):
773
    item_pricing = VendorItemPricing.query.filter_by(item_id=item_id).all()
774
    return item_pricing
775
 
776
def get_item_mappings(item_id):
777
    item_mappings = VendorItemMapping.query.filter_by(item_id=item_id).all()
778
    return item_mappings
779
 
780
def add_vendor_pricing(vendorItemPricing):
781
    if not vendorItemPricing:
782
        raise InventoryServiceException(108, "Bad vendorItemPricing in request")
783
    vendorId = vendorItemPricing.vendorId
784
    itemId = vendorItemPricing.itemId
785
 
786
    try:
787
        vendor = Vendor.query.filter_by(id=vendorId).one()
788
    except:
789
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
790
 
791
    try:
792
        item = __get_item_from_master(itemId)
793
    except:
794
        raise InventoryServiceException(101, "Item not found for itemId " + str(itemId))
795
 
796
    validate_vendor_prices(item, vendorItemPricing)
797
 
798
    try:
799
        ds_vendorItemPricing = VendorItemPricing.query.filter(and_(VendorItemPricing.vendor==vendor, VendorItemPricing.item_id==itemId)).one()
800
    except:
801
        ds_vendorItemPricing = VendorItemPricing()
802
        ds_vendorItemPricing.vendor = vendor
803
        ds_vendorItemPricing.item_id = itemId
804
 
805
    subject = ""
806
    message = ""
807
    if vendorItemPricing.mop:
808
        ds_vendorItemPricing.mop = vendorItemPricing.mop
809
    if vendorItemPricing.dealerPrice:
810
        ds_vendorItemPricing.dealerPrice = vendorItemPricing.dealerPrice
811
    if vendorItemPricing.transferPrice:
812
        if vendorItemPricing.transferPrice != ds_vendorItemPricing.transfer_price:
6617 amar.kumar 813
            client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
814
            item = client.getItem(itemId)
815
            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)
6651 amar.kumar 816
            subject = "Alert:Change in Transfer Price {0} {1} {2} {3} {4}".format(item.brand, item.modelName, item.modelNumber, item.color, itemId)
5944 mandeep.dh 817
        ds_vendorItemPricing.transfer_price = vendorItemPricing.transferPrice
6751 amar.kumar 818
    if vendorItemPricing.nlc:
819
        if vendorItemPricing.nlc != ds_vendorItemPricing.nlc:
820
            client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
821
            item = client.getItem(itemId)
7315 amit.gupta 822
            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)
6751 amar.kumar 823
            subject = "Alert:Change in NLC {0} {1} {2} {3} {4}".format(item.brand, item.modelName, item.modelNumber, item.color, itemId)
824
        ds_vendorItemPricing.nlc = vendorItemPricing.nlc
5944 mandeep.dh 825
 
826
    session.commit()
827
    if subject:
828
        __send_mail(subject, message)
829
    return
830
 
831
def add_vendor_item_mapping(key, vendorItemMapping):
832
    if not vendorItemMapping:
833
        raise InventoryServiceException(108, "Bad vendorItemMapping in request")
834
    vendorId = vendorItemMapping.vendorId
835
    itemId = vendorItemMapping.itemId
836
 
837
    try:
838
        vendor = Vendor.query.filter_by(id=vendorId).one()
839
    except:
840
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
841
 
842
    try:
843
        ds_vendorItemMapping = VendorItemMapping.query.filter(and_(VendorItemMapping.vendor==vendor, VendorItemMapping.item_id==itemId, VendorItemMapping.item_key==key)).one()
844
    except:
845
        ds_vendorItemMapping = VendorItemMapping()
846
        ds_vendorItemMapping.vendor = vendor
847
        ds_vendorItemMapping.item_id = itemId
848
    ds_vendorItemMapping.item_key = vendorItemMapping.itemKey
849
 
850
    session.commit()
851
 
852
    # Marking the missed inventory as not ignored as the catalog dashboard user has updated their key
853
    for missedInventoryUpdate in MissedInventoryUpdate.query.filter_by(itemKey = vendorItemMapping.itemKey).all():
854
        missedInventoryUpdate.isIgnored = 0
855
    session.commit()
856
 
857
    return
858
 
859
def validate_vendor_prices(item, vendorPrices):
860
    if item.mrp != None and item.mrp != "" and vendorPrices.mop != "" and item.mrp <  vendorPrices.mop:
861
        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))
862
        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)))
863
    if vendorPrices.mop != "" and vendorPrices.transferPrice != "" and vendorPrices.transferPrice > vendorPrices.mop:
864
        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))
865
        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)))
866
    return
867
 
868
def get_all_vendors():
869
    return Vendor.query.all()
870
 
871
def get_pending_orders_inventory(vendor_id=1):
872
    """
873
    Returns a list of inventory stock for items for which there are pending orders.
874
    """
875
 
876
    warehouse_ids = [warehouse.id for warehouse in Warehouse.query.filter_by(vendor_id = vendor_id)]
877
    pending_items_inventory = []
878
    if warehouse_ids:
879
        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()
880
    return pending_items_inventory
881
 
7149 amar.kumar 882
def get_billable_inventory_and_pending_orders():
883
    """
884
    Returns a list of inventory Availability and Reserved Count for items which either have real inventory
885
    or have pending orders.
886
    """
887
 
888
    warehouse_ids = [warehouse.id for warehouse in Warehouse.query.filter(Warehouse.isAvailabilityMonitored == 1).filter(or_(Warehouse.inventoryType == 'GOOD', Warehouse.warehouseType == 'OURS'))]
889
    items_inventory = []
890
    reserved_items_inventory = []
891
    available_items_inventory = []
892
    if warehouse_ids:
893
        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()
894
        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()
895
 
896
    items_inventory.extend(reserved_items_inventory)
897
    items_inventory.extend(available_items_inventory)
898
    return items_inventory
899
 
900
 
5944 mandeep.dh 901
def close_session():
902
    if session.is_active:
903
        print "session is active. closing it."
904
        session.close()
905
 
906
def is_alive():
907
    try:
908
        session.query(Vendor.id).limit(1).one()
909
        return True
910
    except:
911
        return False
912
 
913
def add_vendor(vendor):
914
    if not vendor:
915
        raise InventoryServiceException(108, "Bad vendor")
916
    if get_vendor(vendor.id):
917
        #vendor is already present.
918
        raise InventoryServiceException(101, "Vendor already present")
919
 
920
    ds_vendor = Vendor()
921
    ds_vendor.id = vendor.id
922
    ds_vendor.name = vendor.name
923
    session.commit()
924
    return ds_vendor.id
925
 
926
def add_warehouse_vendor_mapping(warehouse_id, VendorId):
927
    return True
928
 
929
def mark_missed_inventory_updates_as_processed(itemKey, warehouseId):
930
    MissedInventoryUpdate.query.filter_by(itemKey = itemKey, warehouseId = warehouseId).delete()
931
    session.commit()
932
 
933
def get_item_keys_to_be_processed(warehouseId):
934
    return [i.itemKey for i in MissedInventoryUpdate.query.filter_by(warehouseId = warehouseId, isIgnored = 0)]
935
 
936
def reset_availability(itemKey, vendorId, quantity, warehouseId):
937
    vendorItemMapping = VendorItemMapping.get_by(vendor_id = vendorId, item_key = itemKey)
938
    if vendorItemMapping:
939
        itemId = vendorItemMapping.item_id
940
 
941
        if skippedItems.has_key(warehouseId) and itemId in skippedItems[warehouseId]:
942
            quantity = 0
943
 
944
        currentInventorySnapshot = CurrentInventorySnapshot.get_by(item_id = itemId, warehouse_id = warehouseId)
945
        if currentInventorySnapshot:
946
            currentInventorySnapshot.availability = quantity
5978 rajveer 947
            clear_item_availability_cache(itemId) 
5944 mandeep.dh 948
        else:
949
            add_inventory(itemId, warehouseId, quantity)
950
 
951
    else:
952
        raise InventoryServiceException(101, 'VendorMapping not found for: ' + itemKey)
953
    session.commit()
954
 
955
def reset_availability_for_warehouse(warehouseId):
956
    for currentInventorySnapshot in CurrentInventorySnapshot.query.filter_by(warehouse_id=warehouseId).all():
957
        currentInventorySnapshot.availability = 0
5978 rajveer 958
        clear_item_availability_cache(currentInventorySnapshot.item_id) 
5944 mandeep.dh 959
    session.commit()
960
 
7718 amar.kumar 961
def get_our_warehouse_id_for_vendor(vendor_id, billing_warehouse_id):
6467 amar.kumar 962
    try:
7718 amar.kumar 963
        warehouse = Warehouse.query.filter_by(vendor_id = vendor_id, warehouseType = 'OURS', inventoryType = 'GOOD', billingWarehouseId = billing_warehouse_id).first()
6467 amar.kumar 964
        return warehouse.id
965
    except Exception as e:
966
        print e;
7755 amar.kumar 967
        raise InventoryServiceException(101, 'No our warehouse found for vendorId: ' + str(vendor_id))
5944 mandeep.dh 968
 
969
def __send_mail(subject, message):
970
    try:
6029 rajveer 971
        thread = threading.Thread(target=partial(mail, mail_user, mail_password, to_addresses, subject, message))
5944 mandeep.dh 972
        thread.start()
973
    except Exception as ex:
974
        print ex    
975
 
976
def get_shipping_locations():
977
    shippingLocationIds = {}
978
    warehouses = Warehouse.query.all()
979
    for warehouse in warehouses:
980
        if warehouse.shippingWarehouseId:
981
            shippingLocationIds[warehouse.shippingWarehouseId] = 1
982
 
983
    shippingLocations = []
984
    for shippingLocationId in shippingLocationIds:
985
        shippingLocations.append(get_Warehouse(shippingLocationId))
986
 
987
    return shippingLocations
988
 
989
def get_inventory_snapshot(warehouseId):
990
    query = CurrentInventorySnapshot.query
991
 
992
    if warehouseId:
993
        query = query.filter_by(warehouse_id = warehouseId)
994
 
995
    itemInventoryMap = {}
996
    for row in query.all():
997
        if not itemInventoryMap.has_key(row.item_id):
998
            itemInventoryMap[row.item_id] = []
999
 
1000
        itemInventoryMap[row.item_id].append(row)
1001
 
1002
    return itemInventoryMap
1003
 
1004
def update_vendor_string(warehouseId, vendorString):
1005
    warehouse = get_Warehouse(warehouseId)
1006
    warehouse.vendorString = vendorString
1007
    session.commit()
1008
 
1009
def __get_item_from_master(item_id):
1010
    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
5978 rajveer 1011
    return client.getItem(item_id)
1012
 
1013
def __check_risky_item(item_id, source_id):
1014
    ## We should get the list of strings which will identify to the catalog servers
1015
    if source_id == 1:
1016
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1017
        client.validateRiskyStatus(item_id)
1018
    if source_id == 2:
1019
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
1020
        client.validateRiskyStatus(item_id)
1021
 
1022
def __get_item_from_source(item_id, source_id):
1023
    if source_id == 1:
1024
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1025
        return client.getItem(item_id)
1026
    if source_id == 2:
1027
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
6531 vikram.rag 1028
        return client.getItem(item_id)
1029
 
1030
def get_monitored_warehouses_for_vendors(vendorIds):
1031
    w = []
1032
    for wh in Warehouse.query.filter_by(isAvailabilityMonitored = 1).all():
1033
        if wh.vendor.id in (vendorIds):
1034
            w.append(to_t_warehouse(wh).id)
1035
    return w
1036
def get_ignored_warehouseids_and_itemids():
1037
    iw = []
1038
    for i in IgnoredInventoryUpdateItems.query.all():
1039
        iw.append(to_t_itemidwarehouseid(i)) 
1040
    return iw
1041
def insert_item_to_ignore_inventory_update_list(item_id,warehouse_id):
1042
    try:
1043
        ds_warehouse=IgnoredInventoryUpdateItems()
1044
        ds_warehouse.item_id=item_id
1045
        ds_warehouse.warehouse_id=warehouse_id
6532 amit.gupta 1046
        clear_item_availability_cache(item_id)
6531 vikram.rag 1047
        session.commit()
1048
        return True
1049
    except:
1050
        return False       
1051
def delete_item_from_ignore_inventory_update_list(item_id,warehouse_id):
1052
    try:
1053
        session.query(IgnoredInventoryUpdateItems).filter_by(item_id=item_id,warehouse_id=warehouse_id).delete()
6532 amit.gupta 1054
        clear_item_availability_cache(item_id)
6531 vikram.rag 1055
        session.commit()
1056
        return True
1057
    except:
1058
        return False           
1059
 
1060
def get_all_ignored_inventoryupdate_items_count():
1061
    return  session.query(func.count(distinct(IgnoredInventoryUpdateItems.item_id))).scalar()
1062
 
1063
def get_ignored_inventoryupdate_itemids(offset=0,limit=None):
1064
    itemIds = session.query(distinct(IgnoredInventoryUpdateItems.item_id))
1065
    '''if limit is not None:
1066
        itemIds = itemIds.limit(limit)'''
1067
    print itemIds.all()
1068
    return [id for (id, ) in itemIds.all()]
6821 amar.kumar 1069
 
1070
def update_item_stock_purchase_params(item_id, numOfDaysStock, minStockLevel):
1071
    if numOfDaysStock is None or minStockLevel is None:
1072
        raise InventoryServiceException(108, "Bad params : numOfDaysStock = " + str(numOfDaysStock) + "minStockLevel = " + str(minStockLevel))
1073
    itemStockPurchaseParams = ItemStockPurchaseParams.query.filter_by(item_id = item_id).first()
1074
    if itemStockPurchaseParams is None:
1075
        itemStockPurchaseParams = ItemStockPurchaseParams()
1076
    itemStockPurchaseParams.item_id = item_id
1077
    itemStockPurchaseParams.numOfDaysStock = numOfDaysStock
1078
    itemStockPurchaseParams.minStockLevel = minStockLevel
1079
    session.commit()
1080
 
1081
def get_item_stock_purchase_params(item_id):
1082
    return ItemStockPurchaseParams.query.filter_by(item_id = item_id).first()
1083
 
1084
def add_oos_status_for_item(oosStatusMap, date):
1085
 
1086
    oosDate = to_py_date(date)
1087
    oosDate.replace(second=0, microsecond=0)
1088
 
1089
    cartAdditionStartDate = oosDate - datetime.timedelta(days = 1)
1090
 
1091
    client = TransactionClient().get_client()
1092
 
1093
    #Gets physical orders in the last day
1094
    orders = client.getPhysicalOrders(to_java_date(cartAdditionStartDate), to_java_date(oosDate))
8019 amar.kumar 1095
    rtoOrders = client.getAllOrders([20], 0, 0, 0)
9665 rajveer 1096
    orderCountByItemIdSourceId = {}
1097
    rtoOrderCountByItemIdSourceId = {}
1098
 
6821 amar.kumar 1099
    for order in orders:
9665 rajveer 1100
        if not orderCountByItemIdSourceId.has_key(order.lineitems[0].item_id):
1101
            orderCountByItemIdSourceId[order.lineitems[0].item_id] = {}
1102
 
1103
        if orderCountByItemIdSourceId[order.lineitems[0].item_id].has_key(order.source):
1104
            orderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = order.source[order.lineitems[0].item_id][order.source] + 1
6821 amar.kumar 1105
        else:
9665 rajveer 1106
            orderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = 1
1107
 
8019 amar.kumar 1108
 
1109
    for order in rtoOrders:
9665 rajveer 1110
        if not rtoOrderCountByItemIdSourceId.has_key(order.lineitems[0].item_id):
1111
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id] = {}
1112
 
1113
        if rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id].has_key(order.source):
1114
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] + 1 
8019 amar.kumar 1115
        else:
9665 rajveer 1116
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = 1
1117
 
1118
 
6821 amar.kumar 1119
    for itemId, status in oosStatusMap.iteritems():
9665 rajveer 1120
        total_order_count = 0 
1121
        total_rto_count = 0 
1122
        for sid in (1,3,6,7,8):
1123
            if OOSStatus.query.filter_by(item_id = itemId, date = oosDate, sourceId = sid).first() is None:
1124
                oosStatus = OOSStatus()
1125
                oosStatus.item_id = itemId
1126
                oosStatus.date = oosDate
1127
                oosStatus.is_oos = status
1128
                oosStatus.sourceId  = sid
1129
                order_count = 0
1130
                rto_count = 0
1131
                if status == False:
1132
                    if orderCountByItemIdSourceId.has_key(itemId) and orderCountByItemIdSourceId[itemId].has_key(sid):
1133
                        order_count = orderCountByItemIdSourceId[itemId][sid]
1134
                if rtoOrderCountByItemIdSourceId.has_key(itemId) and rtoOrderCountByItemIdSourceId[itemId].has_key(sid):
1135
                        rto_count = rtoOrderCountByItemIdSourceId[itemId][sid]
1136
                oosStatus.num_orders = order_count
1137
                oosStatus.rto_orders = rto_count
1138
                total_order_count = total_order_count + order_count
1139
                total_rto_count = total_rto_count + rto_count
1140
            else:
1141
                print "OOS Status already exists for ItemID:"+str(itemId) " and SourceID " + str(sid) 
1142
 
1143
        if OOSStatus.query.filter_by(item_id = itemId, date = oosDate, sourceId = 0).first() is None:
6821 amar.kumar 1144
            oosStatus = OOSStatus()
1145
            oosStatus.item_id = itemId
1146
            oosStatus.date = oosDate
6832 amar.kumar 1147
            oosStatus.is_oos = status
9665 rajveer 1148
            oosStatus.sourceId  = 0
1149
            oosStatus.num_orders = total_order_count
1150
            oosStatus.rto_orders = total_rto_count
6821 amar.kumar 1151
        else:
9665 rajveer 1152
            print "OOS Status already exists for ItemID:"+str(itemId) " and SourceID " + str(sid)
1153
    session.commit()
6821 amar.kumar 1154
 
9665 rajveer 1155
def get_oos_statuses_for_x_days_for_item(itemId, sourceId, days):
6832 amar.kumar 1156
    timestamp = datetime.datetime.now()
9640 amar.kumar 1157
    timestamp = timestamp - datetime.timedelta(days = days)
9665 rajveer 1158
    return OOSStatus.query.filter_by(item_id = itemId).filter_by(sourceId = sourceId).filter(OOSStatus.date > timestamp).all()
6857 amar.kumar 1159
 
1160
def get_non_zero_item_stock_purchase_params():
7281 kshitij.so 1161
    return ItemStockPurchaseParams.query.filter(or_("numOfDaysStock!=0","minStockLevel!=0"))
1162
 
7972 amar.kumar 1163
def get_last_n_day_sale_for_item(itemId, numberOfDays):
1164
    lastNdaySale = ""
1165
    oosStatuses = get_oos_statuses_for_x_days_for_item(itemId, numberOfDays)
1166
    for oosStatus in oosStatuses:
1167
        if oosStatus.is_oos == True:
1168
            lastNdaySale +="X-"
1169
        else:
1170
            lastNdaySale +=str(oosStatus.num_orders) + "-"
1171
    return lastNdaySale[:-1] 
1172
 
7281 kshitij.so 1173
def get_warehouse_name(warehouseId):
1174
    row = Warehouse.get_by(id = warehouseId)
1175
    return row.displayName
1176
 
1177
def get_amazon_inventory_for_item(amazonItemId):
1178
    inventory = AmazonInventorySnapshot.get_by(item_id=amazonItemId)
1179
    return inventory
1180
 
1181
def get_all_amazon_inventory():
1182
    return session.query(AmazonInventorySnapshot).all()
1183
 
1184
def add_or_update_amazon_inventory_for_item(amazoninventorysnapshot):
1185
    inventory = AmazonInventorySnapshot.get_by(item_id = amazoninventorysnapshot.item_id)
1186
    if inventory is None:
1187
        amazon_inventory = AmazonInventorySnapshot()
1188
        amazon_inventory.item_id = amazoninventorysnapshot.item_id
1189
        amazon_inventory.availability = amazoninventorysnapshot.availability
1190
        amazon_inventory.reserved = amazoninventorysnapshot.reserved
1191
    else:
1192
        inventory.availability = amazoninventorysnapshot.availability
1193
        inventory.reserved = amazoninventorysnapshot.reserved
1194
    session.commit()
1195
 
8182 amar.kumar 1196
def add_update_hold_inventory(itemId, warehouseId, holdQuantity, source):
8197 amar.kumar 1197
    hold_inventory_detail = HoldInventoryDetail.get_by(item_id = itemId, warehouse_id=warehouseId, source = source)
1198
    if  hold_inventory_detail is None:
8182 amar.kumar 1199
        diffTobeAddedInCIS = holdQuantity
1200
        hold_inventory_detail = HoldInventoryDetail()
1201
        hold_inventory_detail.item_id = itemId 
1202
        hold_inventory_detail.warehouse_id = warehouseId 
1203
        hold_inventory_detail.held = holdQuantity 
1204
        hold_inventory_detail.source = source
1205
    else:
8497 amar.kumar 1206
        diffTobeAddedInCIS = holdQuantity - hold_inventory_detail.held
8182 amar.kumar 1207
        hold_inventory_detail.held = holdQuantity
1208
 
1209
    current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
1210
    if not current_inventory_snapshot:
1211
        current_inventory_snapshot = CurrentInventorySnapshot()
1212
        current_inventory_snapshot.item_id = itemId
1213
        current_inventory_snapshot.warehouse_id = warehouseId
1214
        current_inventory_snapshot.availability = 0
1215
        current_inventory_snapshot.reserved = 0
1216
        current_inventory_snapshot.held = 0
1217
    current_inventory_snapshot.held = current_inventory_snapshot.held + diffTobeAddedInCIS
1218
    session.commit()
1219
    #**Update item availability cache**#
1220
    clear_item_availability_cache(itemId)
8282 kshitij.so 1221
 
1222
def add_or_update_amazon_fba_inventory(amazonfbainventorysnapshot):
1223
    inventory = AmazonFbaInventorySnapshot.get_by(item_id = amazonfbainventorysnapshot.item_id)
1224
    if inventory is None:
1225
        amazon_fba_inventory = AmazonFbaInventorySnapshot()
1226
        amazon_fba_inventory.item_id = amazonfbainventorysnapshot.item_id
1227
        amazon_fba_inventory.availability = amazonfbainventorysnapshot.availability
1228
    else:
1229
        inventory.availability = amazonfbainventorysnapshot.availability
1230
    session.commit()
1231
 
1232
 
1233
def get_amazon_fba_inventory(itemId):
1234
    row = AmazonFbaInventorySnapshot.get_by(item_id=itemId)
8621 kshitij.so 1235
    if row is None:
1236
        return 0
1237
    else:
1238
        return row.availability
8282 kshitij.so 1239
 
8363 vikram.rag 1240
def get_all_amazon_fba_inventory():
1241
    return AmazonFbaInventorySnapshot.query.all() 
1242
 
1243
def get_oursgood_warehouseids_for_location(state_id):
1244
    warehouseId=[]
1245
    x= session.query(Warehouse.id).filter(Warehouse.id==Warehouse.billingWarehouseId).filter(Warehouse.warehouseType=='OURS').filter(Warehouse.state_id==1).all()
1246
    for id in x:
1247
        warehouseId.append(id[0])
1248
    return session.query(Warehouse.id).filter(Warehouse.inventoryType=='GOOD').filter(Warehouse.warehouseType=='OURS').filter(Warehouse.billingWarehouseId.in_(warehouseId)).all()
8954 vikram.rag 1249
 
1250
def get_holdinventorydetail_forItem_forWarehouseId_exceptsource(item_id,warehouse_id,source):
1251
    holddetails = HoldInventoryDetail.query.filter(HoldInventoryDetail.item_id == item_id).all()
1252
    print holddetails
1253
    hold = 0
1254
    for holddetail in holddetails:
1255
        if holddetail.source !=source and holddetail.warehouse_id == warehouse_id:
1256
            hold = hold + holddetail.held
9404 vikram.rag 1257
    return hold
1258
 
1259
def get_snapdeal_inventory_for_item(id):
1260
    print SnapdealInventorySnapshot.get_by(item_id = id)
1261
    return SnapdealInventorySnapshot.get_by(item_id = id)
1262
 
1263
def add_or_update_snapdeal_inventor_for_item(snapdealinventoryitem):
1264
    snapdeal_inventory_item = SnapdealInventorySnapshot.get_by(item_id = snapdealinventoryitem.item_id)
1265
    if snapdeal_inventory_item is None:
1266
        snapdeal_inventory_item = SnapdealInventorySnapshot()
1267
        snapdeal_inventory_item.item_id = snapdealinventoryitem.item_id
1268
        snapdeal_inventory_item.availability = snapdealinventoryitem.availability
9495 vikram.rag 1269
        snapdeal_inventory_item.pendingOrders = snapdealinventoryitem.pendingOrders
9404 vikram.rag 1270
        snapdeal_inventory_item.lastUpdatedOnSnapdeal = to_py_date(snapdealinventoryitem.lastUpdatedOnSnapdeal)
1271
    else:
1272
        snapdeal_inventory_item.availability = snapdealinventoryitem.availability
9495 vikram.rag 1273
        snapdeal_inventory_item.pendingOrders = snapdealinventoryitem.pendingOrders
9404 vikram.rag 1274
        snapdeal_inventory_item.lastUpdatedOnSnapdeal = to_py_date(snapdealinventoryitem.lastUpdatedOnSnapdeal)
1275
    session.commit()
8954 vikram.rag 1276
 
9404 vikram.rag 1277
def get_nlc_for_warehouse(warehouse_id,itemid):
1278
    warehouse = Warehouse.get_by(id=warehouse_id)
1279
    if warehouse is None:
1280
        return 0
1281
    vendoritempricing = VendorItemPricing.query.filter_by(item_id=itemid, vendor_id=warehouse.vendor_id).first()
1282
    '''vendoritempricing = VendorItemPricing.get_by(id=warehouse.vendor_id,item_id=itemid)'''
1283
    if vendoritempricing is None:
1284
        return 0
9456 vikram.rag 1285
    return vendoritempricing.nlc
1286
 
9495 vikram.rag 1287
def get_snapdeal_inventory_snapshot():
9640 amar.kumar 1288
    return SnapdealInventorySnapshot.query.all()
1289
def get_held_inventory_map_for_item(itemId, warehouseId):
1290
    heldInventoryMap = {}
1291
    holdInventories = HoldInventoryDetail.query.filter_by(item_id= itemId, warehouse_id = warehouseId).all()
1292
    for holdInventory in holdInventories:
1293
        heldInventoryMap[holdInventory.source] = holdInventory.held
1294
    return heldInventoryMap 
1295