Subversion Repositories SmartDukaan

Rev

Rev 9758 | Rev 9762 | 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()
9694 amar.kumar 364
            if holdInventoryDetail is None or holdInventoryDetail.held<=0:
365
                holdInventoryDetails = HoldInventoryDetail.query.filter_by(item_id = item_id, source = order.source).all()
366
                if holdInventoryDetails:
367
                    for hID in holdInventoryDetails:
368
                        if hID.held>0:
369
                            holdInventoryDetail = hID
9574 amar.kumar 370
            if holdInventoryDetail is not None and holdInventoryDetail.held>0:
371
                previousHeld = holdInventoryDetail.held
372
                holdInventoryDetail.held = max(0, holdInventoryDetail.held -quantity)
373
                diff = previousHeld-holdInventoryDetail.held 
374
                current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=item_id, warehouse_id=warehouse_id)
375
                if current_inventory_snapshot is not None:
376
                    current_inventory_snapshot.held = max(0, current_inventory_snapshot.held - diff)
377
                session.commit()
8182 amar.kumar 378
    except:
379
        print "Unable to release hold Inventory for item_id " + str(item_id) + " warehouse_id " + str(warehouse_id) + " source " + str(source_id)
8720 amar.kumar 380
    #session.commit()
5944 mandeep.dh 381
    #**Update item availability cache**#
5978 rajveer 382
    clear_item_availability_cache(item_id)
5944 mandeep.dh 383
    return True
384
 
7968 amar.kumar 385
def update_reservation_for_order(item_id, warehouse_id, source_id, order_id, created_timestamp, promised_shipping_timestamp, quantity):    
386
    if not warehouse_id:
387
        raise InventoryServiceException(101, "bad warehouse_id")
388
    warehouse = get_Warehouse(warehouse_id)
389
    item_pricing = get_item_pricing(item_id, warehouse.vendor.id)
390
    if not item_pricing:
391
        raise InventoryServiceException(101, "No Pricing Info found for vendor and Item")
392
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
393
    try:
394
        new_current_inventory_snapshot = query.one()
395
    except:
396
        new_current_inventory_snapshot = CurrentInventorySnapshot()
397
        new_current_inventory_snapshot.warehouse_id = warehouse_id
398
        new_current_inventory_snapshot.item_id = item_id
399
        new_current_inventory_snapshot.availability = 0
400
        new_current_inventory_snapshot.reserved = 0
401
 
402
    new_current_inventory_snapshot.reserved = new_current_inventory_snapshot.reserved + quantity
403
 
404
    new_reservation = CurrentReservationSnapshot()
405
    new_reservation.item_id = item_id
406
    new_reservation.warehouse_id = warehouse_id
407
    new_reservation.source_id = source_id
408
    new_reservation.order_id = order_id
409
    new_reservation.created_timestamp = to_py_date(created_timestamp)
410
    new_reservation.promised_shipping_timestamp = to_py_date(promised_shipping_timestamp)
411
    new_reservation.reserved = quantity
412
 
8182 amar.kumar 413
    try:
414
        order_client = TransactionClient().get_client()
415
        order = order_client.getOrder(order_id)
9574 amar.kumar 416
        if order.source:
417
            holdInventoryDetail = HoldInventoryDetail.query.filter_by(item_id = item_id, warehouse_id = warehouse_id, source = order.source).first()
9694 amar.kumar 418
            if holdInventoryDetail is None or holdInventoryDetail.held<=0:
419
                holdInventoryDetails = HoldInventoryDetail.query.filter_by(item_id = item_id, source = order.source).all()
420
                if holdInventoryDetails:
421
                    for hID in holdInventoryDetails:
422
                        if hID.held>0:
423
                            holdInventoryDetail = hID
9574 amar.kumar 424
            if holdInventoryDetail is not None and holdInventoryDetail.held>0:
425
                previousHeld = holdInventoryDetail.held
426
                holdInventoryDetail.held = max(0, holdInventoryDetail.held -quantity)
427
                diff = previousHeld-holdInventoryDetail.held 
428
                current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=item_id, warehouse_id=warehouse_id)
429
                if current_inventory_snapshot is not None:
430
                    current_inventory_snapshot.held = max(0, current_inventory_snapshot.held - diff)
431
                session.commit()
8182 amar.kumar 432
    except:
433
        print "Unable to release hold Inventory for item_id " + str(item_id) + " warehouse_id " + str(warehouse_id) + " source " + str(source_id)
434
 
7968 amar.kumar 435
    order_client = TransactionClient().get_client()
436
    order = order_client.getOrder(order_id)
437
    for lineitem in order.lineitems:
438
        query = CurrentInventorySnapshot.query.filter_by(warehouse_id = order.fulfilmentWarehouseId, item_id = lineitem.item_id)
439
        try:
440
            current_inventory_snapshot = query.one()
441
            current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
442
 
443
            reservation = CurrentReservationSnapshot.query.filter_by(warehouse_id = order.fulfilmentWarehouseId, item_id = lineitem.item_id, source_id = source_id, order_id = order_id).one()
444
            if reservation.reserved == quantity:
445
                reservation.delete()
446
            else:
447
                reservation.reserved -= quantity
448
 
449
            clear_item_availability_cache(lineitem.item_id)
450
            session.commit()
451
            try:
452
                if current_inventory_snapshot.reserved < 0:
453
                    item = __get_item_from_master(lineitem.item_id)
454
                    __send_alert_for_negative_reserved(item, current_inventory_snapshot.reserved, get_Warehouse(order.fulfilmentWarehouseId))
455
            except:
8182 amar.kumar 456
                print "Error in sending negative reserved alert:", sys.exc_info()[0]
7968 amar.kumar 457
                return False
458
        except:
459
            print "Error in reducing reservation for item:", sys.exc_info()[0]
460
            return False
461
    session.commit()
462
    #**Update item availability cache**#
463
    clear_item_availability_cache(item_id)
464
    return True
465
 
466
 
5966 rajveer 467
def reduce_reservation_count(item_id, warehouse_id, source_id, order_id, quantity):
5944 mandeep.dh 468
    if not warehouse_id:
469
        raise InventoryServiceException(101, "bad warehouse_id")
470
 
471
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
472
    try:
473
        current_inventory_snapshot = query.one()
474
        current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
5966 rajveer 475
 
