Subversion Repositories SmartDukaan

Rev

Rev 6778 | Rev 6821 | 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
 
6550 rajveer 33
to_addresses = ["khushal.bhatia@shop2020.in", "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:
6617 amar.kumar 196
            EmailAttachmentSender.mail(mail_user, mail_password, ['chaitnaya.vats@shop2020.in', 'chandan.kumar@shop2020.in', 'khushal.bhatia@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):
6545 rajveer 247
    ignore = IgnoredInventoryUpdateItems.query.filter_by(item_id=item_id).filter_by(warehouse_id = warehouse_id).all()
6544 rajveer 248
    if ignore:
249
        return 0
5944 mandeep.dh 250
 
251
    try:
6544 rajveer 252
        current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id).filter_by(item_id = item_id).one()
5944 mandeep.dh 253
        return current_inventory_snapshot.availability - current_inventory_snapshot.reserved
254
    except:
255
        return 0
256
 
6484 amar.kumar 257
def get_item_availability_for_our_warehouses(item_ids):
258
    warehouses = Warehouse.query.filter_by(warehouseType = 'OURS', inventoryType = 'GOOD').all()
259
    warehouse_ids = []
260
    for warehouse in warehouses :
261
        warehouse_ids.append(warehouse.id)
262
 
263
    availability_map = dict()
264
 
265
    try :
266
        for item_id in item_ids :
267
            total_availability = 0
268
            for current_inventory_snapshot in CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).filter_by(item_id = item_id).all():
269
                total_availability += current_inventory_snapshot.availability
270
            if total_availability >0:
271
                availability_map[item_id] = total_availability
272
    except Exception as e:
273
        print e
274
        raise PurchaseServiceException(101, 'Exception while fetching availability of items in our warehouses')
275
 
276
    return availability_map
277
 
5944 mandeep.dh 278
'''
279
This method returns quantity of a particular item across all warehouses whose ids is provided
280
if warehouse_ids is null it checks for inventory in all warehouses.
281
'''
282
def __get_item_availability(item, warehouse_ids):
283
    if warehouse_ids is None:
284
        all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
285
        availability = 0
286
        reserved = 0
287
        for currInv in all_inventory:
288
            availability = availability + currInv.availability
289
            reserved = reserved + currInv.reserved
290
        return availability - reserved
291
    else:
292
        total_availability = 0
293
        for current_inventory_snapshot in CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).filter_by(item_id = item.id).all():
294
            total_availability += current_inventory_snapshot.availability - current_inventory_snapshot.reserved
295
        return total_availability 
296
 
297
def __get_item_reserved(item_id):
298
    all_inventory = CurrentInventorySnapshot.query.filter_by(item_id = item_id).all()
299
    reserved = 0
300
    for currInv in all_inventory:
301
        reserved = reserved + currInv.reserved
302
    return reserved
5966 rajveer 303
 
304
def __get_item_availability_at_warehouse(warehouse_id, item_id):
305
    inventory = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).one()
306
    return inventory.availability
307
 
308
def is_order_billable(item_id, warehouse_id, source_id, order_id):
309
    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()
310
    availability = __get_item_availability_at_warehouse(warehouse_id, item_id)
311
    for reservation in reservations:
312
        availability = availability - reservation.reserved
313
        if reservation.order_id == order_id and reservation.source_id == source_id:
314
            break
315
    if availability < 0:
316
        return False
317
    return True
5944 mandeep.dh 318
 
5966 rajveer 319
def reserve_item_in_warehouse(item_id, warehouse_id, source_id, order_id, created_timestamp, promised_shipping_timestamp, quantity):    
5944 mandeep.dh 320
    if not warehouse_id:
321
        raise InventoryServiceException(101, "bad warehouse_id")
322
 
323
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
324
    try:
325
        current_inventory_snapshot = query.one()
326
    except:
327
        current_inventory_snapshot = CurrentInventorySnapshot()
328
        current_inventory_snapshot.warehouse_id = warehouse_id
329
        current_inventory_snapshot.item_id = item_id
330
        current_inventory_snapshot.availability = 0
331
        current_inventory_snapshot.reserved = 0
332
 
333
    current_inventory_snapshot.reserved = current_inventory_snapshot.reserved + quantity
5966 rajveer 334
 
335
    reservation = CurrentReservationSnapshot()
336
    reservation.item_id = item_id
337
    reservation.warehouse_id = warehouse_id
