Subversion Repositories SmartDukaan

Rev

Rev 6540 | Rev 6544 | 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, \
6531 vikram.rag 16
    VendorItemProcurementDelay, VendorHolidays, ItemAvailabilityCache, \
17
    CurrentReservationSnapshot, IgnoredInventoryUpdateItems
18
from shop2020.thriftpy.model.v1.inventory.ttypes import \
19
    InventoryServiceException, HolidayType, InventoryType, WarehouseType
5944 mandeep.dh 20
from shop2020.thriftpy.model.v1.order.ttypes import AlertType
6531 vikram.rag 21
from shop2020.thriftpy.purchase.ttypes import PurchaseServiceException
5944 mandeep.dh 22
from shop2020.utils import EmailAttachmentSender
23
from shop2020.utils.EmailAttachmentSender import mail
6531 vikram.rag 24
from shop2020.utils.Utils import to_py_date
5944 mandeep.dh 25
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
6531 vikram.rag 26
from sqlalchemy.sql.expression import and_, func, distinct
27
from sqlalchemy.sql.functions import count
5944 mandeep.dh 28
import calendar
29
import datetime
30
import sys
31
import threading
32
 
6501 rajveer 33
to_addresses = ["chaitnaya.vats@shop2020.in", "chandan.kumar@shop2020.in"]
6029 rajveer 34
mail_user = "cnc.center@shop2020.in"
35
mail_password = "5h0p2o2o"
5944 mandeep.dh 36
skippedItems = { 175 : [27, 2160, 2175, 2163, 2158, 7128, 26, 2154],
37
                 193 : [5839] }
38
 
6498 vikram.rag 39
 
40
 
5944 mandeep.dh 41
def initialize(dbname='inventory', db_hostname="localhost"):
42
    DataService.initialize(dbname, db_hostname)
43
 
44
def get_Warehouse(warehouse_id):
45
    return Warehouse.get_by(id=warehouse_id)
46
 
47
def get_vendor(vendorId):
48
    return Vendor.get_by(id=vendorId)
49
 
50
def get_all_warehouses_by_status(status):
51
    return Warehouse.query.all()
52
 
53
def get_all_items_for_warehouse(warehouse_id):
54
    warehouse = get_Warehouse(warehouse_id)
55
    if not warehouse:
56
        raise InventoryServiceException(108, "bad warehouse")
57
    return warehouse.all_items
58
 
59
def add_warehouse(warehouse):
60
    if not warehouse:
61
        raise InventoryServiceException(108, "Bad warehouse")
62
    if get_Warehouse(warehouse.id):
63
        #warehouse is already present.
64
        raise InventoryServiceException(101, "Warehouse already present")
65
 
66
    ds_warehouse = Warehouse()
67
    ds_warehouse.location = warehouse.location
68
    ds_warehouse.status = 3
69
    ds_warehouse.addedOn = datetime.datetime.now()
70
    ds_warehouse.lastCheckedOn = datetime.datetime.now()
71
    ds_warehouse.tinNumber = warehouse.tinNumber
72
    ds_warehouse.pincode = warehouse.pincode
73
    ds_warehouse.billingType = warehouse.billingType
74
    ds_warehouse.billingWarehouseId = warehouse.billingWarehouseId
75
    ds_warehouse.displayName = warehouse.displayName
76
    ds_warehouse.inventoryType = InventoryType._VALUES_TO_NAMES[warehouse.inventoryType]
77
    ds_warehouse.isAvailabilityMonitored = warehouse.isAvailabilityMonitored
78
    ds_warehouse.logisticsLocation = warehouse.logisticsLocation
79
    ds_warehouse.shippingWarehouseId = warehouse.shippingWarehouseId
80
    ds_warehouse.transferDelayInHours = warehouse.transferDelayInHours
81
    ds_warehouse.vendor = get_vendor(warehouse.vendor.id)
82
    ds_warehouse.warehouseType = WarehouseType._VALUES_TO_NAMES[warehouse.warehouseType]    
83
    if warehouse.vendorString:
84
        ds_warehouse.vendorString = warehouse.vendorString
85
    session.commit()
86
    return ds_warehouse.id
87
 
6498 vikram.rag 88
def get_ignored_items(warehouse_id): 
6531 vikram.rag 89
    Ignored_inventory_items = IgnoredInventoryUpdateItems.query.filter_by(warehouse_id=warehouse_id).all()
6498 vikram.rag 90
    negativeItems = []
91
    for Ignored_inventory_item in Ignored_inventory_items:
92
        try:
93
            item_id = Ignored_inventory_item.item_id
94
            negativeItems.append(item_id)
95
        except:
96
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
97
    return negativeItems
98
 
6510 rajveer 99
def get_ignored_warehouses(item_id): 
6539 amit.gupta 100
    Ignored_inventory_items = IgnoredInventoryUpdateItems.query.filter_by(item_id=item_id).all()
6510 rajveer 101
    warehouses = []
102
    for Ignored_inventory_item in Ignored_inventory_items:
103
        warehouses.append(Ignored_inventory_item.warehouse_id)
104
    return warehouses
105
 
5944 mandeep.dh 106
def update_inventory_history(warehouse_id, timestamp, availability):
107
    warehouse = get_Warehouse(warehouse_id)
108
    if not warehouse:
109
        raise InventoryServiceException(107, "Warehouse? Where?")
110
    vendor = warehouse.vendor
111
    time = datetime.datetime.now()
112
    for item_key, quantity in availability.iteritems():
113
        try:
114
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
5960 mandeep.dh 115
            item_id = vendor_item_mapping.item_id
5944 mandeep.dh 116
        except:
6531 vikram.rag 117
            continue  
5944 mandeep.dh 118
        try:
6510 rajveer 119
            item_inventory_history = ItemInventoryHistory()
120
            item_inventory_history.warehouse = warehouse
121
            item_inventory_history.item_id = item_id
122
            item_inventory_history.timestamp = time
123
            item_inventory_history.availability = quantity
5944 mandeep.dh 124
        except:
125
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
126
    session.commit()
127
 
128
def update_inventory(warehouse_id, timestamp, availability):
129
    warehouse = get_Warehouse(warehouse_id)
130
    if not warehouse:
131
        raise InventoryServiceException(107, "Warehouse? Where?")
6510 rajveer 132
 
5944 mandeep.dh 133
    time = datetime.datetime.now()
134
    warehouse.lastCheckedOn = time
135
    warehouse.vendorString = timestamp
136
    vendor = warehouse.vendor
137
    item_ids = []
138
    for item_key, quantity in availability.iteritems():
139
        try:
140
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
141
            item_id = vendor_item_mapping.item_id
6510 rajveer 142
            item_ids.append(item_id)
5944 mandeep.dh 143
        except:
144
            print 'Skipping update for ' + item_key + ' quantity ' + str(quantity) + ' warehouse id: ' + str(warehouse_id)
145
            __send_mail_for_missing_key(item_key, quantity, warehouse_id)
146
            continue
147
        try:
148
            current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=item_id, warehouse=warehouse)
149
            if not current_inventory_snapshot:
150
                current_inventory_snapshot = CurrentInventorySnapshot()
151
                current_inventory_snapshot.item_id = item_id
152
                current_inventory_snapshot.warehouse = warehouse
153
                current_inventory_snapshot.availability = 0
154
                current_inventory_snapshot.reserved = 0
155
            # added the difference in the current inventory    
156
            current_inventory_snapshot.availability = current_inventory_snapshot.availability + quantity
157
            item = __get_item_from_master(item_id)
158
            try:
159
                if quantity > 0 and __get_item_reserved(item_id) > 0:
160
                    cl = TransactionClient().get_client()
161
                    #FIXME hardcoding for warehouse id 
162
                    cl.addAlert(AlertType.NEW_INVENTORY_ALERT, 5, "Inventory received for item " + item.brand + " " + item.modelName + " " + item.modelNumber + " " +  item.color)
163
            except:
164
                print "Not able to raise alert for incoming inventory" 
165
            if current_inventory_snapshot.availability < 0:
166
                __send_alert_for_negative_availability(item, current_inventory_snapshot.availability, warehouse)
167
        except:
168
            print "Some unforeseen error while updating inventory:", sys.exc_info()[0]
169
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
170
    session.commit()
171
 
172
    #**Update item availability cache**#
173
    for item_id in item_ids:
5978 rajveer 174
        clear_item_availability_cache(item_id)
5944 mandeep.dh 175
 