476
        reservation = CurrentReservationSnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id, source_id = source_id, order_id = order_id).one()
477
        if reservation.reserved == quantity:
478
            reservation.delete()
479
        else:
480
            reservation.reserved -= quantity
5944 mandeep.dh 481
        session.commit()
482
        #**Update item availability cache**#
5978 rajveer 483
        clear_item_availability_cache(item_id)
5944 mandeep.dh 484
        if current_inventory_snapshot.reserved < 0:
485
            item = __get_item_from_master(item_id)
486
            __send_alert_for_negative_reserved(item, current_inventory_snapshot.reserved, get_Warehouse(warehouse_id))
487
        return True
488
    except:
489
        print "Unexpected error:", sys.exc_info()[0]
490
        return False
491
 
5978 rajveer 492
def get_item_availability_for_location(item_id, source_id):
493
    item_availability = ItemAvailabilityCache.get_by(itemId=item_id, sourceId = source_id)
5944 mandeep.dh 494
    if item_availability:
7589 rajveer 495
        return [item_availability.warehouseId, item_availability.expectedDelay, item_availability.billingWarehouseId, item_availability.sellingPrice, item_availability.totalAvailability, item_availability.weight]
5944 mandeep.dh 496
    else:
5978 rajveer 497
        __update_item_availability_cache(item_id, source_id)
498
            ##Check risky status for the source
499
        __check_risky_item(item_id, source_id)
500
        return get_item_availability_for_location(item_id, source_id)
5944 mandeep.dh 501
 
5978 rajveer 502
def clear_item_availability_cache(item_id = None):
503
    if item_id:
504
        ItemAvailabilityCache.query.filter_by(itemId = item_id).delete()
505
    else:
506
        ItemAvailabilityCache.query.delete()
5944 mandeep.dh 507
    session.commit()
508
 
5978 rajveer 509
def __update_item_availability_cache(item_id, source_id):
5944 mandeep.dh 510
    """
8954 vikram.rag 511
    Determines the warehouse that should be used to fulfil an order for the given item.
5944 mandeep.dh 512
    Algorithm explained at https://sites.google.com/a/shop2020.in/virtual-w-h-and-inventory/technical-details
513
 
514
    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.
515
    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.
516
 
517
    if item available at any OUR-GOOD warehouse
518
        // OUR-GOOD warehouses have inventory risk; So, we empty them first! 
519
        // We can start with minimum transfer price criterion but down the line we can also bring in Inventory age 
520
        assign OUR-GOOD warehouse with minimum transfer price
521
    else
522
        if Preferred vendor is specified and marked Sticky
523
            // Always purchase from Preferred if its marked sticky
524
            assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
525
        else 
526
            if item available in a THIRDPARTY GOOD/VIRTUAL warehouse
527
                assign THIRDPARTY GOOD/VIRTUAL warehouse where item is available with minimal transfer delay followed by minimum transfer price
528
            else 
529
                // Item not available at any warehouse, OURS or THIRDPARTY
530
                If Preferred vendor is specified
531
                    assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
532
                else
533
                    assign THIRDPARTY GOOD/VIRTUAL warehouse with minimum transfer price
534
 
535
    Returns an ordered list of size 4 with following elements in the given order:
536
    1. Logistics location of the warehouse which was finally picked up to ship the order.
537
    2. Expected delay added by the category manager.
538
    3. Id of the warehouse which was finally picked up.
539
 
540
    Parameters:
541
     - itemId
542
    """
5978 rajveer 543
    item = __get_item_from_source(item_id, source_id)
5944 mandeep.dh 544
    item_pricing = {}
545
    for vendorItemPricing in VendorItemPricing.query.filter_by(item_id=item_id).all():
546
        item_pricing[vendorItemPricing.vendor_id] = vendorItemPricing
547
 
6510 rajveer 548
    ignoredWhs = get_ignored_warehouses(item_id)
549
 
5944 mandeep.dh 550
    warehouses = {}
551
    ourGoodWarehouses = {}
552
    thirdpartyWarehouses = {}
553
    preferredThirdpartyWarehouses = {}
554
    for warehouse in Warehouse.query.all():
7410 amar.kumar 555
        if (warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.BAD] or warehouse.warehouseType == WarehouseType._VALUES_TO_NAMES[WarehouseType.OURS_THIRDPARTY]):
5944 mandeep.dh 556
            continue
557
        warehouses[warehouse.id] = warehouse
558
        if warehouse.warehouseType == WarehouseType._VALUES_TO_NAMES[WarehouseType.OURS]:
559
            if warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
560
                ourGoodWarehouses[warehouse.id] = warehouse
561
        else:
562
            thirdpartyWarehouses[warehouse.id] = warehouse
563
            if item.preferredVendor == warehouse.vendor_id and warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
564
                preferredThirdpartyWarehouses[warehouse.id] = warehouse
565
 
566
    warehouse_retid = -1
567
    total_availability = 0
568
 
6540 rajveer 569
    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(ourGoodWarehouses, ignoredWhs, item_id, item_pricing, False)
5944 mandeep.dh 570
    if warehouse_retid == -1:
571
        if item.preferredVendor and item.isWarehousePreferenceSticky:
6540 rajveer 572
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(preferredThirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 573
            if warehouse_retid == -1:
574
                warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
575
        else:
6540 rajveer 576
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 577
            if warehouse_retid == -1:
578
                if item.preferredVendor:
579
                    warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
580
                else:
6540 rajveer 581
                    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing, True)
5944 mandeep.dh 582
 
583
    warehouse = warehouses[warehouse_retid]
584
    billingWarehouseId = warehouse.billingWarehouseId
585
 
586
    # Fetching billing warehouse of a Good billable warehouse corresponding to the virtual one
587
    if not warehouse.billingWarehouseId:
588
        for w in Warehouse.query.filter_by(vendor_id = warehouse.vendor_id, inventoryType = InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]).all():
589
            if w.billingWarehouseId:
590
                billingWarehouseId = w.billingWarehouseId
591
                break
592
 
593
    expectedDelay = item.expectedDelay 
594
    if expectedDelay is None:
595
        print 'expectedDelay field for this item was Null. Resetting it to 0'
596
        expectedDelay = 0
597
    else:
598
        expectedDelay = int(item.expectedDelay)
599
 
600
    if total_availability <= 0:
8026 amar.kumar 601
        if item.preferredVendor in [1, 5]:
6562 rajveer 602
            expectedDelay = expectedDelay + 3
603
        else:
604
            expectedDelay = expectedDelay + 2
6643 rajveer 605
    else:
606
        if warehouse.transferDelayInHours:
607
            expectedDelay = expectedDelay + warehouse.transferDelayInHours / 24
5944 mandeep.dh 608
 
8491 rajveer 609
    if warehouse.warehouseType == WarehouseType.THIRD_PARTY:
610
        expectedDelay = expectedDelay + __get_vendor_holiday_delay(warehouse.vendor_id, expectedDelay) 
611
 
5963 mandeep.dh 612
    total_availability = 0
613
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
6545 rajveer 614
        if entry.warehouse_id not in ignoredWhs:
615
            total_availability += entry.availability - entry.reserved
5963 mandeep.dh 616
 
5978 rajveer 617
    item_availability_cache = ItemAvailabilityCache.get_by(itemId=item_id, sourceId=source_id)
5944 mandeep.dh 618
    if item_availability_cache is None:
619
        item_availability_cache = ItemAvailabilityCache()
620
        item_availability_cache.itemId = item_id
5978 rajveer 621
        item_availability_cache.sourceId = source_id
5944 mandeep.dh 622
    item_availability_cache.warehouseId = int(warehouse_retid)
623
    item_availability_cache.expectedDelay = expectedDelay
624
    item_availability_cache.billingWarehouseId = billingWarehouseId
625
    item_availability_cache.sellingPrice = item.sellingPrice
626
    item_availability_cache.totalAvailability = total_availability
7589 rajveer 627
    item_availability_cache.weight = 1000*item.weight if item.weight else 300
5944 mandeep.dh 628
    session.commit()
629
 
6540 rajveer 630
def __get_warehouse_with_min_transfer_price(warehouses, ignoredWhs, item_id, item_pricing, ignoreAvailability):
5944 mandeep.dh 631
    warehouse_retid = -1
632
    minTransferPrice = None
633
    total_availability = 0
6013 amar.kumar 634
    availabilityForBillingWarehouses = {}
635
    warehousesAvailability = {}
636
    availability = 0
637
    billing_warehouse_retid = None
5944 mandeep.dh 638
 
639
    if not ignoreAvailability:
640
        for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 641
            entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 642
            entry.held = max(entry.held, 0)
6013 amar.kumar 643
            #if entry.availability > entry.reserved:
8182 amar.kumar 644
            warehousesAvailability[entry.warehouse_id] = [entry.availability, entry.reserved, entry.held] 
5944 mandeep.dh 645
 
6540 rajveer 646
    if len(ignoredWhs) > 0:
647
        for whid in ignoredWhs:
648
            if warehousesAvailability.has_key(whid):
6542 rajveer 649
                warehousesAvailability[whid][0] = 0
6683 rajveer 650
                warehousesAvailability[whid][1] = 0
8182 amar.kumar 651
                warehousesAvailability[whid][2] = 0
6540 rajveer 652
 
5944 mandeep.dh 653
    for warehouse in warehouses.values():
654
        if not ignoreAvailability:
6013 amar.kumar 655
            #TODO Mistake no entry for this warehouse.id in warehouseswithAvailab
656
            if warehouse.id not in warehousesAvailability:
657
                continue
658
            entry = warehousesAvailability[warehouse.id]
659
            if warehouse.billingWarehouseId in availabilityForBillingWarehouses:
660
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
8182 amar.kumar 661
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = availabilityForBillingWarehouses[warehouse.billingWarehouseId] + entry[0] - entry[1] - entry[2]  
5944 mandeep.dh 662
            else:
6013 amar.kumar 663
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
8182 amar.kumar 664
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = entry[0] - entry[1] - entry[2]
665
            if entry[0] <= (entry[1] + entry[2]):
5944 mandeep.dh 666
                continue
8182 amar.kumar 667
            total_availability += entry[0] - entry[1] - entry[2]
5944 mandeep.dh 668
 
669
        # Missing transfer price cases should not impact warehouse assignment
670
        transferPrice = None
671
        if item_pricing.has_key(warehouse.vendor_id):
6778 rajveer 672
            transferPrice = item_pricing[warehouse.vendor_id].nlc
5944 mandeep.dh 673
        if minTransferPrice is None or (transferPrice and minTransferPrice > transferPrice):
674
            warehouse_retid = warehouse.id
6013 amar.kumar 675
            billing_warehouse_retid = warehouse.billingWarehouseId
5944 mandeep.dh 676
            minTransferPrice = transferPrice
6013 amar.kumar 677
 
678
 
679
    if billing_warehouse_retid in availabilityForBillingWarehouses: 
680
        availability = availabilityForBillingWarehouses[billing_warehouse_retid]
681
    else:
682
        availability = total_availability
683
 
684
    return [warehouse_retid, availability]
5944 mandeep.dh 685
 
6540 rajveer 686
def __get_warehouse_with_min_transfer_delay(warehouses, ignoredWhs, item_id, item_pricing):
5944 mandeep.dh 687
    minTransferDelay = None
688
    minTransferDelayWarehouses = {}
689
    total_availability = 0
690
 
691
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 692
        entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 693
        entry.held = max(entry.held, 0)
5944 mandeep.dh 694
        if warehouses.has_key(entry.warehouse_id):
695
            warehouse = warehouses[entry.warehouse_id]
6013 amar.kumar 696
            #if entry.availability > entry.reserved:
6683 rajveer 697
            if entry.warehouse_id not in ignoredWhs:
8182 amar.kumar 698
                total_availability += entry.availability - entry.reserved - entry.held
699
            if entry.availability - entry.reserved - entry.held <= 0:
6780 amar.kumar 700
                continue
6013 amar.kumar 701
            transferDelay = warehouse.transferDelayInHours
702
            if minTransferDelay is None or minTransferDelay >= transferDelay:
703
                if minTransferDelay != transferDelay:
704
                    minTransferDelayWarehouses = {}
705
                minTransferDelayWarehouses[warehouse.id] = warehouse
706
                minTransferDelay = transferDelay
5944 mandeep.dh 707
 
6540 rajveer 708
    return [__get_warehouse_with_min_transfer_price(minTransferDelayWarehouses, ignoredWhs, item_id, item_pricing, False)[0], total_availability]