338
    reservation.source_id = source_id
339
    reservation.order_id = order_id
5990 rajveer 340
    reservation.created_timestamp = to_py_date(created_timestamp)
341
    reservation.promised_shipping_timestamp = to_py_date(promised_shipping_timestamp)
5966 rajveer 342
    reservation.reserved = quantity
343
 
5944 mandeep.dh 344
    session.commit()
345
    #**Update item availability cache**#
5978 rajveer 346
    clear_item_availability_cache(item_id)
5944 mandeep.dh 347
    return True
348
 
5966 rajveer 349
def reduce_reservation_count(item_id, warehouse_id, source_id, order_id, quantity):
5944 mandeep.dh 350
    if not warehouse_id:
351
        raise InventoryServiceException(101, "bad warehouse_id")
352
 
353
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
354
    try:
355
        current_inventory_snapshot = query.one()
356
        current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
5966 rajveer 357
 
358
        reservation = CurrentReservationSnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id, source_id = source_id, order_id = order_id).one()
359
        if reservation.reserved == quantity:
360
            reservation.delete()
361
        else:
362
            reservation.reserved -= quantity
5944 mandeep.dh 363
        session.commit()
364
        #**Update item availability cache**#
5978 rajveer 365
        clear_item_availability_cache(item_id)
5944 mandeep.dh 366
        if current_inventory_snapshot.reserved < 0:
367
            item = __get_item_from_master(item_id)
368
            __send_alert_for_negative_reserved(item, current_inventory_snapshot.reserved, get_Warehouse(warehouse_id))
369
        return True
370
    except:
371
        print "Unexpected error:", sys.exc_info()[0]
372
        return False
373
 
5978 rajveer 374
def get_item_availability_for_location(item_id, source_id):
375
    item_availability = ItemAvailabilityCache.get_by(itemId=item_id, sourceId = source_id)
5944 mandeep.dh 376
    if item_availability:
377
        return [item_availability.warehouseId, item_availability.expectedDelay, item_availability.billingWarehouseId, item_availability.sellingPrice, item_availability.totalAvailability]
378
    else:
5978 rajveer 379
        __update_item_availability_cache(item_id, source_id)
380
            ##Check risky status for the source
381
        __check_risky_item(item_id, source_id)
382
        return get_item_availability_for_location(item_id, source_id)
5944 mandeep.dh 383
 
5978 rajveer 384
def clear_item_availability_cache(item_id = None):
385
    if item_id:
386
        ItemAvailabilityCache.query.filter_by(itemId = item_id).delete()
387
    else:
388
        ItemAvailabilityCache.query.delete()
5944 mandeep.dh 389
    session.commit()
390
 
5978 rajveer 391
def __update_item_availability_cache(item_id, source_id):
5944 mandeep.dh 392
    """
393
    Determines the warehouse that should be used to fulfil an order for the given item.
394
    Algorithm explained at https://sites.google.com/a/shop2020.in/virtual-w-h-and-inventory/technical-details
395
 
396
    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.
397
    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.
398
 
399
    if item available at any OUR-GOOD warehouse
400
        // OUR-GOOD warehouses have inventory risk; So, we empty them first! 
401
        // We can start with minimum transfer price criterion but down the line we can also bring in Inventory age 
402
        assign OUR-GOOD warehouse with minimum transfer price
403
    else
404
        if Preferred vendor is specified and marked Sticky
405
            // Always purchase from Preferred if its marked sticky
406
            assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
407
        else 
408
            if item available in a THIRDPARTY GOOD/VIRTUAL warehouse
409
                assign THIRDPARTY GOOD/VIRTUAL warehouse where item is available with minimal transfer delay followed by minimum transfer price
410
            else 
411
                // Item not available at any warehouse, OURS or THIRDPARTY
412
                If Preferred vendor is specified
413
                    assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
414
                else
415
                    assign THIRDPARTY GOOD/VIRTUAL warehouse with minimum transfer price
416
 
417
    Returns an ordered list of size 4 with following elements in the given order:
418
    1. Logistics location of the warehouse which was finally picked up to ship the order.
419
    2. Expected delay added by the category manager.
420
    3. Id of the warehouse which was finally picked up.
421
 
422
    Parameters:
423
     - itemId
424
    """
5978 rajveer 425
    item = __get_item_from_source(item_id, source_id)
5944 mandeep.dh 426
    item_pricing = {}