176
def __send_alert_for_negative_reserved(item, reserved, warehouse):
177
    itemName = " ".join([str(item.id), str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
6029 rajveer 178
    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 179
 
180
def __send_alert_for_negative_availability(item, availability, warehouse):
181
    itemName = " ".join([str(item.id), str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
5964 amar.kumar 182
    # 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 183
 
184
def __send_mail_for_missing_key(item_key, quantity, warehouse_id):
185
    missedInventoryUpdate = MissedInventoryUpdate.get_by(itemKey = item_key, warehouseId = warehouse_id)
186
    # One email per product key mismatch
187
    if not missedInventoryUpdate:
188
        missedInventoryUpdate = MissedInventoryUpdate()
189
        missedInventoryUpdate.itemKey = item_key
190
        missedInventoryUpdate.quantity = quantity
191
        missedInventoryUpdate.isIgnored = 1
192
        missedInventoryUpdate.timestamp = datetime.datetime.now()
193
        missedInventoryUpdate.warehouseId = warehouse_id
194
        session.commit()
6232 rajveer 195
        try:
6242 amar.kumar 196
            EmailAttachmentSender.mail(mail_user, mail_password, ['chaitnaya.vats@shop2020.in', 'chandan.kumar@spiceretail.co.in', 'amar.kumar@shop2020.in'], 'Skipped inventory update for ' + item_key + ' quantity ' + str(quantity) + ' warehouse id: ' + str(warehouse_id), None)
6232 rajveer 197
        except:
198
            print "Not able to send email. No issues, we can continue with updates."
5944 mandeep.dh 199
    else:
200
        missedInventoryUpdate.quantity += quantity
201
        session.commit()
202
 
203
def add_inventory(itemId, warehouseId, quantity):
204
    current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
205
    if not current_inventory_snapshot:
206
        current_inventory_snapshot = CurrentInventorySnapshot()
207
        current_inventory_snapshot.item_id = itemId
208
        current_inventory_snapshot.warehouse_id = warehouseId
209
        current_inventory_snapshot.availability = 0
210
        current_inventory_snapshot.reserved = 0
211
    # added the difference in the current inventory    
212
    current_inventory_snapshot.availability = current_inventory_snapshot.availability + quantity
213
    session.commit()
214
    #**Update item availability cache**#
5978 rajveer 215
    clear_item_availability_cache(itemId)
5944 mandeep.dh 216
    if current_inventory_snapshot.availability < 0:
217
        item = __get_item_from_master(itemId)
5978 rajveer 218
        __send_alert_for_negative_availability(item, current_inventory_snapshot.availability, get_Warehouse(warehouseId)) 
5944 mandeep.dh 219
 
220
def add_bad_inventory(itemId, warehouseId, quantity):
221
    bad_inventory_snapshot = BadInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
222
    if not bad_inventory_snapshot:
223
        bad_inventory_snapshot = BadInventorySnapshot()
224
        bad_inventory_snapshot.item_id = itemId
225
        bad_inventory_snapshot.warehouse_id = warehouseId
226
        bad_inventory_snapshot.availability = 0
227
    # added the difference in the current inventory    
228
    bad_inventory_snapshot.availability += quantity
229
    session.commit()
230
    if bad_inventory_snapshot.availability < 0:
231
        item = __get_item_from_master(itemId)
232
        __send_alert_for_negative_availability(item, bad_inventory_snapshot.availability, get_Warehouse(warehouseId))
233
 
234
def get_item_inventory_by_item_id(item_id):
235
    return CurrentInventorySnapshot.query.filter_by(item_id=item_id).all()
236
 
237
def retire_warehouse(warehouse_id):
238
    if not warehouse_id:
239
        raise InventoryServiceException(101, "Bad warehouse id")
240
    warehouse = get_Warehouse(warehouse_id)
241
    if not warehouse:
242
        raise InventoryServiceException(108, "warehouse id not present")
243
    warehouse.status = 0;
244
    session.commit()
245
 
246
def get_item_availability_for_warehouse(warehouse_id, item_id):
247
    if not warehouse_id:
248
        raise InventoryServiceException(101, "bad warehouse_id")
249
    if not item_id:
250
        raise InventoryServiceException(101, "bad item_id")
251
 
252
    warehouse = get_Warehouse(warehouse_id)
253
    if not warehouse:
254
        raise InventoryServiceException(108, "warehouse does not exist")
255
 
256
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id)
257
    query = query.filter_by(item_id = item_id)
258
    try:
259
        current_inventory_snapshot = query.one()
260
        return current_inventory_snapshot.availability - current_inventory_snapshot.reserved
261
    except:
262
        return 0
263
 
6484 amar.kumar 264
def get_item_availability_for_our_warehouses(item_ids):
265
    warehouses = Warehouse.query.filter_by(warehouseType = 'OURS', inventoryType = 'GOOD').all()
266
    warehouse_ids = []
267
    for warehouse in warehouses :
268
        warehouse_ids.append(warehouse.id)
269
 
270
    availability_map = dict()
271
 
272
    try :
273
        for item_id in item_ids :
274
            total_availability = 0
275
            for current_inventory_snapshot in CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).filter_by(item_id = item_id).all():
276
                total_availability += current_inventory_snapshot.availability
277
            if total_availability >0:
278
                availability_map[item_id] = total_availability
279
    except Exception as e:
280
        print e
281
        raise PurchaseServiceException(101, 'Exception while fetching availability of items in our warehouses')
282
 
283
    return availability_map
284
 
5944 mandeep.dh 285
'''
286
This method returns quantity of a particular item across all warehouses whose ids is provided
287
if warehouse_ids is null it checks for inventory in all warehouses.
288
'''
289
def __get_item_availability(item, warehouse_ids):
290
    if warehouse_ids is None:
291
        all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
292
        availability = 0
293
        reserved = 0
294
        for currInv in all_inventory:
295
            availability = availability + currInv.availability
296
            reserved = reserved + currInv.reserved
297
        return availability - reserved
298
    else:
299
        total_availability = 0
300
        for current_inventory_snapshot in CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).filter_by(item_id = item.id).all():
301
            total_availability += current_inventory_snapshot.availability - current_inventory_snapshot.reserved
302
        return total_availability 
303
 
304
def __get_item_reserved(item_id):
305
    all_inventory = CurrentInventorySnapshot.query.filter_by(item_id = item_id).all()
306
    reserved = 0
307
    for currInv in all_inventory:
308
        reserved = reserved + currInv.reserved
309
    return reserved
5966 rajveer 310
 
311
def __get_item_availability_at_warehouse(warehouse_id, item_id):
312
    inventory = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).one()
313
    return inventory.availability
314
 
315
def is_order_billable(item_id, warehouse_id, source_id, order_id):
316
    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()
317
    availability = __get_item_availability_at_warehouse(warehouse_id, item_id)
318
    for reservation in reservations:
319
        availability = availability - reservation.reserved
320
        if reservation.order_id == order_id and reservation.source_id == source_id:
321
            break
322
    if availability < 0:
323
        return False
324
    return True
5944 mandeep.dh 325
 
5966 rajveer 326
def reserve_item_in_warehouse(item_id, warehouse_id, source_id, order_id, created_timestamp, promised_shipping_timestamp, quantity):    
5944 mandeep.dh 327
    if not warehouse_id:
328
        raise InventoryServiceException(101, "bad warehouse_id")
329
 
330
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
331
    try:
332
        current_inventory_snapshot = query.one()
333
    except:
334
        current_inventory_snapshot = CurrentInventorySnapshot()
335
        current_inventory_snapshot.warehouse_id = warehouse_id
336
        current_inventory_snapshot.item_id = item_id
337
        current_inventory_snapshot.availability = 0
338
        current_inventory_snapshot.reserved = 0
339
 
340
    current_inventory_snapshot.reserved = current_inventory_snapshot.reserved + quantity
5966 rajveer 341
 
342
    reservation = CurrentReservationSnapshot()
343
    reservation.item_id = item_id
344
    reservation.warehouse_id = warehouse_id
345
    reservation.source_id = source_id
346
    reservation.order_id = order_id
5990 rajveer 347
    reservation.created_timestamp = to_py_date(created_timestamp)
348
    reservation.promised_shipping_timestamp = to_py_date(promised_shipping_timestamp)
5966 rajveer 349
    reservation.reserved = quantity
350
 
5944 mandeep.dh 351
    session.commit()
352
    #**Update item availability cache**#
5978 rajveer 353
    clear_item_availability_cache(item_id)