5944 mandeep.dh 709
 
710
def __get_warehouse_with_max_availability(warehouse_ids, item_id):
711
    warehouse_retid = -1
712
    max_availability = 0
713
    total_availability = 0
714
 
715
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 716
        entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 717
        entry.held = max(entry.held, 0)
5944 mandeep.dh 718
        if entry.warehouse_id in warehouse_ids:
719
            availability = entry.availability - entry.reserved
720
            if availability > max_availability:
721
                warehouse_retid = entry.warehouse_id
722
                max_availability = availability
723
            total_availability += availability
724
 
725
    return [warehouse_retid, total_availability]
726
 
8491 rajveer 727
def __get_vendor_holiday_delay(vendor_id, expectedDelay):
728
    ## If vendor is closed two days continuously
5944 mandeep.dh 729
    holidayDelay = 0
8491 rajveer 730
    currentDate = datetime.date.today()
731
    expectedDate = currentDate + datetime.timedelta(days = expectedDelay)
732
    holidays = VendorHolidays.query.filter(VendorHolidays.vendor_id == vendor_id).filter(VendorHolidays.date.between(currentDate, expectedDate)).all()
733
    if holidays:
734
        holidayDelay = holidayDelay + len(holidays)
5944 mandeep.dh 735
    return holidayDelay 
736
 
737
def get_item_pricing(item_id, vendorId):
738
    '''
739
    if vendor id is -1 then we calculate an average transfer price to be populated
740
    at the time of order creation. This will be later updated with actual transfer price
741
    at the time of billing.
742
    '''
743
    if(vendorId == -1):
6778 rajveer 744
        tp_total = 0
745
        nlc_total = 0
5944 mandeep.dh 746
        try:
747
            item_pricings = []
748
            item = __get_item_from_master(item_id)
749
            if item.preferredVendor is not None:
750
                item_pricing = VendorItemPricing.query.filter_by(item_id=item_id, vendor_id=item.preferredVendor).first()
751
                if item_pricing:
752
                    item_pricings.append(item_pricing)                    
753
            else :
754
                item_pricings = VendorItemPricing.query.filter_by(item_id=item_id).all()
755
            if item_pricings:
756
                for item_pricing in item_pricings:
6778 rajveer 757
                    tp_total += item_pricing.transfer_price
758
                    nlc_total += item_pricing.nlc
759
                tp_avg = tp_total / len(item_pricings)
760
                nlc_avg = nlc_total / len(item_pricings)
761
                item_pricing.transfer_price = tp_avg
762
                item_pricing.nlc = nlc_avg
5944 mandeep.dh 763
            else:
764
                item_pricing = VendorItemPricing()
765
                item_pricing.transfer_price = item.sellingPrice
6778 rajveer 766
                item_pricing.nlc = item.sellingPrice
5944 mandeep.dh 767
                vendor = Vendor()
768
                vendor.id = vendorId
769
                item_pricing.vendor = vendor
770
                item_pricing.item_id = item_id
771
 
772
            return item_pricing
773
        except:
774
            raise InventoryServiceException(101, "Item pricing not found ")
775
    vendor = Vendor.get_by(id=vendorId)    
776
    try:
777
        item_pricing = VendorItemPricing.query.filter_by(vendor=vendor, item_id=item_id).one()
778
        return item_pricing
779
    except MultipleResultsFound:
780
        raise InventoryServiceException(110, "Multiple pricing information present for Vendor: " + vendor.name + " and Item: " + str(item_id))
781
    except NoResultFound:
782
        raise InventoryServiceException(111, "Missing pricing information for Vendor: " + vendor.name + " and Item: " + str(item_id))
783
 
784
def get_all_item_pricing(item_id):
785
    item_pricing = VendorItemPricing.query.filter_by(item_id=item_id).all()
786
    return item_pricing
787
 
788
def get_item_mappings(item_id):
789
    item_mappings = VendorItemMapping.query.filter_by(item_id=item_id).all()
790
    return item_mappings
791
 
792
def add_vendor_pricing(vendorItemPricing):
793
    if not vendorItemPricing:
794
        raise InventoryServiceException(108, "Bad vendorItemPricing in request")
795
    vendorId = vendorItemPricing.vendorId
796
    itemId = vendorItemPricing.itemId
797
 
798
    try:
799
        vendor = Vendor.query.filter_by(id=vendorId).one()
800
    except:
801
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
802
 
803
    try:
804
        item = __get_item_from_master(itemId)
805
    except:
806
        raise InventoryServiceException(101, "Item not found for itemId " + str(itemId))
807
 
808
    validate_vendor_prices(item, vendorItemPricing)
809
 
810
    try:
811
        ds_vendorItemPricing = VendorItemPricing.query.filter(and_(VendorItemPricing.vendor==vendor, VendorItemPricing.item_id==itemId)).one()
812
    except:
813
        ds_vendorItemPricing = VendorItemPricing()
814
        ds_vendorItemPricing.vendor = vendor
815
        ds_vendorItemPricing.item_id = itemId
816
 
817
    subject = ""
818
    message = ""
819
    if vendorItemPricing.mop:
820
        ds_vendorItemPricing.mop = vendorItemPricing.mop
821
    if vendorItemPricing.dealerPrice:
822
        ds_vendorItemPricing.dealerPrice = vendorItemPricing.dealerPrice
823
    if vendorItemPricing.transferPrice:
824
        if vendorItemPricing.transferPrice != ds_vendorItemPricing.transfer_price:
6617 amar.kumar 825
            client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
826
            item = client.getItem(itemId)
827
            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 828
            subject = "Alert:Change in Transfer Price {0} {1} {2} {3} {4}".format(item.brand, item.modelName, item.modelNumber, item.color, itemId)
5944 mandeep.dh 829
        ds_vendorItemPricing.transfer_price = vendorItemPricing.transferPrice
6751 amar.kumar 830
    if vendorItemPricing.nlc:
831
        if vendorItemPricing.nlc != ds_vendorItemPricing.nlc:
832
            client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
833
            item = client.getItem(itemId)
7315 amit.gupta 834
            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 835
            subject = "Alert:Change in NLC {0} {1} {2} {3} {4}".format(item.brand, item.modelName, item.modelNumber, item.color, itemId)
836
        ds_vendorItemPricing.nlc = vendorItemPricing.nlc