427
    for vendorItemPricing in VendorItemPricing.query.filter_by(item_id=item_id).all():
428
        item_pricing[vendorItemPricing.vendor_id] = vendorItemPricing
429
 
6510 rajveer 430
    ignoredWhs = get_ignored_warehouses(item_id)
431
 
5944 mandeep.dh 432
    warehouses = {}
433
    ourGoodWarehouses = {}
434
    thirdpartyWarehouses = {}
435
    preferredThirdpartyWarehouses = {}
436
    for warehouse in Warehouse.query.all():
437
        if (warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.BAD]):
438
            continue
439
        warehouses[warehouse.id] = warehouse
440
        if warehouse.warehouseType == WarehouseType._VALUES_TO_NAMES[WarehouseType.OURS]:
441
            if warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
442
                ourGoodWarehouses[warehouse.id] = warehouse
443
        else:
444
            thirdpartyWarehouses[warehouse.id] = warehouse
445
            if item.preferredVendor == warehouse.vendor_id and warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
446
                preferredThirdpartyWarehouses[warehouse.id] = warehouse
447
 
448
    warehouse_retid = -1
449
    total_availability = 0
450
 
6540 rajveer 451
    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(ourGoodWarehouses, ignoredWhs, item_id, item_pricing, False)
5944 mandeep.dh 452
    if warehouse_retid == -1:
453
        if item.preferredVendor and item.isWarehousePreferenceSticky:
6540 rajveer 454
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(preferredThirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 455
            if warehouse_retid == -1:
456
                warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
457
        else:
6540 rajveer 458
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 459
            if warehouse_retid == -1:
460
                if item.preferredVendor:
461
                    warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
462
                else:
6540 rajveer 463
                    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing, True)
5944 mandeep.dh 464
 
465
    warehouse = warehouses[warehouse_retid]
466
    billingWarehouseId = warehouse.billingWarehouseId
467
 
468
    # Fetching billing warehouse of a Good billable warehouse corresponding to the virtual one
469
    if not warehouse.billingWarehouseId:
470
        for w in Warehouse.query.filter_by(vendor_id = warehouse.vendor_id, inventoryType = InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]).all():
471
            if w.billingWarehouseId:
472
                billingWarehouseId = w.billingWarehouseId
473
                break
474
 
475
    expectedDelay = item.expectedDelay 
476
    if expectedDelay is None:
477
        print 'expectedDelay field for this item was Null. Resetting it to 0'
478
        expectedDelay = 0
479
    else:
480
        expectedDelay = int(item.expectedDelay)
481
 
482
    if total_availability <= 0:
6562 rajveer 483
        if item.preferredVendor in [1, 5]:
484
            expectedDelay = expectedDelay + 3
485
        else:
486
            expectedDelay = expectedDelay + 2
6643 rajveer 487
    else:
488
        if warehouse.transferDelayInHours:
489
            expectedDelay = expectedDelay + warehouse.transferDelayInHours / 24
5944 mandeep.dh 490
 
5963 mandeep.dh 491
    total_availability = 0
492
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
6545 rajveer 493
        if entry.warehouse_id not in ignoredWhs:
494
            total_availability += entry.availability - entry.reserved
5963 mandeep.dh 495
 
5978 rajveer 496
    item_availability_cache = ItemAvailabilityCache.get_by(itemId=item_id, sourceId=source_id)
5944 mandeep.dh 497
    if item_availability_cache is None:
498
        item_availability_cache = ItemAvailabilityCache()
499
        item_availability_cache.itemId = item_id
5978 rajveer 500
        item_availability_cache.sourceId = source_id
5944 mandeep.dh 501
    item_availability_cache.warehouseId = int(warehouse_retid)
502
    item_availability_cache.expectedDelay = expectedDelay
503
    item_availability_cache.billingWarehouseId = billingWarehouseId
504
    item_availability_cache.sellingPrice = item.sellingPrice
505
    item_availability_cache.totalAvailability = total_availability
506
    session.commit()
507
 
6540 rajveer 508
def __get_warehouse_with_min_transfer_price(warehouses, ignoredWhs, item_id, item_pricing, ignoreAvailability):
5944 mandeep.dh 509
    warehouse_retid = -1
510
    minTransferPrice = None
511
    total_availability = 0
6013 amar.kumar 512
    availabilityForBillingWarehouses = {}
513
    warehousesAvailability = {}
514
    availability = 0