5944 mandeep.dh 354
    return True
355
 
5966 rajveer 356
def reduce_reservation_count(item_id, warehouse_id, source_id, order_id, quantity):
5944 mandeep.dh 357
    if not warehouse_id:
358
        raise InventoryServiceException(101, "bad warehouse_id")
359
 
360
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
361
    try:
362
        current_inventory_snapshot = query.one()
363
        current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
5966 rajveer 364
 
365
        reservation = CurrentReservationSnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id, source_id = source_id, order_id = order_id).one()
366
        if reservation.reserved == quantity:
367
            reservation.delete()
368
        else:
369
            reservation.reserved -= quantity
5944 mandeep.dh 370
        session.commit()
371
        #**Update item availability cache**#
5978 rajveer 372
        clear_item_availability_cache(item_id)
5944 mandeep.dh 373
        if current_inventory_snapshot.reserved < 0:
374
            item = __get_item_from_master(item_id)
375
            __send_alert_for_negative_reserved(item, current_inventory_snapshot.reserved, get_Warehouse(warehouse_id))
376
        return True
377
    except:
378
        print "Unexpected error:", sys.exc_info()[0]
379
        return False
380
 
5978 rajveer 381
def get_item_availability_for_location(item_id, source_id):
382
    item_availability = ItemAvailabilityCache.get_by(itemId=item_id, sourceId = source_id)
5944 mandeep.dh 383
    if item_availability:
384
        return [item_availability.warehouseId, item_availability.expectedDelay, item_availability.billingWarehouseId, item_availability.sellingPrice, item_availability.totalAvailability]
385
    else:
5978 rajveer 386
        __update_item_availability_cache(item_id, source_id)
387
            ##Check risky status for the source
388
        __check_risky_item(item_id, source_id)
389
        return get_item_availability_for_location(item_id, source_id)
5944 mandeep.dh 390
 
5978 rajveer 391
def clear_item_availability_cache(item_id = None):
392
    if item_id:
393
        ItemAvailabilityCache.query.filter_by(itemId = item_id).delete()
394
    else:
395
        ItemAvailabilityCache.query.delete()
5944 mandeep.dh 396
    session.commit()
397
 
5978 rajveer 398
def __update_item_availability_cache(item_id, source_id):
5944 mandeep.dh 399
    """
400
    Determines the warehouse that should be used to fulfil an order for the given item.
401
    Algorithm explained at https://sites.google.com/a/shop2020.in/virtual-w-h-and-inventory/technical-details
402
 
403
    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.
404
    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.
405
 
406
    if item available at any OUR-GOOD warehouse
407
        // OUR-GOOD warehouses have inventory risk; So, we empty them first! 
408
        // We can start with minimum transfer price criterion but down the line we can also bring in Inventory age 
409
        assign OUR-GOOD warehouse with minimum transfer price
410
    else
411
        if Preferred vendor is specified and marked Sticky
412
            // Always purchase from Preferred if its marked sticky
413
            assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
414
        else 
415
            if item available in a THIRDPARTY GOOD/VIRTUAL warehouse
416
                assign THIRDPARTY GOOD/VIRTUAL warehouse where item is available with minimal transfer delay followed by minimum transfer price
417
            else 
418
                // Item not available at any warehouse, OURS or THIRDPARTY
419
                If Preferred vendor is specified
420
                    assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
421
                else
422
                    assign THIRDPARTY GOOD/VIRTUAL warehouse with minimum transfer price
423
 
424
    Returns an ordered list of size 4 with following elements in the given order:
425
    1. Logistics location of the warehouse which was finally picked up to ship the order.
426
    2. Expected delay added by the category manager.
427
    3. Id of the warehouse which was finally picked up.
428
 
429
    Parameters:
430
     - itemId
431
    """
5978 rajveer 432
    item = __get_item_from_source(item_id, source_id)
5944 mandeep.dh 433
    item_pricing = {}
434
    for vendorItemPricing in VendorItemPricing.query.filter_by(item_id=item_id).all():
435
        item_pricing[vendorItemPricing.vendor_id] = vendorItemPricing
436
 
6510 rajveer 437
    ignoredWhs = get_ignored_warehouses(item_id)
438
 
5944 mandeep.dh 439
    warehouses = {}
440
    ourGoodWarehouses = {}
441
    thirdpartyWarehouses = {}
442
    preferredThirdpartyWarehouses = {}
443
    for warehouse in Warehouse.query.all():
444
        if (warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.BAD]):
445
            continue
446
        warehouses[warehouse.id] = warehouse
447
        if warehouse.warehouseType == WarehouseType._VALUES_TO_NAMES[WarehouseType.OURS]:
448
            if warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
449
                ourGoodWarehouses[warehouse.id] = warehouse
450
        else:
451
            thirdpartyWarehouses[warehouse.id] = warehouse
452
            if item.preferredVendor == warehouse.vendor_id and warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
453
                preferredThirdpartyWarehouses[warehouse.id] = warehouse
454
 
455
    warehouse_retid = -1
456
    total_availability = 0
457
 
6540 rajveer 458
    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(ourGoodWarehouses, ignoredWhs, item_id, item_pricing, False)
5944 mandeep.dh 459
    if warehouse_retid == -1:
460
        if item.preferredVendor and item.isWarehousePreferenceSticky:
6540 rajveer 461
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(preferredThirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 462
            if warehouse_retid == -1:
463
                warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
464
        else:
6540 rajveer 465
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 466
            if warehouse_retid == -1:
467
                if item.preferredVendor:
468
                    warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
469
                else:
6540 rajveer 470
                    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing, True)
5944 mandeep.dh 471
 
472
    warehouse = warehouses[warehouse_retid]