5944 mandeep.dh 837
 
838
    session.commit()
839
    if subject:
840
        __send_mail(subject, message)
841
    return
842
 
843
def add_vendor_item_mapping(key, vendorItemMapping):
844
    if not vendorItemMapping:
845
        raise InventoryServiceException(108, "Bad vendorItemMapping in request")
846
    vendorId = vendorItemMapping.vendorId
847
    itemId = vendorItemMapping.itemId
848
 
849
    try:
850
        vendor = Vendor.query.filter_by(id=vendorId).one()
851
    except:
852
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
853
 
854
    try:
855
        ds_vendorItemMapping = VendorItemMapping.query.filter(and_(VendorItemMapping.vendor==vendor, VendorItemMapping.item_id==itemId, VendorItemMapping.item_key==key)).one()
856
    except:
857
        ds_vendorItemMapping = VendorItemMapping()
858
        ds_vendorItemMapping.vendor = vendor
859
        ds_vendorItemMapping.item_id = itemId
860
    ds_vendorItemMapping.item_key = vendorItemMapping.itemKey
861
 
862
    session.commit()
863
 
864
    # Marking the missed inventory as not ignored as the catalog dashboard user has updated their key
865
    for missedInventoryUpdate in MissedInventoryUpdate.query.filter_by(itemKey = vendorItemMapping.itemKey).all():
866
        missedInventoryUpdate.isIgnored = 0
867
    session.commit()
868
 
869
    return
870
 
871
def validate_vendor_prices(item, vendorPrices):
872
    if item.mrp != None and item.mrp != "" and vendorPrices.mop != "" and item.mrp <  vendorPrices.mop:
873
        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))
874
        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)))
875
    if vendorPrices.mop != "" and vendorPrices.transferPrice != "" and vendorPrices.transferPrice > vendorPrices.mop:
876
        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))
877
        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)))
878
    return
879
 
880
def get_all_vendors():
881
    return Vendor.query.all()
882
 
883
def get_pending_orders_inventory(vendor_id=1):
884
    """
885
    Returns a list of inventory stock for items for which there are pending orders.
886
    """
887
 
888
    warehouse_ids = [warehouse.id for warehouse in Warehouse.query.filter_by(vendor_id = vendor_id)]
889
    pending_items_inventory = []
890
    if warehouse_ids:
891
        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()
892
    return pending_items_inventory
893
 
7149 amar.kumar 894
def get_billable_inventory_and_pending_orders():
895
    """
896
    Returns a list of inventory Availability and Reserved Count for items which either have real inventory
897
    or have pending orders.
898
    """
899
 
900
    warehouse_ids = [warehouse.id for warehouse in Warehouse.query.filter(Warehouse.isAvailabilityMonitored == 1).filter(or_(Warehouse.inventoryType == 'GOOD', Warehouse.warehouseType == 'OURS'))]
901
    items_inventory = []
902
    reserved_items_inventory = []
903
    available_items_inventory = []
904
    if warehouse_ids:
905
        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()
906
        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()
907
 
908
    items_inventory.extend(reserved_items_inventory)
909
    items_inventory.extend(available_items_inventory)
910
    return items_inventory
911
 
912
 
5944 mandeep.dh 913
def close_session():
914
    if session.is_active:
915
        print "session is active. closing it."
916
        session.close()
917
 
918
def is_alive():
919
    try:
920
        session.query(Vendor.id).limit(1).one()
921
        return True
922
    except:
923
        return False
924
 
925
def add_vendor(vendor):
926
    if not vendor:
927
        raise InventoryServiceException(108, "Bad vendor")
928
    if get_vendor(vendor.id):
929
        #vendor is already present.
930
        raise InventoryServiceException(101, "Vendor already present")
931
 
932
    ds_vendor = Vendor()
933
    ds_vendor.id = vendor.id
934
    ds_vendor.name = vendor.name
935
    session.commit()
936
    return ds_vendor.id
937
 
938
def add_warehouse_vendor_mapping(warehouse_id, VendorId):
939
    return True
940
 
941
def mark_missed_inventory_updates_as_processed(itemKey, warehouseId):
942
    MissedInventoryUpdate.query.filter_by(itemKey = itemKey, warehouseId = warehouseId).delete()
943
    session.commit()
944
 
945
def get_item_keys_to_be_processed(warehouseId):
946
    return [i.itemKey for i in MissedInventoryUpdate.query.filter_by(warehouseId = warehouseId, isIgnored = 0)]
947
 
948
def reset_availability(itemKey, vendorId, quantity, warehouseId):
949
    vendorItemMapping = VendorItemMapping.get_by(vendor_id = vendorId, item_key = itemKey)
950
    if vendorItemMapping:
951
        itemId = vendorItemMapping.item_id
952
 
953
        if skippedItems.has_key(warehouseId) and itemId in skippedItems[warehouseId]:
954
            quantity = 0
955
 
956
        currentInventorySnapshot = CurrentInventorySnapshot.get_by(item_id = itemId, warehouse_id = warehouseId)
957
        if currentInventorySnapshot:
958
            currentInventorySnapshot.availability = quantity
5978 rajveer 959
            clear_item_availability_cache(itemId) 
5944 mandeep.dh 960
        else:
961
            add_inventory(itemId, warehouseId, quantity)
962
 
963
    else:
964
        raise InventoryServiceException(101, 'VendorMapping not found for: ' + itemKey)
965
    session.commit()
966
 
967
def reset_availability_for_warehouse(warehouseId):
968
    for currentInventorySnapshot in CurrentInventorySnapshot.query.filter_by(warehouse_id=warehouseId).all():
969
        currentInventorySnapshot.availability = 0
5978 rajveer 970
        clear_item_availability_cache(currentInventorySnapshot.item_id) 
5944 mandeep.dh 971
    session.commit()
972
 
7718 amar.kumar 973
def get_our_warehouse_id_for_vendor(vendor_id, billing_warehouse_id):
6467 amar.kumar 974
    try:
7718 amar.kumar 975
        warehouse = Warehouse.query.filter_by(vendor_id = vendor_id, warehouseType = 'OURS', inventoryType = 'GOOD', billingWarehouseId = billing_warehouse_id).first()
6467 amar.kumar 976
        return warehouse.id
977
    except Exception as e:
978
        print e;