515
    billing_warehouse_retid = None
5944 mandeep.dh 516
 
517
    if not ignoreAvailability:
518
        for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
6013 amar.kumar 519
            #if entry.availability > entry.reserved:
6542 rajveer 520
            warehousesAvailability[entry.warehouse_id] = [entry.availability, entry.reserved] 
5944 mandeep.dh 521
 
6540 rajveer 522
    if len(ignoredWhs) > 0:
523
        for whid in ignoredWhs:
524
            if warehousesAvailability.has_key(whid):
6542 rajveer 525
                warehousesAvailability[whid][0] = 0
6683 rajveer 526
                warehousesAvailability[whid][1] = 0
6540 rajveer 527
 
5944 mandeep.dh 528
    for warehouse in warehouses.values():
529
        if not ignoreAvailability:
6013 amar.kumar 530
            #TODO Mistake no entry for this warehouse.id in warehouseswithAvailab
531
            if warehouse.id not in warehousesAvailability:
532
                continue
533
            entry = warehousesAvailability[warehouse.id]
534
            if warehouse.billingWarehouseId in availabilityForBillingWarehouses:
535
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
6544 rajveer 536
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = availabilityForBillingWarehouses[warehouse.billingWarehouseId] + entry[0] - entry[1]  
5944 mandeep.dh 537
            else:
6013 amar.kumar 538
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
6542 rajveer 539
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = entry[0] - entry[1]
540
            if entry[0] <= entry[1]:
5944 mandeep.dh 541
                continue
6542 rajveer 542
            total_availability += entry[0] - entry[1]
5944 mandeep.dh 543
 
544
        # Missing transfer price cases should not impact warehouse assignment
545
        transferPrice = None
546
        if item_pricing.has_key(warehouse.vendor_id):
6778 rajveer 547
            transferPrice = item_pricing[warehouse.vendor_id].nlc
5944 mandeep.dh 548
        if minTransferPrice is None or (transferPrice and minTransferPrice > transferPrice):
549
            warehouse_retid = warehouse.id
6013 amar.kumar 550
            billing_warehouse_retid = warehouse.billingWarehouseId
5944 mandeep.dh 551
            minTransferPrice = transferPrice
6013 amar.kumar 552
 
553
 
554
    if billing_warehouse_retid in availabilityForBillingWarehouses: 
555
        availability = availabilityForBillingWarehouses[billing_warehouse_retid]
556
    else:
557
        availability = total_availability
558
 
559
    return [warehouse_retid, availability]
5944 mandeep.dh 560
 
6540 rajveer 561
def __get_warehouse_with_min_transfer_delay(warehouses, ignoredWhs, item_id, item_pricing):
5944 mandeep.dh 562
    minTransferDelay = None
563
    minTransferDelayWarehouses = {}
564
    total_availability = 0
565
 
566
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
567
        if warehouses.has_key(entry.warehouse_id):
568
            warehouse = warehouses[entry.warehouse_id]
6013 amar.kumar 569
            #if entry.availability > entry.reserved:
6683 rajveer 570
            if entry.warehouse_id not in ignoredWhs:
571
                total_availability += entry.availability - entry.reserved
6780 amar.kumar 572
            if entry.availability - entry.reserved <= 0:
573
                continue
6013 amar.kumar 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):
6778 rajveer 646
        tp_total = 0
647
        nlc_total = 0
5944 mandeep.dh 648
        try:
649
            item_pricings = []
650
            item = __get_item_from_master(item_id)
651
            if item.preferredVendor is not None:
652
                item_pricing = VendorItemPricing.query.filter_by(item_id=item_id, vendor_id=item.preferredVendor).first()
653
                if item_pricing:
654
                    item_pricings.append(item_pricing)                    
655
            else :
656
                item_pricings = VendorItemPricing.query.filter_by(item_id=item_id).all()
657
            if item_pricings:
658
                for item_pricing in item_pricings:
6778 rajveer 659
                    tp_total += item_pricing.transfer_price
660
                    nlc_total += item_pricing.nlc
661
                tp_avg = tp_total / len(item_pricings)
662
                nlc_avg = nlc_total / len(item_pricings)
663
                item_pricing.transfer_price = tp_avg
664
                item_pricing.nlc = nlc_avg
5944 mandeep.dh 665
            else:
666
                item_pricing = VendorItemPricing()
667
                item_pricing.transfer_price = item.sellingPrice