473
    billingWarehouseId = warehouse.billingWarehouseId
474
 
475
    # Fetching billing warehouse of a Good billable warehouse corresponding to the virtual one
476
    if not warehouse.billingWarehouseId:
477
        for w in Warehouse.query.filter_by(vendor_id = warehouse.vendor_id, inventoryType = InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]).all():
478
            if w.billingWarehouseId:
479
                billingWarehouseId = w.billingWarehouseId
480
                break
481
 
482
    expectedDelay = item.expectedDelay 
483
    if expectedDelay is None:
484
        print 'expectedDelay field for this item was Null. Resetting it to 0'
485
        expectedDelay = 0
486
    else:
487
        expectedDelay = int(item.expectedDelay)
488
 
489
    if total_availability <= 0:
5978 rajveer 490
        expectedDelay = expectedDelay + __get_expected_procurement_delay(item.id, item.preferredVendor)
491
        expectedDelay = expectedDelay + __get_vendor_holiday_delay(item.preferredVendor, expectedDelay)
5944 mandeep.dh 492
    else:
493
        if warehouse.transferDelayInHours:
494
            expectedDelay = expectedDelay + warehouse.transferDelayInHours / 24
495
 
5963 mandeep.dh 496
    total_availability = 0
497
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
498
        total_availability += entry.availability - entry.reserved
499
 
5978 rajveer 500
    item_availability_cache = ItemAvailabilityCache.get_by(itemId=item_id, sourceId=source_id)
5944 mandeep.dh 501
    if item_availability_cache is None:
502
        item_availability_cache = ItemAvailabilityCache()
503
        item_availability_cache.itemId = item_id
5978 rajveer 504
        item_availability_cache.sourceId = source_id
5944 mandeep.dh 505
    item_availability_cache.warehouseId = int(warehouse_retid)
506
    item_availability_cache.expectedDelay = expectedDelay
507
    item_availability_cache.billingWarehouseId = billingWarehouseId
508
    item_availability_cache.sellingPrice = item.sellingPrice
509
    item_availability_cache.totalAvailability = total_availability
510
    session.commit()
511
 
6540 rajveer 512
def __get_warehouse_with_min_transfer_price(warehouses, ignoredWhs, item_id, item_pricing, ignoreAvailability):
5944 mandeep.dh 513
    warehouse_retid = -1
514
    minTransferPrice = None
515
    total_availability = 0
6013 amar.kumar 516
    availabilityForBillingWarehouses = {}
517
    warehousesAvailability = {}
518
    availability = 0
519
    billing_warehouse_retid = None
5944 mandeep.dh 520
 
521
    if not ignoreAvailability:
522
        for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
6013 amar.kumar 523
            #if entry.availability > entry.reserved:
6542 rajveer 524
            warehousesAvailability[entry.warehouse_id] = [entry.availability, entry.reserved] 
5944 mandeep.dh 525
 
6540 rajveer 526
    if len(ignoredWhs) > 0:
527
        for whid in ignoredWhs:
528
            if warehousesAvailability.has_key(whid):
6542 rajveer 529
                warehousesAvailability[whid][0] = 0
6540 rajveer 530
 
5944 mandeep.dh 531
    for warehouse in warehouses.values():
532
        if not ignoreAvailability:
6013 amar.kumar 533
            #TODO Mistake no entry for this warehouse.id in warehouseswithAvailab
534
            if warehouse.id not in warehousesAvailability:
535
                continue
536
            entry = warehousesAvailability[warehouse.id]
537
            if warehouse.billingWarehouseId in availabilityForBillingWarehouses:
538
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
539
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = availabilityForBillingWarehouses[warehouse.billingWarehouseId] + entry.availability - entry.reserved  
5944 mandeep.dh 540
            else:
6013 amar.kumar 541
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
6542 rajveer 542
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = entry[0] - entry[1]
543
            if entry[0] <= entry[1]:
5944 mandeep.dh 544
                continue
6542 rajveer 545
            total_availability += entry[0] - entry[1]
5944 mandeep.dh 546
 
547
        # Missing transfer price cases should not impact warehouse assignment
548
        transferPrice = None
549
        if item_pricing.has_key(warehouse.vendor_id):
550
            transferPrice = item_pricing[warehouse.vendor_id].transfer_price
551
        if minTransferPrice is None or (transferPrice and minTransferPrice > transferPrice):
552
            warehouse_retid = warehouse.id
6013 amar.kumar 553
            billing_warehouse_retid = warehouse.billingWarehouseId
5944 mandeep.dh 554
            minTransferPrice = transferPrice
6013 amar.kumar 555
 
556
 
557
    if billing_warehouse_retid in availabilityForBillingWarehouses: 
558
        availability = availabilityForBillingWarehouses[billing_warehouse_retid]
559
    else:
560
        availability = total_availability
561
 
562
    return [warehouse_retid, availability]
5944 mandeep.dh 563
 
6540 rajveer 564
def __get_warehouse_with_min_transfer_delay(warehouses, ignoredWhs, item_id, item_pricing):
5944 mandeep.dh 565
    minTransferDelay = None
566
    minTransferDelayWarehouses = {}
567
    total_availability = 0
568
 
569
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
570
        if warehouses.has_key(entry.warehouse_id):
571
            warehouse = warehouses[entry.warehouse_id]
6013 amar.kumar 572
            #if entry.availability > entry.reserved:
573
            total_availability += entry.availability - entry.reserved
574
            transferDelay = warehouse.transferDelayInHours
575
            if minTransferDelay is None or minTransferDelay >= transferDelay:
576
                if minTransferDelay != transferDelay:
577
                    minTransferDelayWarehouses = {}