7755 amar.kumar 979
        raise InventoryServiceException(101, 'No our warehouse found for vendorId: ' + str(vendor_id))
5944 mandeep.dh 980
 
981
def __send_mail(subject, message):
982
    try:
6029 rajveer 983
        thread = threading.Thread(target=partial(mail, mail_user, mail_password, to_addresses, subject, message))
5944 mandeep.dh 984
        thread.start()
985
    except Exception as ex:
986
        print ex    
987
 
988
def get_shipping_locations():
989
    shippingLocationIds = {}
990
    warehouses = Warehouse.query.all()
991
    for warehouse in warehouses:
992
        if warehouse.shippingWarehouseId:
993
            shippingLocationIds[warehouse.shippingWarehouseId] = 1
994
 
995
    shippingLocations = []
996
    for shippingLocationId in shippingLocationIds:
997
        shippingLocations.append(get_Warehouse(shippingLocationId))
998
 
999
    return shippingLocations
1000
 
1001
def get_inventory_snapshot(warehouseId):
1002
    query = CurrentInventorySnapshot.query
1003
 
1004
    if warehouseId:
1005
        query = query.filter_by(warehouse_id = warehouseId)
1006
 
1007
    itemInventoryMap = {}
1008
    for row in query.all():
1009
        if not itemInventoryMap.has_key(row.item_id):
1010
            itemInventoryMap[row.item_id] = []
1011
 
1012
        itemInventoryMap[row.item_id].append(row)
1013
 
1014
    return itemInventoryMap
1015
 
1016
def update_vendor_string(warehouseId, vendorString):
1017
    warehouse = get_Warehouse(warehouseId)
1018
    warehouse.vendorString = vendorString
1019
    session.commit()
1020
 
1021
def __get_item_from_master(item_id):
1022
    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
5978 rajveer 1023
    return client.getItem(item_id)
1024
 
1025
def __check_risky_item(item_id, source_id):
1026
    ## We should get the list of strings which will identify to the catalog servers
1027
    if source_id == 1:
1028
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1029
        client.validateRiskyStatus(item_id)
1030
    if source_id == 2:
1031
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
1032
        client.validateRiskyStatus(item_id)
1033
 
1034
def __get_item_from_source(item_id, source_id):
1035
    if source_id == 1:
1036
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1037
        return client.getItem(item_id)
1038
    if source_id == 2:
1039
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
6531 vikram.rag 1040
        return client.getItem(item_id)
1041
 
1042
def get_monitored_warehouses_for_vendors(vendorIds):
1043
    w = []
1044
    for wh in Warehouse.query.filter_by(isAvailabilityMonitored = 1).all():
1045
        if wh.vendor.id in (vendorIds):
1046
            w.append(to_t_warehouse(wh).id)
1047
    return w
1048
def get_ignored_warehouseids_and_itemids():
1049
    iw = []
1050
    for i in IgnoredInventoryUpdateItems.query.all():
1051
        iw.append(to_t_itemidwarehouseid(i)) 
1052
    return iw
1053
def insert_item_to_ignore_inventory_update_list(item_id,warehouse_id):
1054
    try:
1055
        ds_warehouse=IgnoredInventoryUpdateItems()
1056
        ds_warehouse.item_id=item_id
1057
        ds_warehouse.warehouse_id=warehouse_id
6532 amit.gupta 1058
        clear_item_availability_cache(item_id)
6531 vikram.rag 1059
        session.commit()
1060
        return True
1061
    except:
1062
        return False       
1063
def delete_item_from_ignore_inventory_update_list(item_id,warehouse_id):
1064
    try:
1065
        session.query(IgnoredInventoryUpdateItems).filter_by(item_id=item_id,warehouse_id=warehouse_id).delete()
6532 amit.gupta 1066
        clear_item_availability_cache(item_id)
6531 vikram.rag 1067
        session.commit()
1068
        return True
1069
    except:
1070
        return False           
1071
 
1072
def get_all_ignored_inventoryupdate_items_count():
1073
    return  session.query(func.count(distinct(IgnoredInventoryUpdateItems.item_id))).scalar()
1074
 
1075
def get_ignored_inventoryupdate_itemids(offset=0,limit=None):
1076
    itemIds = session.query(distinct(IgnoredInventoryUpdateItems.item_id))
1077
    '''if limit is not None:
1078
        itemIds = itemIds.limit(limit)'''
1079
    print itemIds.all()
1080
    return [id for (id, ) in itemIds.all()]
6821 amar.kumar 1081
 
1082
def update_item_stock_purchase_params(item_id, numOfDaysStock, minStockLevel):
1083
    if numOfDaysStock is None or minStockLevel is None:
1084
        raise InventoryServiceException(108, "Bad params : numOfDaysStock = " + str(numOfDaysStock) + "minStockLevel = " + str(minStockLevel))
1085
    itemStockPurchaseParams = ItemStockPurchaseParams.query.filter_by(item_id = item_id).first()
1086
    if itemStockPurchaseParams is None:
1087
        itemStockPurchaseParams = ItemStockPurchaseParams()
1088
    itemStockPurchaseParams.item_id = item_id
1089
    itemStockPurchaseParams.numOfDaysStock = numOfDaysStock
1090
    itemStockPurchaseParams.minStockLevel = minStockLevel
1091
    session.commit()
1092
 
1093
def get_item_stock_purchase_params(item_id):
1094
    return ItemStockPurchaseParams.query.filter_by(item_id = item_id).first()
1095
 
1096
def add_oos_status_for_item(oosStatusMap, date):
1097
 
1098
    oosDate = to_py_date(date)
1099
    oosDate.replace(second=0, microsecond=0)
1100
 
1101
    cartAdditionStartDate = oosDate - datetime.timedelta(days = 1)
1102
 
1103
    client = TransactionClient().get_client()
1104
 
1105
    #Gets physical orders in the last day
1106
    orders = client.getPhysicalOrders(to_java_date(cartAdditionStartDate), to_java_date(oosDate))
8019 amar.kumar 1107
    rtoOrders = client.getAllOrders([20], 0, 0, 0)
9665 rajveer 1108
    orderCountByItemIdSourceId = {}
1109
    rtoOrderCountByItemIdSourceId = {}
1110
 
6821 amar.kumar 1111
    for order in orders:
9665 rajveer 1112
        if not orderCountByItemIdSourceId.has_key(order.lineitems[0].item_id):