6778 rajveer 668
                item_pricing.nlc = item.sellingPrice
5944 mandeep.dh 669
                vendor = Vendor()
670
                vendor.id = vendorId
671
                item_pricing.vendor = vendor
672
                item_pricing.item_id = item_id
673
 
674
            return item_pricing
675
        except:
676
            raise InventoryServiceException(101, "Item pricing not found ")
677
    vendor = Vendor.get_by(id=vendorId)    
678
    try:
679
        item_pricing = VendorItemPricing.query.filter_by(vendor=vendor, item_id=item_id).one()
680
        return item_pricing
681
    except MultipleResultsFound:
682
        raise InventoryServiceException(110, "Multiple pricing information present for Vendor: " + vendor.name + " and Item: " + str(item_id))
683
    except NoResultFound:
684
        raise InventoryServiceException(111, "Missing pricing information for Vendor: " + vendor.name + " and Item: " + str(item_id))
685
 
686
def get_all_item_pricing(item_id):
687
    item_pricing = VendorItemPricing.query.filter_by(item_id=item_id).all()
688
    return item_pricing
689
 
690
def get_item_mappings(item_id):
691
    item_mappings = VendorItemMapping.query.filter_by(item_id=item_id).all()
692
    return item_mappings
693
 
694
def add_vendor_pricing(vendorItemPricing):
695
    if not vendorItemPricing:
696
        raise InventoryServiceException(108, "Bad vendorItemPricing in request")
697
    vendorId = vendorItemPricing.vendorId
698
    itemId = vendorItemPricing.itemId
699
 
700
    try:
701
        vendor = Vendor.query.filter_by(id=vendorId).one()
702
    except:
703
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
704
 
705
    try:
706
        item = __get_item_from_master(itemId)
707
    except:
708
        raise InventoryServiceException(101, "Item not found for itemId " + str(itemId))
709
 
710
    validate_vendor_prices(item, vendorItemPricing)
711
 
712
    try:
713
        ds_vendorItemPricing = VendorItemPricing.query.filter(and_(VendorItemPricing.vendor==vendor, VendorItemPricing.item_id==itemId)).one()
714
    except:
715
        ds_vendorItemPricing = VendorItemPricing()
716
        ds_vendorItemPricing.vendor = vendor
717
        ds_vendorItemPricing.item_id = itemId
718
 
719
    subject = ""
720
    message = ""
721
    if vendorItemPricing.mop:
722
        ds_vendorItemPricing.mop = vendorItemPricing.mop
723
    if vendorItemPricing.dealerPrice:
724
        ds_vendorItemPricing.dealerPrice = vendorItemPricing.dealerPrice
725
    if vendorItemPricing.transferPrice:
726
        if vendorItemPricing.transferPrice != ds_vendorItemPricing.transfer_price:
6617 amar.kumar 727
            client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
728
            item = client.getItem(itemId)
729
            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 730
            subject = "Alert:Change in Transfer Price {0} {1} {2} {3} {4}".format(item.brand, item.modelName, item.modelNumber, item.color, itemId)
5944 mandeep.dh 731
        ds_vendorItemPricing.transfer_price = vendorItemPricing.transferPrice
6751 amar.kumar 732
    if vendorItemPricing.nlc:
733
        if vendorItemPricing.nlc != ds_vendorItemPricing.nlc:
734
            client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
735
            item = client.getItem(itemId)
736
            message = "NLC 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)
737
            subject = "Alert:Change in NLC {0} {1} {2} {3} {4}".format(item.brand, item.modelName, item.modelNumber, item.color, itemId)
738
        ds_vendorItemPricing.nlc = vendorItemPricing.nlc
5944 mandeep.dh 739
 
740
    session.commit()
741
    if subject:
742
        __send_mail(subject, message)
743
    return
744
 
745
def add_vendor_item_mapping(key, vendorItemMapping):
746
    if not vendorItemMapping:
747
        raise InventoryServiceException(108, "Bad vendorItemMapping in request")
748
    vendorId = vendorItemMapping.vendorId
749
    itemId = vendorItemMapping.itemId
750
 
751
    try:
752
        vendor = Vendor.query.filter_by(id=vendorId).one()
753
    except:
754
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
755
 
756
    try:
757
        ds_vendorItemMapping = VendorItemMapping.query.filter(and_(VendorItemMapping.vendor==vendor, VendorItemMapping.item_id==itemId, VendorItemMapping.item_key==key)).one()