578
                minTransferDelayWarehouses[warehouse.id] = warehouse
579
                minTransferDelay = transferDelay
5944 mandeep.dh 580
 
6540 rajveer 581
    return [__get_warehouse_with_min_transfer_price(minTransferDelayWarehouses, ignoredWhs, item_id, item_pricing, False)[0], total_availability]
5944 mandeep.dh 582
 
583
def __get_warehouse_with_max_availability(warehouse_ids, item_id):
584
    warehouse_retid = -1
585
    max_availability = 0
586
    total_availability = 0
587
 
588
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
589
        if entry.warehouse_id in warehouse_ids:
590
            availability = entry.availability - entry.reserved
591
            if availability > max_availability:
592
                warehouse_retid = entry.warehouse_id
593
                max_availability = availability
594
            total_availability += availability
595
 
596
    return [warehouse_retid, total_availability]
597
 
5978 rajveer 598
def __get_expected_procurement_delay(item_id, preferredVendor):
5944 mandeep.dh 599
    procurementDelay = 2
600
    try:
5978 rajveer 601
        if preferredVendor:
602
            delays = VendorItemProcurementDelay.query.filter_by(vendor_id = preferredVendor, item_id = item_id).all()
5944 mandeep.dh 603
        else:
5978 rajveer 604
            delays = VendorItemProcurementDelay.query.filter_by(item_id = item_id).all()
5944 mandeep.dh 605
 
606
        procurementDelay= min([delay.procurementDelay for delay in delays])
607
    except Exception as e:
608
        print e
609
    return procurementDelay
610
 
5978 rajveer 611
def __get_vendor_holiday_delay(preferredVendor, expectedDelay):
5944 mandeep.dh 612
    holidayDelay = 0
613
    try:
5978 rajveer 614
        if preferredVendor:
615
            holidays = VendorHolidays.query.filter_by(vendor_id = preferredVendor).all()
5944 mandeep.dh 616
            currentDate = datetime.date.today()
617
            expectedDate = currentDate + datetime.timedelta(days = expectedDelay)
618
            for holiday in holidays:
619
                if holiday.holidayType == HolidayType.WEEKLY and holiday.holidayValue != calendar.SUNDAY:
620
                    if currentDate.weekday() > holiday.holidayValue:
621
                        holidayDate = currentDate + datetime.timedelta(days=holiday.holidayValue-currentDate.weekday(), weeks=1)
622
                    else:
623
                        holidayDate = currentDate + datetime.timedelta(days=holiday.holidayValue-currentDate.weekday())
624
                    if holidayDate >=  currentDate and holidayDate <= expectedDate:
625
                        holidayDelay = holidayDelay + 1
626
                elif holiday.holidayType == HolidayType.MONTHLY:
627
                    holidayDate = datetime.date(currentDate.year, currentDate.month, holiday.holidayValue)
628
                    if holidayDate >=  currentDate and holidayDate <= expectedDate:
629
                        holidayDelay = holidayDelay + 1    
630
                elif holiday.holidayType == HolidayType.SPECIFIC:
631
                    holidayValue = str(holiday.holidayValue)
632
                    holidayDate = datetime.date(int(holidayValue[:4]), int(holidayValue[4:6]), int(holidayValue[6:8]))
633
                    if holidayDate >=  currentDate and holidayDate <= expectedDate:
634
                        holidayDelay = holidayDelay + 1                
635
    except Exception as e:
636
        print e
637
    return holidayDelay 
638
 
639
def get_item_pricing(item_id, vendorId):
640
    '''
641
    if vendor id is -1 then we calculate an average transfer price to be populated
642
    at the time of order creation. This will be later updated with actual transfer price
643
    at the time of billing.
644
    '''
645
    if(vendorId == -1):
646
        total = 0
647
        try:
648
            item_pricings = []
649
            item = __get_item_from_master(item_id)
650
            if item.preferredVendor is not None:
651
                item_pricing = VendorItemPricing.query.filter_by(item_id=item_id, vendor_id=item.preferredVendor).first()
652
                if item_pricing:
653
                    item_pricings.append(item_pricing)                    
654
            else :
655
                item_pricings = VendorItemPricing.query.filter_by(item_id=item_id).all()
656
            if item_pricings:
657
                for item_pricing in item_pricings:
658
                    total += item_pricing.transfer_price
659
                avg = total / len(item_pricings)
660
                item_pricing.transfer_price = avg
661
            else:
662
                item_pricing = VendorItemPricing()
663
                item_pricing.transfer_price = item.sellingPrice
664
                vendor = Vendor()
665
                vendor.id = vendorId
666
                item_pricing.vendor = vendor
667
                item_pricing.item_id = item_id
668
 
669
            return item_pricing
670
        except:
671
            raise InventoryServiceException(101, "Item pricing not found ")
672
    vendor = Vendor.get_by(id=vendorId)    
673
    try:
674
        item_pricing = VendorItemPricing.query.filter_by(vendor=vendor, item_id=item_id).one()
675
        return item_pricing
676
    except MultipleResultsFound:
677
        raise InventoryServiceException(110, "Multiple pricing information present for Vendor: " + vendor.name + " and Item: " + str(item_id))
678
    except NoResultFound:
679
        raise InventoryServiceException(111, "Missing pricing information for Vendor: " + vendor.name + " and Item: " + str(item_id))
680
 
681
def get_all_item_pricing(item_id):
682
    item_pricing = VendorItemPricing.query.filter_by(item_id=item_id).all()
683
    return item_pricing
684
 
685
def get_item_mappings(item_id):
686
    item_mappings = VendorItemMapping.query.filter_by(item_id=item_id).all()
687
    return item_mappings
688
 
689
def add_vendor_pricing(vendorItemPricing):
690
    if not vendorItemPricing:
691
        raise InventoryServiceException(108, "Bad vendorItemPricing in request")
692
    vendorId = vendorItemPricing.vendorId
693
    itemId = vendorItemPricing.itemId
694
 
695
    try:
696
        vendor = Vendor.query.filter_by(id=vendorId).one()
697
    except:
698
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
699
 
700
    try:
701
        item = __get_item_from_master(itemId)
702
    except:
703
        raise InventoryServiceException(101, "Item not found for itemId " + str(itemId))
704
 
705
    validate_vendor_prices(item, vendorItemPricing)
706
 
707
    try:
708
        ds_vendorItemPricing = VendorItemPricing.query.filter(and_(VendorItemPricing.vendor==vendor, VendorItemPricing.item_id==itemId)).one()
709
    except:
710
        ds_vendorItemPricing = VendorItemPricing()
711
        ds_vendorItemPricing.vendor = vendor
712
        ds_vendorItemPricing.item_id = itemId
713
 
714
    subject = ""
715
    message = ""
716
    if vendorItemPricing.mop:
717
        ds_vendorItemPricing.mop = vendorItemPricing.mop
718
    if vendorItemPricing.dealerPrice:
719
        ds_vendorItemPricing.dealerPrice = vendorItemPricing.dealerPrice
720
    if vendorItemPricing.transferPrice:
721
        if vendorItemPricing.transferPrice != ds_vendorItemPricing.transfer_price:
6014 amit.gupta 722
            message = "Transfer price for Item '{0}' \nand Vendor:{1} is changed from {2} to {3}.".format(itemId, vendor.name, ds_vendorItemPricing.transfer_price, vendorItemPricing.transferPrice)
5944 mandeep.dh 723
            subject = "Alert:Change in Transfer Price"
724
        ds_vendorItemPricing.transfer_price = vendorItemPricing.transferPrice
725
 
726
    session.commit()
727
    if subject:
728
        __send_mail(subject, message)
729
    return
730
 
731
def add_vendor_item_mapping(key, vendorItemMapping):
732
    if not vendorItemMapping:
733
        raise InventoryServiceException(108, "Bad vendorItemMapping in request")
734
    vendorId = vendorItemMapping.vendorId
735
    itemId = vendorItemMapping.itemId
736
 
737
    try:
738
        vendor = Vendor.query.filter_by(id=vendorId).one()
739
    except:
740
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
741
 
742
    try:
743
        ds_vendorItemMapping = VendorItemMapping.query.filter(and_(VendorItemMapping.vendor==vendor, VendorItemMapping.item_id==itemId, VendorItemMapping.item_key==key)).one()
744
    except:
745
        ds_vendorItemMapping = VendorItemMapping()
746
        ds_vendorItemMapping.vendor = vendor
747
        ds_vendorItemMapping.item_id = itemId
748
    ds_vendorItemMapping.item_key = vendorItemMapping.itemKey
749
 
750
    session.commit()
751
 
752
    # Marking the missed inventory as not ignored as the catalog dashboard user has updated their key
753
    for missedInventoryUpdate in MissedInventoryUpdate.query.filter_by(itemKey = vendorItemMapping.itemKey).all():
754
        missedInventoryUpdate.isIgnored = 0
755
    session.commit()
756
 
757
    return
758
 
759
def validate_vendor_prices(item, vendorPrices):
760
    if item.mrp != None and item.mrp != "" and vendorPrices.mop != "" and item.mrp <  vendorPrices.mop:
761
        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))
762
        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)))
763
    if vendorPrices.mop != "" and vendorPrices.transferPrice != "" and vendorPrices.transferPrice > vendorPrices.mop:
764
        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))
765
        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)))
766
    return
767
 
768
def get_all_vendors():
769
    return Vendor.query.all()
770
 
771
def get_pending_orders_inventory(vendor_id=1):
772
    """
773
    Returns a list of inventory stock for items for which there are pending orders.
774
    """
775
 
776
    warehouse_ids = [warehouse.id for warehouse in Warehouse.query.filter_by(vendor_id = vendor_id)]
777
    pending_items_inventory = []
778
    if warehouse_ids:
779
        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()
780
    return pending_items_inventory
781
 
782
def close_session():
783
    if session.is_active:
784
        print "session is active. closing it."
785
        session.close()
786
 
787
def is_alive():
788
    try:
789
        session.query(Vendor.id).limit(1).one()
790
        return True
791
    except:
792
        return False
793
 
794
def add_vendor(vendor):
795
    if not vendor:
796
        raise InventoryServiceException(108, "Bad vendor")
797
    if get_vendor(vendor.id):
798
        #vendor is already present.
799
        raise InventoryServiceException(101, "Vendor already present")
800
 
801
    ds_vendor = Vendor()
802
    ds_vendor.id = vendor.id
803
    ds_vendor.name = vendor.name
804
    session.commit()
805
    return ds_vendor.id
806
 
807
def add_warehouse_vendor_mapping(warehouse_id, VendorId):
808
    return True
809
 
810
def mark_missed_inventory_updates_as_processed(itemKey, warehouseId):
811
    MissedInventoryUpdate.query.filter_by(itemKey = itemKey, warehouseId = warehouseId).delete()
812
    session.commit()
813
 
814
def get_item_keys_to_be_processed(warehouseId):
815
    return [i.itemKey for i in MissedInventoryUpdate.query.filter_by(warehouseId = warehouseId, isIgnored = 0)]
816
 
817
def reset_availability(itemKey, vendorId, quantity, warehouseId):
818
    vendorItemMapping = VendorItemMapping.get_by(vendor_id = vendorId, item_key = itemKey)
819
    if vendorItemMapping:
820
        itemId = vendorItemMapping.item_id
821
 
822
        if skippedItems.has_key(warehouseId) and itemId in skippedItems[warehouseId]:
823
            quantity = 0
824
 
825
        currentInventorySnapshot = CurrentInventorySnapshot.get_by(item_id = itemId, warehouse_id = warehouseId)
826
        if currentInventorySnapshot:
827
            currentInventorySnapshot.availability = quantity
5978 rajveer 828
            clear_item_availability_cache(itemId) 
5944 mandeep.dh 829
        else:
830
            add_inventory(itemId, warehouseId, quantity)
831
 
832
    else:
833
        raise InventoryServiceException(101, 'VendorMapping not found for: ' + itemKey)
834
    session.commit()
835
 
836
def reset_availability_for_warehouse(warehouseId):
837
    for currentInventorySnapshot in CurrentInventorySnapshot.query.filter_by(warehouse_id=warehouseId).all():
838
        currentInventorySnapshot.availability = 0
5978 rajveer 839
        clear_item_availability_cache(currentInventorySnapshot.item_id) 
5944 mandeep.dh 840
    session.commit()
841
 
6467 amar.kumar 842
def get_our_warehouse_id_for_vendor(vendor_id):
843
    try:
844
        warehouse = Warehouse.query.filter_by(vendor_id = vendor_id, warehouseType = 'OURS', inventoryType = 'GOOD').first()
845
        return warehouse.id
846
    except Exception as e:
847
        print e;
848
        raise InventoryServiceException(101, 'No our warehouse found for vendorId: ' + vendor_id)
5944 mandeep.dh 849
 
850
def __send_mail(subject, message):
851
    try:
6029 rajveer 852
        thread = threading.Thread(target=partial(mail, mail_user, mail_password, to_addresses, subject, message))
5944 mandeep.dh 853
        thread.start()
854
    except Exception as ex:
855
        print ex    
856
 
857
def get_shipping_locations():
858
    shippingLocationIds = {}
859
    warehouses = Warehouse.query.all()
860
    for warehouse in warehouses:
861
        if warehouse.shippingWarehouseId:
862
            shippingLocationIds[warehouse.shippingWarehouseId] = 1
863
 
864
    shippingLocations = []
865
    for shippingLocationId in shippingLocationIds:
866
        shippingLocations.append(get_Warehouse(shippingLocationId))
867
 
868
    return shippingLocations
869
 
870
def get_inventory_snapshot(warehouseId):
871
    query = CurrentInventorySnapshot.query
872
 
873
    if warehouseId:
874
        query = query.filter_by(warehouse_id = warehouseId)
875
 
876
    itemInventoryMap = {}
877
    for row in query.all():
878
        if not itemInventoryMap.has_key(row.item_id):
879
            itemInventoryMap[row.item_id] = []
880
 
881
        itemInventoryMap[row.item_id].append(row)
882
 
883
    return itemInventoryMap
884
 
885
def update_vendor_string(warehouseId, vendorString):
886
    warehouse = get_Warehouse(warehouseId)
887
    warehouse.vendorString = vendorString
888
    session.commit()
889
 
890
def __get_item_from_master(item_id):
891
    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
5978 rajveer 892
    return client.getItem(item_id)
893
 
894
def __check_risky_item(item_id, source_id):
895
    ## We should get the list of strings which will identify to the catalog servers
896
    if source_id == 1:
897
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
898
        client.validateRiskyStatus(item_id)
899
    if source_id == 2:
900
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
901
        client.validateRiskyStatus(item_id)
902
 
903
def __get_item_from_source(item_id, source_id):
904
    if source_id == 1:
905
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
906
        return client.getItem(item_id)
907
    if source_id == 2:
908
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
6531 vikram.rag 909
        return client.getItem(item_id)
910
 
911
def get_monitored_warehouses_for_vendors(vendorIds):
912
    w = []
913
    for wh in Warehouse.query.filter_by(isAvailabilityMonitored = 1).all():
914
        if wh.vendor.id in (vendorIds):
915
            w.append(to_t_warehouse(wh).id)
916
    return w
917
def get_ignored_warehouseids_and_itemids():
918
    iw = []
919
    for i in IgnoredInventoryUpdateItems.query.all():
920
        iw.append(to_t_itemidwarehouseid(i)) 
921
    return iw
922
def insert_item_to_ignore_inventory_update_list(item_id,warehouse_id):
923
    try:
924
        ds_warehouse=IgnoredInventoryUpdateItems()
925
        ds_warehouse.item_id=item_id
926
        ds_warehouse.warehouse_id=warehouse_id
6532 amit.gupta 927
        clear_item_availability_cache(item_id)
6531 vikram.rag 928
        session.commit()
929
        return True
930
    except:
931
        return False       
932
def delete_item_from_ignore_inventory_update_list(item_id,warehouse_id):
933
    try:
934
        session.query(IgnoredInventoryUpdateItems).filter_by(item_id=item_id,warehouse_id=warehouse_id).delete()
6532 amit.gupta 935
        clear_item_availability_cache(item_id)
6531 vikram.rag 936
        session.commit()
937
        return True
938
    except:
939
        return False           
940
 
941
def get_all_ignored_inventoryupdate_items_count():
942
    return  session.query(func.count(distinct(IgnoredInventoryUpdateItems.item_id))).scalar()
943
 
944
def get_ignored_inventoryupdate_itemids(offset=0,limit=None):
945
    itemIds = session.query(distinct(IgnoredInventoryUpdateItems.item_id))
946
    '''if limit is not None:
947
        itemIds = itemIds.limit(limit)'''
948
    print itemIds.all()
949
    return [id for (id, ) in itemIds.all()]
950