Subversion Repositories SmartDukaan

Rev

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