1113
            orderCountByItemIdSourceId[order.lineitems[0].item_id] = {}
1114
 
1115
        if orderCountByItemIdSourceId[order.lineitems[0].item_id].has_key(order.source):
1116
            orderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = order.source[order.lineitems[0].item_id][order.source] + 1
6821 amar.kumar 1117
        else:
9665 rajveer 1118
            orderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = 1
1119
 
8019 amar.kumar 1120
 
1121
    for order in rtoOrders:
9665 rajveer 1122
        if not rtoOrderCountByItemIdSourceId.has_key(order.lineitems[0].item_id):
1123
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id] = {}
1124
 
1125
        if rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id].has_key(order.source):
1126
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] + 1 
8019 amar.kumar 1127
        else:
9665 rajveer 1128
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = 1
1129
 
1130
 
6821 amar.kumar 1131
    for itemId, status in oosStatusMap.iteritems():
9665 rajveer 1132
        total_order_count = 0 
1133
        total_rto_count = 0 
1134
        for sid in (1,3,6,7,8):
1135
            if OOSStatus.query.filter_by(item_id = itemId, date = oosDate, sourceId = sid).first() is None:
1136
                oosStatus = OOSStatus()
1137
                oosStatus.item_id = itemId
1138
                oosStatus.date = oosDate
1139
                oosStatus.is_oos = status
1140
                oosStatus.sourceId  = sid
1141
                order_count = 0
1142
                rto_count = 0
9666 rajveer 1143
                if orderCountByItemIdSourceId.has_key(itemId) and orderCountByItemIdSourceId[itemId].has_key(sid):
1144
                    order_count = orderCountByItemIdSourceId[itemId][sid]
9665 rajveer 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
                if status == True and order_count > 0:
1150
                    status = False
9665 rajveer 1151
                total_order_count = total_order_count + order_count
1152
                total_rto_count = total_rto_count + rto_count
1153
            else:
9758 amit.gupta 1154
                print "OOS Status already exists for ItemID:"+str(itemId) + " and SourceID " + str(sid) 
9665 rajveer 1155
 
1156
        if OOSStatus.query.filter_by(item_id = itemId, date = oosDate, sourceId = 0).first() is None:
6821 amar.kumar 1157
            oosStatus = OOSStatus()
1158
            oosStatus.item_id = itemId
1159
            oosStatus.date = oosDate
9665 rajveer 1160
            oosStatus.sourceId  = 0
1161
            oosStatus.num_orders = total_order_count
1162
            oosStatus.rto_orders = total_rto_count
9666 rajveer 1163
            if status == True and total_order_count > 0:
1164
                status = False
1165
            oosStatus.is_oos = status
6821 amar.kumar 1166
        else:
9758 amit.gupta 1167
            print "OOS Status already exists for ItemID:"+str(itemId) + " and SourceID " + str(sid)
9665 rajveer 1168
    session.commit()
6821 amar.kumar 1169
 
9665 rajveer 1170
def get_oos_statuses_for_x_days_for_item(itemId, sourceId, days):
6832 amar.kumar 1171
    timestamp = datetime.datetime.now()
9640 amar.kumar 1172
    timestamp = timestamp - datetime.timedelta(days = days)
9665 rajveer 1173
    return OOSStatus.query.filter_by(item_id = itemId).filter_by(sourceId = sourceId).filter(OOSStatus.date > timestamp).all()
6857 amar.kumar 1174
 
1175
def get_non_zero_item_stock_purchase_params():
7281 kshitij.so 1176
    return ItemStockPurchaseParams.query.filter(or_("numOfDaysStock!=0","minStockLevel!=0"))
1177
 
7972 amar.kumar 1178
def get_last_n_day_sale_for_item(itemId, numberOfDays):
1179
    lastNdaySale = ""
9685 rajveer 1180
    oosStatuses = get_oos_statuses_for_x_days_for_item(itemId, 0, numberOfDays)
7972 amar.kumar 1181
    for oosStatus in oosStatuses:
1182
        if oosStatus.is_oos == True:
1183
            lastNdaySale +="X-"
1184
        else:
1185
            lastNdaySale +=str(oosStatus.num_orders) + "-"
1186
    return lastNdaySale[:-1] 
1187
 
7281 kshitij.so 1188
def get_warehouse_name(warehouseId):
1189
    row = Warehouse.get_by(id = warehouseId)
1190
    return row.displayName
1191
 
1192
def get_amazon_inventory_for_item(amazonItemId):
1193
    inventory = AmazonInventorySnapshot.get_by(item_id=amazonItemId)
1194
    return inventory
1195
 
1196
def get_all_amazon_inventory():
1197
    return session.query(AmazonInventorySnapshot).all()
1198
 
1199
def add_or_update_amazon_inventory_for_item(amazoninventorysnapshot):
1200
    inventory = AmazonInventorySnapshot.get_by(item_id = amazoninventorysnapshot.item_id)
1201
    if inventory is None:
1202
        amazon_inventory = AmazonInventorySnapshot()
1203
        amazon_inventory.item_id = amazoninventorysnapshot.item_id
1204
        amazon_inventory.availability = amazoninventorysnapshot.availability
1205
        amazon_inventory.reserved = amazoninventorysnapshot.reserved
1206
    else:
1207
        inventory.availability = amazoninventorysnapshot.availability
1208
        inventory.reserved = amazoninventorysnapshot.reserved
1209
    session.commit()
1210
 
8182 amar.kumar 1211
def add_update_hold_inventory(itemId, warehouseId, holdQuantity, source):
8197 amar.kumar 1212
    hold_inventory_detail = HoldInventoryDetail.get_by(item_id = itemId, warehouse_id=warehouseId, source = source)
1213
    if  hold_inventory_detail is None:
8182 amar.kumar 1214
        diffTobeAddedInCIS = holdQuantity
1215
        hold_inventory_detail = HoldInventoryDetail()
1216
        hold_inventory_detail.item_id = itemId 
1217
        hold_inventory_detail.warehouse_id = warehouseId 
1218
        hold_inventory_detail.held = holdQuantity 
1219
        hold_inventory_detail.source = source
1220
    else:
8497 amar.kumar 1221
        diffTobeAddedInCIS = holdQuantity - hold_inventory_detail.held
8182 amar.kumar 1222
        hold_inventory_detail.held = holdQuantity