758
    except:
759
        ds_vendorItemMapping = VendorItemMapping()
760
        ds_vendorItemMapping.vendor = vendor
761
        ds_vendorItemMapping.item_id = itemId
762
    ds_vendorItemMapping.item_key = vendorItemMapping.itemKey
763
 
764
    session.commit()
765
 
766
    # Marking the missed inventory as not ignored as the catalog dashboard user has updated their key
767
    for missedInventoryUpdate in MissedInventoryUpdate.query.filter_by(itemKey = vendorItemMapping.itemKey).all():
768
        missedInventoryUpdate.isIgnored = 0
769
    session.commit()
770
 
771
    return
772
 
773
def validate_vendor_prices(item, vendorPrices):
774
    if item.mrp != None and item.mrp != "" and vendorPrices.mop != "" and item.mrp <  vendorPrices.mop:
775
        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))
776
        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)))
777
    if vendorPrices.mop != "" and vendorPrices.transferPrice != "" and vendorPrices.transferPrice > vendorPrices.mop:
778
        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))
779
        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)))
780
    return
781
 
782
def get_all_vendors():
783
    return Vendor.query.all()
784
 
785
def get_pending_orders_inventory(vendor_id=1):
786
    """
787
    Returns a list of inventory stock for items for which there are pending orders.
788
    """
789
 
790
    warehouse_ids = [warehouse.id for warehouse in Warehouse.query.filter_by(vendor_id = vendor_id)]
791
    pending_items_inventory = []
792
    if warehouse_ids:
793
        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()
794
    return pending_items_inventory
795
 
796
def close_session():
797
    if session.is_active:
798
        print "session is active. closing it."
799
        session.close()
800
 
801
def is_alive():
802
    try:
803
        session.query(Vendor.id).limit(1).one()
804
        return True
805
    except:
806
        return False
807
 
808
def add_vendor(vendor):
809
    if not vendor:
810
        raise InventoryServiceException(108, "Bad vendor")
811
    if get_vendor(vendor.id):
812
        #vendor is already present.
813
        raise InventoryServiceException(101, "Vendor already present")
814
 
815
    ds_vendor = Vendor()
816
    ds_vendor.id = vendor.id
817
    ds_vendor.name = vendor.name
818
    session.commit()
819
    return ds_vendor.id
820
 
821
def add_warehouse_vendor_mapping(warehouse_id, VendorId):
822
    return True
823
 
824
def mark_missed_inventory_updates_as_processed(itemKey, warehouseId):
825
    MissedInventoryUpdate.query.filter_by(itemKey = itemKey, warehouseId = warehouseId).delete()
826
    session.commit()
827
 
828
def get_item_keys_to_be_processed(warehouseId):
829
    return [i.itemKey for i in MissedInventoryUpdate.query.filter_by(warehouseId = warehouseId, isIgnored = 0)]
830
 
831
def reset_availability(itemKey, vendorId, quantity, warehouseId):
832
    vendorItemMapping = VendorItemMapping.get_by(vendor_id = vendorId, item_key = itemKey)
833
    if vendorItemMapping:
834
        itemId = vendorItemMapping.item_id
835
 
836
        if skippedItems.has_key(warehouseId) and itemId in skippedItems[warehouseId]:
837
            quantity = 0
838
 
839
        currentInventorySnapshot = CurrentInventorySnapshot.get_by(item_id = itemId, warehouse_id = warehouseId)
840
        if currentInventorySnapshot:
841
            currentInventorySnapshot.availability = quantity
5978 rajveer 842
            clear_item_availability_cache(itemId) 
5944 mandeep.dh 843
        else:
844
            add_inventory(itemId, warehouseId, quantity)
845
 
846
    else:
847
        raise InventoryServiceException(101, 'VendorMapping not found for: ' + itemKey)
848
    session.commit()
849
 
850
def reset_availability_for_warehouse(warehouseId):
851
    for currentInventorySnapshot in CurrentInventorySnapshot.query.filter_by(warehouse_id=warehouseId).all():
852
        currentInventorySnapshot.availability = 0
5978 rajveer 853
        clear_item_availability_cache(currentInventorySnapshot.item_id) 
5944 mandeep.dh 854
    session.commit()
855
 
6467 amar.kumar 856
def get_our_warehouse_id_for_vendor(vendor_id):
857
    try:
858
        warehouse = Warehouse.query.filter_by(vendor_id = vendor_id, warehouseType = 'OURS', inventoryType = 'GOOD').first()
859
        return warehouse.id
860
    except Exception as e:
861
        print e;
862
        raise InventoryServiceException(101, 'No our warehouse found for vendorId: ' + vendor_id)
5944 mandeep.dh 863
 
864
def __send_mail(subject, message):
865
    try:
6029 rajveer 866
        thread = threading.Thread(target=partial(mail, mail_user, mail_password, to_addresses, subject, message))
5944 mandeep.dh 867
        thread.start()
868
    except Exception as ex:
869
        print ex    
870
 
871
def get_shipping_locations():
872
    shippingLocationIds = {}
873
    warehouses = Warehouse.query.all()
874
    for warehouse in warehouses:
875
        if warehouse.shippingWarehouseId:
876
            shippingLocationIds[warehouse.shippingWarehouseId] = 1
877
 
878
    shippingLocations = []
879
    for shippingLocationId in shippingLocationIds:
880
        shippingLocations.append(get_Warehouse(shippingLocationId))
881
 
882
    return shippingLocations
883
 
884
def get_inventory_snapshot(warehouseId):
885
    query = CurrentInventorySnapshot.query
886
 
887
    if warehouseId:
888
        query = query.filter_by(warehouse_id = warehouseId)
889
 
890
    itemInventoryMap = {}
891
    for row in query.all():
892
        if not itemInventoryMap.has_key(row.item_id):
893
            itemInventoryMap[row.item_id] = []
894
 
895
        itemInventoryMap[row.item_id].append(row)
896
 
897
    return itemInventoryMap
898
 
899
def update_vendor_string(warehouseId, vendorString):
900
    warehouse = get_Warehouse(warehouseId)
901
    warehouse.vendorString = vendorString
902
    session.commit()
903
 
904
def __get_item_from_master(item_id):
905
    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
5978 rajveer 906
    return client.getItem(item_id)
907
 
908
def __check_risky_item(item_id, source_id):
909
    ## We should get the list of strings which will identify to the catalog servers
910
    if source_id == 1:
911
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
912
        client.validateRiskyStatus(item_id)
913
    if source_id == 2:
914
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
915
        client.validateRiskyStatus(item_id)
916
 
917
def __get_item_from_source(item_id, source_id):
918
    if source_id == 1:
919
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
920
        return client.getItem(item_id)
921
    if source_id == 2:
922
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
6531 vikram.rag 923
        return client.getItem(item_id)
924
 
925
def get_monitored_warehouses_for_vendors(vendorIds):
926
    w = []
927
    for wh in Warehouse.query.filter_by(isAvailabilityMonitored = 1).all():
928
        if wh.vendor.id in (vendorIds):
929
            w.append(to_t_warehouse(wh).id)
930
    return w
931
def get_ignored_warehouseids_and_itemids():
932
    iw = []
933
    for i in IgnoredInventoryUpdateItems.query.all():
934
        iw.append(to_t_itemidwarehouseid(i)) 
935
    return iw
936
def insert_item_to_ignore_inventory_update_list(item_id,warehouse_id):
937
    try:
938
        ds_warehouse=IgnoredInventoryUpdateItems()
939
        ds_warehouse.item_id=item_id
940
        ds_warehouse.warehouse_id=warehouse_id
6532 amit.gupta 941
        clear_item_availability_cache(item_id)
6531 vikram.rag 942
        session.commit()
943
        return True
944
    except:
945
        return False       
946
def delete_item_from_ignore_inventory_update_list(item_id,warehouse_id):
947
    try:
948
        session.query(IgnoredInventoryUpdateItems).filter_by(item_id=item_id,warehouse_id=warehouse_id).delete()
6532 amit.gupta 949
        clear_item_availability_cache(item_id)
6531 vikram.rag 950
        session.commit()
951
        return True
952
    except:
953
        return False           
954
 
955
def get_all_ignored_inventoryupdate_items_count():
956
    return  session.query(func.count(distinct(IgnoredInventoryUpdateItems.item_id))).scalar()
957
 
958
def get_ignored_inventoryupdate_itemids(offset=0,limit=None):
959
    itemIds = session.query(distinct(IgnoredInventoryUpdateItems.item_id))
960
    '''if limit is not None:
961
        itemIds = itemIds.limit(limit)'''
962
    print itemIds.all()
963
    return [id for (id, ) in itemIds.all()]
964