1223
 
1224
    current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
1225
    if not current_inventory_snapshot:
1226
        current_inventory_snapshot = CurrentInventorySnapshot()
1227
        current_inventory_snapshot.item_id = itemId
1228
        current_inventory_snapshot.warehouse_id = warehouseId
1229
        current_inventory_snapshot.availability = 0
1230
        current_inventory_snapshot.reserved = 0
1231
        current_inventory_snapshot.held = 0
1232
    current_inventory_snapshot.held = current_inventory_snapshot.held + diffTobeAddedInCIS
1233
    session.commit()
1234
    #**Update item availability cache**#
1235
    clear_item_availability_cache(itemId)
8282 kshitij.so 1236
 
1237
def add_or_update_amazon_fba_inventory(amazonfbainventorysnapshot):
1238
    inventory = AmazonFbaInventorySnapshot.get_by(item_id = amazonfbainventorysnapshot.item_id)
1239
    if inventory is None:
1240
        amazon_fba_inventory = AmazonFbaInventorySnapshot()
1241
        amazon_fba_inventory.item_id = amazonfbainventorysnapshot.item_id
1242
        amazon_fba_inventory.availability = amazonfbainventorysnapshot.availability
1243
    else:
1244
        inventory.availability = amazonfbainventorysnapshot.availability
1245
    session.commit()
1246
 
1247
 
1248
def get_amazon_fba_inventory(itemId):
1249
    row = AmazonFbaInventorySnapshot.get_by(item_id=itemId)
8621 kshitij.so 1250
    if row is None:
1251
        return 0
1252
    else:
1253
        return row.availability
8282 kshitij.so 1254
 
8363 vikram.rag 1255
def get_all_amazon_fba_inventory():
1256
    return AmazonFbaInventorySnapshot.query.all() 
1257
 
1258
def get_oursgood_warehouseids_for_location(state_id):
1259
    warehouseId=[]
1260
    x= session.query(Warehouse.id).filter(Warehouse.id==Warehouse.billingWarehouseId).filter(Warehouse.warehouseType=='OURS').filter(Warehouse.state_id==1).all()
1261
    for id in x:
1262
        warehouseId.append(id[0])
1263
    return session.query(Warehouse.id).filter(Warehouse.inventoryType=='GOOD').filter(Warehouse.warehouseType=='OURS').filter(Warehouse.billingWarehouseId.in_(warehouseId)).all()
8954 vikram.rag 1264
 
1265
def get_holdinventorydetail_forItem_forWarehouseId_exceptsource(item_id,warehouse_id,source):
1266
    holddetails = HoldInventoryDetail.query.filter(HoldInventoryDetail.item_id == item_id).all()
1267
    print holddetails
1268
    hold = 0
1269
    for holddetail in holddetails:
1270
        if holddetail.source !=source and holddetail.warehouse_id == warehouse_id:
1271
            hold = hold + holddetail.held
9404 vikram.rag 1272
    return hold
1273
 
1274
def get_snapdeal_inventory_for_item(id):
1275
    print SnapdealInventorySnapshot.get_by(item_id = id)
1276
    return SnapdealInventorySnapshot.get_by(item_id = id)
1277
 
1278
def add_or_update_snapdeal_inventor_for_item(snapdealinventoryitem):
1279
    snapdeal_inventory_item = SnapdealInventorySnapshot.get_by(item_id = snapdealinventoryitem.item_id)
1280
    if snapdeal_inventory_item is None:
1281
        snapdeal_inventory_item = SnapdealInventorySnapshot()
1282
        snapdeal_inventory_item.item_id = snapdealinventoryitem.item_id
1283
        snapdeal_inventory_item.availability = snapdealinventoryitem.availability
9495 vikram.rag 1284
        snapdeal_inventory_item.pendingOrders = snapdealinventoryitem.pendingOrders
9404 vikram.rag 1285
        snapdeal_inventory_item.lastUpdatedOnSnapdeal = to_py_date(snapdealinventoryitem.lastUpdatedOnSnapdeal)
1286
    else:
1287
        snapdeal_inventory_item.availability = snapdealinventoryitem.availability
9495 vikram.rag 1288
        snapdeal_inventory_item.pendingOrders = snapdealinventoryitem.pendingOrders
9404 vikram.rag 1289
        snapdeal_inventory_item.lastUpdatedOnSnapdeal = to_py_date(snapdealinventoryitem.lastUpdatedOnSnapdeal)
1290
    session.commit()
8954 vikram.rag 1291
 
9404 vikram.rag 1292
def get_nlc_for_warehouse(warehouse_id,itemid):
1293
    warehouse = Warehouse.get_by(id=warehouse_id)
1294
    if warehouse is None:
1295
        return 0
1296
    vendoritempricing = VendorItemPricing.query.filter_by(item_id=itemid, vendor_id=warehouse.vendor_id).first()
1297
    '''vendoritempricing = VendorItemPricing.get_by(id=warehouse.vendor_id,item_id=itemid)'''
1298
    if vendoritempricing is None:
1299
        return 0
9456 vikram.rag 1300
    return vendoritempricing.nlc
1301
 
9495 vikram.rag 1302
def get_snapdeal_inventory_snapshot():
9640 amar.kumar 1303
    return SnapdealInventorySnapshot.query.all()
1304
def get_held_inventory_map_for_item(itemId, warehouseId):
1305
    heldInventoryMap = {}
1306
    holdInventories = HoldInventoryDetail.query.filter_by(item_id= itemId, warehouse_id = warehouseId).all()
1307
    for holdInventory in holdInventories:
1308
        heldInventoryMap[holdInventory.source] = holdInventory.held
1309
    return heldInventoryMap 
9761 amar.kumar 1310
def get_hold_inventory_details(itemId, warehouseId, source):
1311
    heldInventoryQuery = HoldInventoryDetail.query
1312
    if itemId:
1313
        heldInventoryQuery = heldInventoryQuery.filter_by(item_id = itemId)
1314
    if warehouseId:
1315
        heldInventoryQuery = heldInventoryQuery.filter_by(warehouse_id = warehouseId)
1316
    if source:
1317
        heldInventoryQuery = heldInventoryQuery.filter_by(source = source)
1318
    holdInventoryDetails = heldInventoryQuery.all()
1319
    return holdInventoryDetails
9640 amar.kumar 1320