Subversion Repositories SmartDukaan

Rev

Rev 22720 | Rev 22722 | 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
19413 amit.gupta 9
from shop2020.clients.LogisticsClient import LogisticsClient
5944 mandeep.dh 10
from shop2020.clients.TransactionClient import TransactionClient
11
from shop2020.model.v1.inventory.impl import DataService
6531 vikram.rag 12
from shop2020.model.v1.inventory.impl.Convertors import to_t_warehouse, \
19413 amit.gupta 13
    to_t_itemidwarehouseid, to_t_state, to_t_item_location_availability
5944 mandeep.dh 14
from shop2020.model.v1.inventory.impl.DataService import Warehouse, \
15
    ItemInventoryHistory, CurrentInventorySnapshot, VendorItemPricing, \
16
    VendorItemMapping, Vendor, MissedInventoryUpdate, BadInventorySnapshot, \
19413 amit.gupta 17
    VendorHolidays, ItemAvailabilityCache, CurrentReservationSnapshot, \
18
    IgnoredInventoryUpdateItems, ItemStockPurchaseParams, OOSStatus, \
19
    AmazonInventorySnapshot, StateMaster, HoldInventoryDetail, \
20
    AmazonFbaInventorySnapshot, SnapdealInventorySnapshot, FlipkartInventorySnapshot, \
21
    SnapdealStockAtEOD, FlipkartStockAtEOD, StockWeightedNlcInfo, \
22
    ItemLocationAvailabilityCache
6531 vikram.rag 23
from shop2020.thriftpy.model.v1.inventory.ttypes import \
19413 amit.gupta 24
    InventoryServiceException, HolidayType, InventoryType, WarehouseType,\
25
    ItemLocationAvailability, ItemPincodeAvailability
5944 mandeep.dh 26
from shop2020.thriftpy.model.v1.order.ttypes import AlertType
6531 vikram.rag 27
from shop2020.thriftpy.purchase.ttypes import PurchaseServiceException
5944 mandeep.dh 28
from shop2020.utils import EmailAttachmentSender
29
from shop2020.utils.EmailAttachmentSender import mail
6821 amar.kumar 30
from shop2020.utils.Utils import to_py_date, to_java_date
5944 mandeep.dh 31
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
7410 amar.kumar 32
from sqlalchemy.sql import or_
12363 kshitij.so 33
from sqlalchemy.sql.expression import and_, func, distinct, desc
6531 vikram.rag 34
from sqlalchemy.sql.functions import count
5944 mandeep.dh 35
import calendar
36
import datetime
19413 amit.gupta 37
import math
5944 mandeep.dh 38
import sys
39
import threading
19413 amit.gupta 40
import json
41
from shop2020.thriftpy.logistics.ttypes import LocationInfo
5944 mandeep.dh 42
 
10687 rajveer 43
to_addresses = ["khushal.bhatia@shop2020.in", "chaitnaya.vats@shop2020.in", "chandan.kumar@shop2020.in",'manoj.kumar@shop2020.in']
6029 rajveer 44
mail_user = "cnc.center@shop2020.in"
45
mail_password = "5h0p2o2o"
5944 mandeep.dh 46
skippedItems = { 175 : [27, 2160, 2175, 2163, 2158, 7128, 26, 2154],
47
                 193 : [5839] }
48
 
19413 amit.gupta 49
pincodePricingServiceabilityMap = {}
50
warehouseMap = {}
51
logisticsLocationWarehouseMap = {}
52
 
6821 amar.kumar 53
OOS_CALCULATION_TIME = 23
22721 amit.gupta 54
physicalWarehouseIdsForFofo = [7678, 7681]
6498 vikram.rag 55
 
19413 amit.gupta 56
last_date = datetime.date.today()
57
adjusted_dates={}
58
 
5944 mandeep.dh 59
def initialize(dbname='inventory', db_hostname="localhost"):
60
    DataService.initialize(dbname, db_hostname)
19413 amit.gupta 61
    __populateWarehouseMap()
5944 mandeep.dh 62
 
19413 amit.gupta 63
def __populateWarehouseMap():
64
    warehouses = Warehouse.query.filter(Warehouse.warehouseType.in_(['OURS', 'THIRD_PARTY'])).filter(Warehouse.inventoryType == 'GOOD').all()
65
    for warehouse in warehouses:
66
        warehouseMap[warehouse.id] = warehouse
67
        if not logisticsLocationWarehouseMap.has_key(warehouse.logisticsLocation):
68
            logisticsLocationWarehouseMap[warehouse.logisticsLocation] = []
69
        logisticsLocationWarehouseMap[warehouse.logisticsLocation].append(warehouse.id)
70
 
71
 
5944 mandeep.dh 72
def get_Warehouse(warehouse_id):
73
    return Warehouse.get_by(id=warehouse_id)
74
 
75
def get_vendor(vendorId):
76
    return Vendor.get_by(id=vendorId)
77
 
7410 amar.kumar 78
def get_state(stateId):
79
    return StateMaster.get_by(id=stateId)
80
 
5944 mandeep.dh 81
def get_all_warehouses_by_status(status):
82
    return Warehouse.query.all()
83
 
84
def get_all_items_for_warehouse(warehouse_id):
85
    warehouse = get_Warehouse(warehouse_id)
86
    if not warehouse:
87
        raise InventoryServiceException(108, "bad warehouse")
88
    return warehouse.all_items
89
 
90
def add_warehouse(warehouse):
91
    if not warehouse:
92
        raise InventoryServiceException(108, "Bad warehouse")
93
    if get_Warehouse(warehouse.id):
94
        #warehouse is already present.
95
        raise InventoryServiceException(101, "Warehouse already present")
96
 
97
    ds_warehouse = Warehouse()
98
    ds_warehouse.location = warehouse.location
99
    ds_warehouse.status = 3
100
    ds_warehouse.addedOn = datetime.datetime.now()
101
    ds_warehouse.lastCheckedOn = datetime.datetime.now()
102
    ds_warehouse.tinNumber = warehouse.tinNumber
103
    ds_warehouse.pincode = warehouse.pincode
104
    ds_warehouse.billingType = warehouse.billingType
105
    ds_warehouse.billingWarehouseId = warehouse.billingWarehouseId
106
    ds_warehouse.displayName = warehouse.displayName
107
    ds_warehouse.inventoryType = InventoryType._VALUES_TO_NAMES[warehouse.inventoryType]
108
    ds_warehouse.isAvailabilityMonitored = warehouse.isAvailabilityMonitored
109
    ds_warehouse.logisticsLocation = warehouse.logisticsLocation
110
    ds_warehouse.shippingWarehouseId = warehouse.shippingWarehouseId
111
    ds_warehouse.transferDelayInHours = warehouse.transferDelayInHours
112
    ds_warehouse.vendor = get_vendor(warehouse.vendor.id)
7410 amar.kumar 113
    ds_warehouse.state = get_state(warehouse.stateId)
5944 mandeep.dh 114
    ds_warehouse.warehouseType = WarehouseType._VALUES_TO_NAMES[warehouse.warehouseType]    
115
    if warehouse.vendorString:
116
        ds_warehouse.vendorString = warehouse.vendorString
117
    session.commit()
118
    return ds_warehouse.id
119
 
6498 vikram.rag 120
def get_ignored_items(warehouse_id): 
6531 vikram.rag 121
    Ignored_inventory_items = IgnoredInventoryUpdateItems.query.filter_by(warehouse_id=warehouse_id).all()
6498 vikram.rag 122
    negativeItems = []
123
    for Ignored_inventory_item in Ignored_inventory_items:
124
        try:
125
            item_id = Ignored_inventory_item.item_id
126
            negativeItems.append(item_id)
127
        except:
128
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
129
    return negativeItems
130
 
22630 amit.gupta 131
def get_ignored_warehouses(item_id):
132
    warehouses = []
133
    #No item availability cache for Hotspot Specific Store
134
    #No virtual is allowed
22632 amit.gupta 135
#    hotspotPhysicalWarehouses = [7678, 7681]
136
#    hotspotVendorWarehouses = Warehouse.query.filter(Warehouse.billingWarehouseId.in_(hotspotPhysicalWarehouses)).filter(Warehouse.inventoryType=='GOOD').all()
137
#    for warehouse in hotspotVendorWarehouses:
138
#        warehouses.append(warehouse.id)
6539 amit.gupta 139
    Ignored_inventory_items = IgnoredInventoryUpdateItems.query.filter_by(item_id=item_id).all()
6510 rajveer 140
    for Ignored_inventory_item in Ignored_inventory_items:
141
        warehouses.append(Ignored_inventory_item.warehouse_id)
142
    return warehouses
143
 
5944 mandeep.dh 144
def update_inventory_history(warehouse_id, timestamp, availability):
145
    warehouse = get_Warehouse(warehouse_id)
146
    if not warehouse:
147
        raise InventoryServiceException(107, "Warehouse? Where?")
148
    vendor = warehouse.vendor
149
    time = datetime.datetime.now()
150
    for item_key, quantity in availability.iteritems():
151
        try:
152
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
5960 mandeep.dh 153
            item_id = vendor_item_mapping.item_id
5944 mandeep.dh 154
        except:
6531 vikram.rag 155
            continue  
5944 mandeep.dh 156
        try:
6510 rajveer 157
            item_inventory_history = ItemInventoryHistory()
158
            item_inventory_history.warehouse = warehouse
159
            item_inventory_history.item_id = item_id
160
            item_inventory_history.timestamp = time
161
            item_inventory_history.availability = quantity
5944 mandeep.dh 162
        except:
163
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
164
    session.commit()
165
 
166
def update_inventory(warehouse_id, timestamp, availability):
167
    warehouse = get_Warehouse(warehouse_id)
168
    if not warehouse:
169
        raise InventoryServiceException(107, "Warehouse? Where?")
6510 rajveer 170
 
5944 mandeep.dh 171
    time = datetime.datetime.now()
172
    warehouse.lastCheckedOn = time
173
    warehouse.vendorString = timestamp
174
    vendor = warehouse.vendor
175
    item_ids = []
176
    for item_key, quantity in availability.iteritems():
177
        try:
178
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
179
            item_id = vendor_item_mapping.item_id
6510 rajveer 180
            item_ids.append(item_id)
5944 mandeep.dh 181
        except:
182
            print 'Skipping update for ' + item_key + ' quantity ' + str(quantity) + ' warehouse id: ' + str(warehouse_id)
183
            __send_mail_for_missing_key(item_key, quantity, warehouse_id)
184
            continue
185
        try:
186
            current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=item_id, warehouse=warehouse)
187
            if not current_inventory_snapshot:
188
                current_inventory_snapshot = CurrentInventorySnapshot()
189
                current_inventory_snapshot.item_id = item_id
190
                current_inventory_snapshot.warehouse = warehouse
191
                current_inventory_snapshot.availability = 0
192
                current_inventory_snapshot.reserved = 0
8204 amar.kumar 193
                current_inventory_snapshot.held = 0
5944 mandeep.dh 194
            # added the difference in the current inventory    
195
            current_inventory_snapshot.availability = current_inventory_snapshot.availability + quantity
196
            item = __get_item_from_master(item_id)
197
            try:
198
                if quantity > 0 and __get_item_reserved(item_id) > 0:
199
                    cl = TransactionClient().get_client()
200
                    #FIXME hardcoding for warehouse id 
201
                    cl.addAlert(AlertType.NEW_INVENTORY_ALERT, 5, "Inventory received for item " + item.brand + " " + item.modelName + " " + item.modelNumber + " " +  item.color)
202
            except:
203
                print "Not able to raise alert for incoming inventory" 
204
            if current_inventory_snapshot.availability < 0:
205
                __send_alert_for_negative_availability(item, current_inventory_snapshot.availability, warehouse)
206
        except:
207
            print "Some unforeseen error while updating inventory:", sys.exc_info()[0]
208
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
209
    session.commit()
210
 
211
    #**Update item availability cache**#
212
    for item_id in item_ids:
5978 rajveer 213
        clear_item_availability_cache(item_id)
5944 mandeep.dh 214
 
215
def __send_alert_for_negative_reserved(item, reserved, warehouse):
216
    itemName = " ".join([str(item.id), str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
10253 manish.sha 217
    EmailAttachmentSender.mail(mail_user, mail_password, 'manish.sharma@shop2020.in', 'Negative reserved: ' + str(reserved) + ' for Item Id: ' + itemName + ' warehouse id: ' + str(warehouse.id), None)
5944 mandeep.dh 218
 
219
def __send_alert_for_negative_availability(item, availability, warehouse):
220
    itemName = " ".join([str(item.id), str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
5964 amar.kumar 221
    # 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 222
 
223
def __send_mail_for_missing_key(item_key, quantity, warehouse_id):
224
    missedInventoryUpdate = MissedInventoryUpdate.get_by(itemKey = item_key, warehouseId = warehouse_id)
225
    # One email per product key mismatch
226
    if not missedInventoryUpdate:
227
        missedInventoryUpdate = MissedInventoryUpdate()
228
        missedInventoryUpdate.itemKey = item_key
229
        missedInventoryUpdate.quantity = quantity
230
        missedInventoryUpdate.isIgnored = 1
231
        missedInventoryUpdate.timestamp = datetime.datetime.now()
232
        missedInventoryUpdate.warehouseId = warehouse_id
233
        session.commit()
6232 rajveer 234
        try:
8214 amar.kumar 235
            EmailAttachmentSender.mail(mail_user, mail_password, ['chaitnaya.vats@shop2020.in', 'chandan.kumar@shop2020.in', 'khushal.bhatia@shop2020.in', 'manoj.kumar@shop2020.in'], 'Skipped inventory update for ' + item_key + ' quantity ' + str(quantity) + ' warehouse id: ' + str(warehouse_id), None)
6232 rajveer 236
        except:
237
            print "Not able to send email. No issues, we can continue with updates."
5944 mandeep.dh 238
    else:
239
        missedInventoryUpdate.quantity += quantity
240
        session.commit()
241
 
19989 kshitij.so 242
def add_inventory(itemId, warehouseId, quantity, skipAddition=False):
5944 mandeep.dh 243
    current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
244
    if not current_inventory_snapshot:
245
        current_inventory_snapshot = CurrentInventorySnapshot()
246
        current_inventory_snapshot.item_id = itemId
247
        current_inventory_snapshot.warehouse_id = warehouseId
248
        current_inventory_snapshot.availability = 0
249
        current_inventory_snapshot.reserved = 0
8204 amar.kumar 250
        current_inventory_snapshot.held = 0
19989 kshitij.so 251
    # added the difference in the current inventory
252
    if skipAddition is None or not skipAddition:    
253
        current_inventory_snapshot.availability = current_inventory_snapshot.availability + quantity
254
    else:
255
        current_inventory_snapshot.availability = quantity
5944 mandeep.dh 256
    session.commit()
257
    #**Update item availability cache**#
20849 amit.gupta 258
    clear_item_availability_cache(itemId)
5944 mandeep.dh 259
    if current_inventory_snapshot.availability < 0:
260
        item = __get_item_from_master(itemId)
5978 rajveer 261
        __send_alert_for_negative_availability(item, current_inventory_snapshot.availability, get_Warehouse(warehouseId)) 
5944 mandeep.dh 262
 
263
def add_bad_inventory(itemId, warehouseId, quantity):
264
    bad_inventory_snapshot = BadInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
265
    if not bad_inventory_snapshot:
266
        bad_inventory_snapshot = BadInventorySnapshot()
267
        bad_inventory_snapshot.item_id = itemId
268
        bad_inventory_snapshot.warehouse_id = warehouseId
269
        bad_inventory_snapshot.availability = 0
270
    # added the difference in the current inventory    
271
    bad_inventory_snapshot.availability += quantity
272
    session.commit()
273
    if bad_inventory_snapshot.availability < 0:
274
        item = __get_item_from_master(itemId)
275
        __send_alert_for_negative_availability(item, bad_inventory_snapshot.availability, get_Warehouse(warehouseId))
276
 
277
def get_item_inventory_by_item_id(item_id):
278
    return CurrentInventorySnapshot.query.filter_by(item_id=item_id).all()
279
 
280
def retire_warehouse(warehouse_id):
281
    if not warehouse_id:
282
        raise InventoryServiceException(101, "Bad warehouse id")
283
    warehouse = get_Warehouse(warehouse_id)
284
    if not warehouse:
285
        raise InventoryServiceException(108, "warehouse id not present")
286
    warehouse.status = 0;
287
    session.commit()
288
 
289
def get_item_availability_for_warehouse(warehouse_id, item_id):
6545 rajveer 290
    ignore = IgnoredInventoryUpdateItems.query.filter_by(item_id=item_id).filter_by(warehouse_id = warehouse_id).all()
6544 rajveer 291
    if ignore:
292
        return 0
5944 mandeep.dh 293
 
294
    try:
6544 rajveer 295
        current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id).filter_by(item_id = item_id).one()
15958 amit.gupta 296
        return current_inventory_snapshot.availability - current_inventory_snapshot.reserved - current_inventory_snapshot.held
5944 mandeep.dh 297
    except:
298
        return 0
299
 
6484 amar.kumar 300
def get_item_availability_for_our_warehouses(item_ids):
7699 amar.kumar 301
    our_warehouses = Warehouse.query.filter_by(warehouseType = 'OURS', inventoryType = 'GOOD').all()
302
    our_thirdparty_warehouses = Warehouse.query.filter_by(warehouseType = 'OURS_THIRDPARTY').all()
6484 amar.kumar 303
    warehouse_ids = []
7699 amar.kumar 304
    for warehouse in our_warehouses :
6484 amar.kumar 305
        warehouse_ids.append(warehouse.id)
10170 amar.kumar 306
    #for warehouse in our_thirdparty_warehouses :
307
    #    warehouse_ids.append(warehouse.id)
7699 amar.kumar 308
 
6484 amar.kumar 309
    availability_map = dict()
310
 
311
    try :
312
        for item_id in item_ids :
313
            total_availability = 0
314
            for current_inventory_snapshot in CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).filter_by(item_id = item_id).all():
315
                total_availability += current_inventory_snapshot.availability
316
            if total_availability >0:
317
                availability_map[item_id] = total_availability
318
    except Exception as e:
319
        print e
320
        raise PurchaseServiceException(101, 'Exception while fetching availability of items in our warehouses')
321
 
322
    return availability_map
323
 
22719 amit.gupta 324
def get_fofo_availability(item_ids):
22721 amit.gupta 325
    #TODO: Amit Should be removed physicalWarehouseIdsForFofo
22719 amit.gupta 326
    returnMap = {}
327
    if not item_ids:
328
        return returnMap
22720 amit.gupta 329
    fofoWarehouses = Warehouse.query.filter(Warehouse.warehouseType.in_(['OURS', 'THIRD_PARTY'])).filter(Warehouse.inventoryType == 'GOOD').filter(Warehouse.billingWarehouseId.in_(physicalWarehouseIdsForFofo)).all()
22719 amit.gupta 330
    warehouse_ids = []
331
    for fofoWarehouse in fofoWarehouses:
332
        warehouse_ids.append(fofoWarehouse.id)
333
    snapshots = CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).filter(CurrentInventorySnapshot.item_id.in_(item_ids)).all()
334
    for snapshot in snapshots:
335
        if returnMap.has_key(snapshot.item_id):
336
            returnMap[snapshot.item_id] += snapshot.availability - snapshot.reserved - snapshot.held
337
        else:
338
            returnMap[snapshot.item_id] = snapshot.availability - snapshot.reserved - snapshot.held 
339
    return returnMap
340
 
22721 amit.gupta 341
def get_fofo_fulfilment_warehouse_map(itemIds):
342
    returnMap = {}
343
    fofoWarehouses = Warehouse.query.filter(Warehouse.warehouseType.in_(['OURS', 'THIRD_PARTY'])).filter(Warehouse.inventoryType == 'GOOD').filter(Warehouse.billingWarehouseId.in_(physicalWarehouseIdsForFofo)).all()
344
    warehouse_ids = []
345
    for fofoWarehouse in fofoWarehouses:
346
        warehouse_ids.append(fofoWarehouse.id)
347
    snapshots = CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).filter(CurrentInventorySnapshot.item_id.in_(itemIds)).all()
348
    for snapshot in snapshots:
349
        availability = snapshot.availability - snapshot.reserved - snapshot.held
350
        if availability > 0:
351
            if not returnMap.has_key(snapshot.item_id):
352
                returnMap[snapshot.item_id] = to_t_warehouse(snapshot.warehouse)
353
    return returnMap 
354
 
355
 
356
 
5944 mandeep.dh 357
'''
358
This method returns quantity of a particular item across all warehouses whose ids is provided
359
if warehouse_ids is null it checks for inventory in all warehouses.
360
'''
361
def __get_item_availability(item, warehouse_ids):
362
    if warehouse_ids is None:
363
        all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
364
        availability = 0
365
        reserved = 0
366
        for currInv in all_inventory:
367
            availability = availability + currInv.availability
368
            reserved = reserved + currInv.reserved
369
        return availability - reserved
370
    else:
371
        total_availability = 0
372
        for current_inventory_snapshot in CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).filter_by(item_id = item.id).all():
373
            total_availability += current_inventory_snapshot.availability - current_inventory_snapshot.reserved
374
        return total_availability 
375
 
376
def __get_item_reserved(item_id):
377
    all_inventory = CurrentInventorySnapshot.query.filter_by(item_id = item_id).all()
378
    reserved = 0
379
    for currInv in all_inventory:
380
        reserved = reserved + currInv.reserved
381
    return reserved
5966 rajveer 382
 
383
def __get_item_availability_at_warehouse(warehouse_id, item_id):
384
    inventory = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).one()
385
    return inventory.availability
386
 
387
def is_order_billable(item_id, warehouse_id, source_id, order_id):
388
    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()
389
    availability = __get_item_availability_at_warehouse(warehouse_id, item_id)
390
    for reservation in reservations:
391
        availability = availability - reservation.reserved
392
        if reservation.order_id == order_id and reservation.source_id == source_id:
393
            break
394
    if availability < 0:
395
        return False
396
    return True
5944 mandeep.dh 397
 
19989 kshitij.so 398
def reserve_item_in_warehouse(item_id, warehouse_id, source_id, order_id, created_timestamp, promised_shipping_timestamp, quantity):
399
 
5944 mandeep.dh 400
    if not warehouse_id:
401
        raise InventoryServiceException(101, "bad warehouse_id")
402
 
403
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
404
    try:
405
        current_inventory_snapshot = query.one()
406
    except:
407
        current_inventory_snapshot = CurrentInventorySnapshot()
408
        current_inventory_snapshot.warehouse_id = warehouse_id
409
        current_inventory_snapshot.item_id = item_id
410
        current_inventory_snapshot.availability = 0
411
        current_inventory_snapshot.reserved = 0
8204 amar.kumar 412
        current_inventory_snapshot.held = 0
5944 mandeep.dh 413
 
414
    current_inventory_snapshot.reserved = current_inventory_snapshot.reserved + quantity
5966 rajveer 415
 
416
    reservation = CurrentReservationSnapshot()
417
    reservation.item_id = item_id
418
    reservation.warehouse_id = warehouse_id
419
    reservation.source_id = source_id
420
    reservation.order_id = order_id
5990 rajveer 421
    reservation.created_timestamp = to_py_date(created_timestamp)
422
    reservation.promised_shipping_timestamp = to_py_date(promised_shipping_timestamp)
5966 rajveer 423
    reservation.reserved = quantity
424
 
8720 amar.kumar 425
    session.commit()
8182 amar.kumar 426
 
427
    try:
428
        order_client = TransactionClient().get_client()
429
        order = order_client.getOrder(order_id)
9574 amar.kumar 430
        if order.source:
431
            holdInventoryDetail = HoldInventoryDetail.query.filter_by(item_id = item_id, warehouse_id = warehouse_id, source = order.source).first()
9694 amar.kumar 432
            if holdInventoryDetail is None or holdInventoryDetail.held<=0:
433
                holdInventoryDetails = HoldInventoryDetail.query.filter_by(item_id = item_id, source = order.source).all()
434
                if holdInventoryDetails:
435
                    for hID in holdInventoryDetails:
436
                        if hID.held>0:
437
                            holdInventoryDetail = hID
9574 amar.kumar 438
            if holdInventoryDetail is not None and holdInventoryDetail.held>0:
439
                previousHeld = holdInventoryDetail.held
440
                holdInventoryDetail.held = max(0, holdInventoryDetail.held -quantity)
441
                diff = previousHeld-holdInventoryDetail.held 
9770 amar.kumar 442
                current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=item_id, warehouse_id=holdInventoryDetail.warehouse_id)
9574 amar.kumar 443
                if current_inventory_snapshot is not None:
444
                    current_inventory_snapshot.held = max(0, current_inventory_snapshot.held - diff)
445
                session.commit()
8182 amar.kumar 446
    except:
447
        print "Unable to release hold Inventory for item_id " + str(item_id) + " warehouse_id " + str(warehouse_id) + " source " + str(source_id)
8720 amar.kumar 448
    #session.commit()
5944 mandeep.dh 449
    #**Update item availability cache**#
5978 rajveer 450
    clear_item_availability_cache(item_id)
5944 mandeep.dh 451
    return True
452
 
7968 amar.kumar 453
def update_reservation_for_order(item_id, warehouse_id, source_id, order_id, created_timestamp, promised_shipping_timestamp, quantity):    
454
    if not warehouse_id:
455
        raise InventoryServiceException(101, "bad warehouse_id")
456
    warehouse = get_Warehouse(warehouse_id)
457
    item_pricing = get_item_pricing(item_id, warehouse.vendor.id)
458
    if not item_pricing:
459
        raise InventoryServiceException(101, "No Pricing Info found for vendor and Item")
460
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
461
    try:
462
        new_current_inventory_snapshot = query.one()
463
    except:
464
        new_current_inventory_snapshot = CurrentInventorySnapshot()
465
        new_current_inventory_snapshot.warehouse_id = warehouse_id
466
        new_current_inventory_snapshot.item_id = item_id
467
        new_current_inventory_snapshot.availability = 0
468
        new_current_inventory_snapshot.reserved = 0
469
 
470
    new_current_inventory_snapshot.reserved = new_current_inventory_snapshot.reserved + quantity
471
 
472
    new_reservation = CurrentReservationSnapshot()
473
    new_reservation.item_id = item_id
474
    new_reservation.warehouse_id = warehouse_id
475
    new_reservation.source_id = source_id
476
    new_reservation.order_id = order_id
477
    new_reservation.created_timestamp = to_py_date(created_timestamp)
478
    new_reservation.promised_shipping_timestamp = to_py_date(promised_shipping_timestamp)
479
    new_reservation.reserved = quantity
480
 
8182 amar.kumar 481
    try:
482
        order_client = TransactionClient().get_client()
483
        order = order_client.getOrder(order_id)
9574 amar.kumar 484
        if order.source:
485
            holdInventoryDetail = HoldInventoryDetail.query.filter_by(item_id = item_id, warehouse_id = warehouse_id, source = order.source).first()
9694 amar.kumar 486
            if holdInventoryDetail is None or holdInventoryDetail.held<=0:
487
                holdInventoryDetails = HoldInventoryDetail.query.filter_by(item_id = item_id, source = order.source).all()
488
                if holdInventoryDetails:
489
                    for hID in holdInventoryDetails:
490
                        if hID.held>0:
491
                            holdInventoryDetail = hID
9574 amar.kumar 492
            if holdInventoryDetail is not None and holdInventoryDetail.held>0:
493
                previousHeld = holdInventoryDetail.held
494
                holdInventoryDetail.held = max(0, holdInventoryDetail.held -quantity)
495
                diff = previousHeld-holdInventoryDetail.held 
9770 amar.kumar 496
                current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=item_id, warehouse_id=holdInventoryDetail.warehouse_id)
9574 amar.kumar 497
                if current_inventory_snapshot is not None:
498
                    current_inventory_snapshot.held = max(0, current_inventory_snapshot.held - diff)
499
                session.commit()
8182 amar.kumar 500
    except:
501
        print "Unable to release hold Inventory for item_id " + str(item_id) + " warehouse_id " + str(warehouse_id) + " source " + str(source_id)
502
 
7968 amar.kumar 503
    order_client = TransactionClient().get_client()
504
    order = order_client.getOrder(order_id)
505
    for lineitem in order.lineitems:
506
        query = CurrentInventorySnapshot.query.filter_by(warehouse_id = order.fulfilmentWarehouseId, item_id = lineitem.item_id)
507
        try:
508
            current_inventory_snapshot = query.one()
509
            current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
510
 
511
            reservation = CurrentReservationSnapshot.query.filter_by(warehouse_id = order.fulfilmentWarehouseId, item_id = lineitem.item_id, source_id = source_id, order_id = order_id).one()
512
            if reservation.reserved == quantity:
513
                reservation.delete()
514
            else:
515
                reservation.reserved -= quantity
516
 
517
            clear_item_availability_cache(lineitem.item_id)
518
            session.commit()
519
            try:
520
                if current_inventory_snapshot.reserved < 0:
521
                    item = __get_item_from_master(lineitem.item_id)
522
                    __send_alert_for_negative_reserved(item, current_inventory_snapshot.reserved, get_Warehouse(order.fulfilmentWarehouseId))
523
            except:
8182 amar.kumar 524
                print "Error in sending negative reserved alert:", sys.exc_info()[0]
7968 amar.kumar 525
                return False
526
        except:
527
            print "Error in reducing reservation for item:", sys.exc_info()[0]
528
            return False
529
    session.commit()
530
    #**Update item availability cache**#
531
    clear_item_availability_cache(item_id)
532
    return True
533
 
19419 amit.gupta 534
def get_item_pincode_availability(itemPricingMap, pin_code):
19413 amit.gupta 535
    returnMap = {}
536
    missingItemPricingList = []
537
    for item_id, pricing in itemPricingMap.iteritems():
538
        if not pricing:
539
            missingItemPricingList.append(item_id)
20641 amit.gupta 540
    if missingItemPricingList:
541
        cc = CatalogClient().get_client()
542
        items = cc.getItems(missingItemPricingList)
543
        lc = LogisticsClient().get_client()
544
        #Consider selling price if its missing in itempricing
545
        for item in items:
546
            itemPricingMap[item.id] = item.sellingPrice
19413 amit.gupta 547
    pricingLocationInfoMap = __getLocationInfoMap(pin_code, itemPricingMap)    
548
    if pricingLocationInfoMap == -1:
549
        returnMap = {"pincode_serviceable":False}    
550
    else:
551
        #for item_id, sellingPrice in itemPricingMap.iteritems():
552
        allLocations = pricingLocationInfoMap[1].keys()    
553
        itemLocationAvailabilityList = __get_item_location_availability_bulk(itemPricingMap.keys(), allLocations)
554
        pricingLocationsMap = {}
555
        for itemLocationAvailability in itemLocationAvailabilityList:
556
            sellingPrice = itemPricingMap[itemLocationAvailability.item_id]
557
            if pricingLocationInfoMap[sellingPrice] == -1:
558
                continue
559
            if not pricingLocationsMap.has_key(sellingPrice):
560
                pricingLocationsMap[sellingPrice] = pricingLocationInfoMap[sellingPrice].keys() 
561
 
562
            if itemLocationAvailability.location_id not in pricingLocationsMap[sellingPrice]:
563
                continue
564
            if not returnMap.has_key(itemLocationAvailability.item_id):
565
                returnMap[itemLocationAvailability.item_id] = ItemPincodeAvailability(vatQty = 0, totalQty = 0, minDeliveryDate=-1)
566
            itemPincodeAvailability = ItemPincodeAvailability()
567
            itemPincodeAvailability = returnMap[itemLocationAvailability.item_id]
568
            locationInfo = LocationInfo()
569
            locationInfo = pricingLocationInfoMap[sellingPrice][itemLocationAvailability.location_id]
570
            locationQty = itemLocationAvailability.virtual_availability + itemLocationAvailability.physical_availability
571
            if locationInfo.sameState:
572
                itemPincodeAvailability.vatQty += locationQty
573
            itemPincodeAvailability.totalQty += locationQty
574
            itemPincodeAvailability.isCod = itemPincodeAvailability.isCod or locationInfo.isCod 
575
            itemPincodeAvailability.isOtg = itemPincodeAvailability.isOtg or locationInfo.isOtg 
576
            if itemPincodeAvailability.minDeliveryDate == -1:
577
                itemPincodeAvailability.minDeliveryDate = itemLocationAvailability.min_transfer_delay + locationInfo.minDelay 
578
                itemPincodeAvailability.maxDeliveryDate = itemLocationAvailability.max_transfer_delay + locationInfo.maxDelay
579
            else:
580
                itemPincodeAvailability.minDeliveryDate = min(itemPincodeAvailability.minDeliveryDate, itemLocationAvailability.min_transfer_delay + locationInfo.minDelay) 
581
                itemPincodeAvailability.maxDeliveryDate = max(itemPincodeAvailability.maxDeliveryDate, itemLocationAvailability.max_transfer_delay + locationInfo.maxDelay)
582
        for itemId, itemPincodeAvailability in returnMap.iteritems():
583
            sellingPrice = itemPricingMap[itemId]
584
            locationsMap = pricingLocationsMap[sellingPrice]
585
            minDay = math.ceil(itemPincodeAvailability.minDeliveryDate)
586
            maxDay = math.ceil(itemPincodeAvailability.maxDeliveryDate)
587
            itemPincodeAvailability.minDeliveryDate, itemPincodeAvailability.maxDeliveryDate = __getDeliveryDate(minDay, itemPincodeAvailability.isCod, maxDay)
588
 
589
    return json.dumps(returnMap)
590
 
591
 
592
def __getLocationInfoMap(pin_code, itemPricingMap):
20641 amit.gupta 593
    priceSet = set(itemPricingMap.values() + [1])
19413 amit.gupta 594
    if not pincodePricingServiceabilityMap.has_key(pin_code):
595
        pincodePricingServiceabilityMap[pin_code] = {}
596
    pricingMap = pincodePricingServiceabilityMap[pin_code]
597
    if pricingMap != -1: 
20641 amit.gupta 598
        missingInMap = list(priceSet - set(pricingMap.keys())) 
599
        if missingInMap:
600
            lc = LogisticsClient().get_client()
601
            priceLocationInfoMap = lc.getLocationInfoMap(pin_code, missingInMap)
602
            if not priceLocationInfoMap:
603
                pricingMap = pincodePricingServiceabilityMap[pin_code] = -1
604
            else:
605
                for sellingPrice in missingInMap:
606
                    if priceLocationInfoMap[sellingPrice] == {}:
607
                        pricingMap[sellingPrice] = -1
608
                    else:
609
                        pricingMap[sellingPrice] = priceLocationInfoMap[sellingPrice]
19413 amit.gupta 610
 
611
    return pricingMap
612
 
613
def __getDeliveryDate(minDays, isCod, maxDays=None):
614
    curTime = datetime.datetime.now()
615
    if maxDays is None:
616
        maxDays = minDays 
617
    if isCod and curTime.hour < 15:
618
        maxDays = maxDays + 1
619
    return __getAdjustedDate(minDays), __getAdjustedDate(maxDays) 
7968 amar.kumar 620
 
19413 amit.gupta 621
def __getAdjustedDate(days):
622
    curDate = datetime.date.today()
623
    if curDate == last_date:
624
        if adjusted_dates.has_key(days):
625
            return adjusted_dates[days]
626
    else:
627
        adjusted_dates = {}
628
    lc = LogisticsClient().get_client()
629
    adjusted_day = lc.adjustDeliveryDays(datetime.datetime.now(), to_java_date(days))
630
 
631
    adjusted_date = to_java_date(datetime.datetime.combine(curDate, datetime.datetime.min.time()) + datetime.timedelta(days=adjusted_day))
632
    adjusted_dates[days] = adjusted_date
633
    return adjusted_date
634
 
5966 rajveer 635
def reduce_reservation_count(item_id, warehouse_id, source_id, order_id, quantity):
5944 mandeep.dh 636
    if not warehouse_id:
637
        raise InventoryServiceException(101, "bad warehouse_id")
638
 
639
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
640
    try:
641
        current_inventory_snapshot = query.one()
642
        current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
5966 rajveer 643
 
644
        reservation = CurrentReservationSnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id, source_id = source_id, order_id = order_id).one()
645
        if reservation.reserved == quantity:
646
            reservation.delete()
647
        else:
648
            reservation.reserved -= quantity
5944 mandeep.dh 649
        session.commit()
650
        #**Update item availability cache**#
5978 rajveer 651
        clear_item_availability_cache(item_id)
5944 mandeep.dh 652
        if current_inventory_snapshot.reserved < 0:
653
            item = __get_item_from_master(item_id)
654
            __send_alert_for_negative_reserved(item, current_inventory_snapshot.reserved, get_Warehouse(warehouse_id))
655
        return True
656
    except:
657
        print "Unexpected error:", sys.exc_info()[0]
658
        return False
659
 
12976 amit.gupta 660
#This is not the source as in snapdeal or website, this source is to incorporate different pricing depending upon source id.
22566 amit.gupta 661
#i.e. if user visiting to our site has specific source he would see pricing on that source basis. Default source is 1.
22719 amit.gupta 662
# Have to add another source id 2 for fofo warehouses
5978 rajveer 663
def get_item_availability_for_location(item_id, source_id):
664
    item_availability = ItemAvailabilityCache.get_by(itemId=item_id, sourceId = source_id)
5944 mandeep.dh 665
    if item_availability:
7589 rajveer 666
        return [item_availability.warehouseId, item_availability.expectedDelay, item_availability.billingWarehouseId, item_availability.sellingPrice, item_availability.totalAvailability, item_availability.weight]
20641 amit.gupta 667
        #return [item_availability.warehouseId, item_availability.expectedDelay, item_availability.billingWarehouseId, item_availability.sellingPrice, 0, item_availability.weight]
5944 mandeep.dh 668
    else:
5978 rajveer 669
        __update_item_availability_cache(item_id, source_id)
670
            ##Check risky status for the source
671
        __check_risky_item(item_id, source_id)
672
        return get_item_availability_for_location(item_id, source_id)
5944 mandeep.dh 673
 
19413 amit.gupta 674
def get_item_location_availability(item_id, locations=[]):
675
    if locations:
676
        newLocations = locations + [-1]
677
        itemisedItemLocationAvailability = ItemLocationAvailabilityCache.filter_by(itemId=item_id).filter(ItemLocationAvailability.locationId.in_(newLocations)).all()
678
    else:
679
        itemisedItemLocationAvailability = ItemLocationAvailabilityCache.filter_by(itemId=item_id).all()
680
    if not itemisedItemLocationAvailability:
681
        __update_item_location(item_id)
682
        return get_item_location_availability(item_id, locations)
683
    else:
684
        thriftList = []
685
        for itemLocationAvailability in itemisedItemLocationAvailability:
686
            if itemLocationAvailability.location_id == -1:
687
                itemisedItemLocationAvailability
688
            else:
689
                thriftList.append(to_t_item_location_availability(itemLocationAvailability))
690
        return thriftList
691
 
692
def __get_item_location_availability_bulk(item_ids, locations=[]):
693
 
694
    query = ItemLocationAvailabilityCache.query.filter(ItemLocationAvailabilityCache.item_id.in_(item_ids))
695
    allPopulated = query.filter(ItemLocationAvailabilityCache.location_id==-1).all()
696
    if len(item_ids) > len(allPopulated):
697
        for item_id in allPopulated:
698
            if item_id not in item_ids:
699
                __update_item_location(item_id)
700
    if locations:
701
        query.filter(ItemLocationAvailabilityCache.location_id.in_(locations)).all()
702
    return query.all()
703
 
704
 
705
def clear_item_location_availability_cache(item_id, locations=[]):
706
    if type(item_id)==list:
707
        ItemLocationAvailabilityCache.query.filter(ItemLocationAvailabilityCache.itemId.in_(item_id)).delete(synchronize_session='fetch')
708
        session.commit()
709
        t = threading.Thread(target=_task_update_item_availability_cache, args=(item_id,))
710
        t.start()
711
    elif item_id:
712
        ItemLocationAvailabilityCache.query.filter_by(itemId = item_id).delete()
713
    session.commit()
714
 
5978 rajveer 715
def clear_item_availability_cache(item_id = None):
13150 manish.sha 716
    print item_id
13149 manish.sha 717
    if type(item_id)==list:
13150 manish.sha 718
        ItemAvailabilityCache.query.filter(ItemAvailabilityCache.itemId.in_(item_id)).delete(synchronize_session='fetch')
13149 manish.sha 719
        session.commit()
13493 amit.gupta 720
        t = threading.Thread(target=_task_update_item_availability_cache, args=(item_id,))
721
        t.start()
722
 
13520 amit.gupta 723
    elif item_id:
5978 rajveer 724
        ItemAvailabilityCache.query.filter_by(itemId = item_id).delete()
12963 amit.gupta 725
        session.commit()
13493 amit.gupta 726
 
727
def _task_update_item_availability_cache(item_ids):
728
    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
729
    items = client.getItems(item_ids)
730
    for item_id in item_ids:
731
        item_availability = ItemAvailabilityCache.get_by(itemId=item_id, sourceId=1)
732
        if not item_availability:
733
            try:
17974 amit.gupta 734
                __update_item_availability_cache(item_id, 1, items[item_id])
735
                __check_risky_item(item_id, 1)
13493 amit.gupta 736
            except:
737
                print "Could not update cache for "
738
                continue
17990 kshitij.so 739
    return True   
5944 mandeep.dh 740
 
19413 amit.gupta 741
def __update_item_location(item_id):
742
    ignoredWhs = get_ignored_warehouses(item_id)
743
 
744
    itemsnapshot = CurrentInventorySnapshot.query.filter_by(item_id = item_id).all()
745
    locationsMap = {}
746
    for row in itemsnapshot:
747
        warehouse = warehouseMap[row.warehouse_id]
748
        if row.warehouse_id in ignoredWhs:
749
            continue 
750
 
751
        location = warehouse.logisticsLocation
752
        if not locationsMap.has_key(location):
753
            locationsMap[location] = {"physicalQty":0, "virtualQty":0,    "minTransferDelay":100, "maxTransferDelay":0}
754
        locationMap = locationsMap[location]
755
        if warehouse.type == 'THIRD_PARTY':
756
            locationMap["virtualQty"] += max(0, row.availability - row.reserverd - row.held)
757
            locationMap["minTransferDelay"] = min(locationMap["minTransferDelay"], row.transferDelayInHours/24)
758
            locationMap["maxTransferDelay"] = max(locationMap["maxTransferDelay"], row.transferDelayInHours/24)
759
        else:
760
            locationMap["physicalQty"] += max(0, row.availability - row.reserverd - row.held)
761
            locationMap["minTransferDelay"] = 0
762
    for location, locationMap in locationsMap.iteritems():
763
        if locationMap["virtualQty"] > 0 or locationMap["physicalQty"] > 0: 
764
            itemLocationAvailability = ItemLocationAvailabilityCache()
765
            itemLocationAvailability.item_id = item_id
766
            itemLocationAvailability.location_id = location
767
            itemLocationAvailability.max_transfer_delay = locationMap["maxTransferDelay"]
768
            itemLocationAvailability.min_transfer_delay = locationMap["minTransferDelay"]
769
            itemLocationAvailability.virtual_availability = locationMap["virtualQty"]
770
            itemLocationAvailability.physical_availability = locationMap["physicalQty"]
771
    #Add location -1 for each item
772
    itemLocationAvailability = ItemLocationAvailabilityCache()
773
    itemLocationAvailability.item_id = item_id
774
    itemLocationAvailability.location_id = -1
775
    session.commit()
776
 
777
 
778
 
779
 
780
 
12963 amit.gupta 781
def __update_item_availability_cache(item_id, source_id, item=None):
5944 mandeep.dh 782
    """
22719 amit.gupta 783
    Source 2 is completely hardcoded for fofo which has physical warehouse as 7678 and 7681
784
    Then how shoud we handle virtual because for both source virtual gonna mark
785
    """
786
    """
8954 vikram.rag 787
    Determines the warehouse that should be used to fulfil an order for the given item.
5944 mandeep.dh 788
    Algorithm explained at https://sites.google.com/a/shop2020.in/virtual-w-h-and-inventory/technical-details
789
 
790
    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.
791
    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.
792
 
793
    if item available at any OUR-GOOD warehouse
794
        // OUR-GOOD warehouses have inventory risk; So, we empty them first! 
795
        // We can start with minimum transfer price criterion but down the line we can also bring in Inventory age 
796
        assign OUR-GOOD warehouse with minimum transfer price
797
    else
798
        if Preferred vendor is specified and marked Sticky
799
            // Always purchase from Preferred if its marked sticky
800
            assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
801
        else 
802
            if item available in a THIRDPARTY GOOD/VIRTUAL warehouse
803
                assign THIRDPARTY GOOD/VIRTUAL warehouse where item is available with minimal transfer delay followed by minimum transfer price
804
            else 
805
                // Item not available at any warehouse, OURS or THIRDPARTY
806
                If Preferred vendor is specified
807
                    assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
808
                else
809
                    assign THIRDPARTY GOOD/VIRTUAL warehouse with minimum transfer price
810
 
811
    Returns an ordered list of size 4 with following elements in the given order:
812
    1. Logistics location of the warehouse which was finally picked up to ship the order.
813
    2. Expected delay added by the category manager.
814
    3. Id of the warehouse which was finally picked up.
815
 
816
    Parameters:
817
     - itemId
818
    """
12963 amit.gupta 819
    if item is None:
820
        item = __get_item_from_source(item_id, source_id)
5944 mandeep.dh 821
    item_pricing = {}
822
    for vendorItemPricing in VendorItemPricing.query.filter_by(item_id=item_id).all():
823
        item_pricing[vendorItemPricing.vendor_id] = vendorItemPricing
824
 
6510 rajveer 825
    ignoredWhs = get_ignored_warehouses(item_id)
826
 
5944 mandeep.dh 827
    warehouses = {}
828
    ourGoodWarehouses = {}
829
    thirdpartyWarehouses = {}
830
    preferredThirdpartyWarehouses = {}
831
    for warehouse in Warehouse.query.all():
7410 amar.kumar 832
        if (warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.BAD] or warehouse.warehouseType == WarehouseType._VALUES_TO_NAMES[WarehouseType.OURS_THIRDPARTY]):
5944 mandeep.dh 833
            continue
834
        warehouses[warehouse.id] = warehouse
835
        if warehouse.warehouseType == WarehouseType._VALUES_TO_NAMES[WarehouseType.OURS]:
836
            if warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
837
                ourGoodWarehouses[warehouse.id] = warehouse
838
        else:
839
            thirdpartyWarehouses[warehouse.id] = warehouse
840
            if item.preferredVendor == warehouse.vendor_id and warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
841
                preferredThirdpartyWarehouses[warehouse.id] = warehouse
842
 
843
    warehouse_retid = -1
844
    total_availability = 0
845
 
6540 rajveer 846
    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(ourGoodWarehouses, ignoredWhs, item_id, item_pricing, False)
5944 mandeep.dh 847
    if warehouse_retid == -1:
848
        if item.preferredVendor and item.isWarehousePreferenceSticky:
6540 rajveer 849
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(preferredThirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 850
            if warehouse_retid == -1:
851
                warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
852
        else:
6540 rajveer 853
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 854
            if warehouse_retid == -1:
855
                if item.preferredVendor:
856
                    warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
857
                else:
6540 rajveer 858
                    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing, True)
5944 mandeep.dh 859
 
860
    warehouse = warehouses[warehouse_retid]
861
    billingWarehouseId = warehouse.billingWarehouseId
862
 
863
    # Fetching billing warehouse of a Good billable warehouse corresponding to the virtual one
864
    if not warehouse.billingWarehouseId:
21152 amit.gupta 865
        for w in Warehouse.query.filter_by(vendor_id = warehouse.vendor_id, inventoryType = InventoryType._VALUES_TO_NAMES[InventoryType.GOOD], state_id=warehouse.state_id).all():
5944 mandeep.dh 866
            if w.billingWarehouseId:
867
                billingWarehouseId = w.billingWarehouseId
868
                break
869
 
870
    expectedDelay = item.expectedDelay 
871
    if expectedDelay is None:
872
        print 'expectedDelay field for this item was Null. Resetting it to 0'
873
        expectedDelay = 0
874
    else:
875
        expectedDelay = int(item.expectedDelay)
876
 
877
    if total_availability <= 0:
8026 amar.kumar 878
        if item.preferredVendor in [1, 5]:
6562 rajveer 879
            expectedDelay = expectedDelay + 3
880
        else:
881
            expectedDelay = expectedDelay + 2
6643 rajveer 882
    else:
883
        if warehouse.transferDelayInHours:
884
            expectedDelay = expectedDelay + warehouse.transferDelayInHours / 24
5944 mandeep.dh 885
 
18022 manish.sha 886
    if WarehouseType._NAMES_TO_VALUES[warehouse.warehouseType] == WarehouseType.THIRD_PARTY:
8491 rajveer 887
        expectedDelay = expectedDelay + __get_vendor_holiday_delay(warehouse.vendor_id, expectedDelay) 
888
 
5963 mandeep.dh 889
    total_availability = 0
16029 amit.gupta 890
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
6545 rajveer 891
        if entry.warehouse_id not in ignoredWhs:
16029 amit.gupta 892
            if entry.warehouse_id not in ourGoodWarehouses and entry.warehouse_id not in thirdpartyWarehouses:
16015 amit.gupta 893
                continue
894
            if entry.warehouse_id in ourGoodWarehouses and ourGoodWarehouses[entry.warehouse_id].billingWarehouseId == billingWarehouseId:
895
                total_availability += entry.availability - entry.reserved - entry.held
896
            elif entry.warehouse_id in thirdpartyWarehouses:
897
                vendorId = thirdpartyWarehouses[entry.warehouse_id].vendor_id
898
                for goodWarehouse in ourGoodWarehouses.values():
21152 amit.gupta 899
                    if goodWarehouse.vendor_id==vendorId and goodWarehouse.billingWarehouseId == billingWarehouseId and warehouse.state_id==goodWarehouse.state_id:
16015 amit.gupta 900
                        total_availability += entry.availability - entry.reserved - entry.held
901
                        break
5963 mandeep.dh 902
 
5978 rajveer 903
    item_availability_cache = ItemAvailabilityCache.get_by(itemId=item_id, sourceId=source_id)
5944 mandeep.dh 904
    if item_availability_cache is None:
905
        item_availability_cache = ItemAvailabilityCache()
906
        item_availability_cache.itemId = item_id
5978 rajveer 907
        item_availability_cache.sourceId = source_id
5944 mandeep.dh 908
    item_availability_cache.warehouseId = int(warehouse_retid)
909
    item_availability_cache.expectedDelay = expectedDelay
910
    item_availability_cache.billingWarehouseId = billingWarehouseId
911
    item_availability_cache.sellingPrice = item.sellingPrice
912
    item_availability_cache.totalAvailability = total_availability
16029 amit.gupta 913
    #item_availability_cache.location = warehouse.logisticsLocation 
7589 rajveer 914
    item_availability_cache.weight = 1000*item.weight if item.weight else 300
5944 mandeep.dh 915
    session.commit()
916
 
6540 rajveer 917
def __get_warehouse_with_min_transfer_price(warehouses, ignoredWhs, item_id, item_pricing, ignoreAvailability):
5944 mandeep.dh 918
    warehouse_retid = -1
919
    minTransferPrice = None
920
    total_availability = 0
6013 amar.kumar 921
    availabilityForBillingWarehouses = {}
922
    warehousesAvailability = {}
923
    availability = 0
924
    billing_warehouse_retid = None
5944 mandeep.dh 925
 
926
    if not ignoreAvailability:
927
        for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 928
            entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 929
            entry.held = max(entry.held, 0)
6013 amar.kumar 930
            #if entry.availability > entry.reserved:
8182 amar.kumar 931
            warehousesAvailability[entry.warehouse_id] = [entry.availability, entry.reserved, entry.held] 
5944 mandeep.dh 932
 
6540 rajveer 933
    if len(ignoredWhs) > 0:
934
        for whid in ignoredWhs:
935
            if warehousesAvailability.has_key(whid):
6542 rajveer 936
                warehousesAvailability[whid][0] = 0
6683 rajveer 937
                warehousesAvailability[whid][1] = 0
8182 amar.kumar 938
                warehousesAvailability[whid][2] = 0
6540 rajveer 939
 
5944 mandeep.dh 940
    for warehouse in warehouses.values():
941
        if not ignoreAvailability:
6013 amar.kumar 942
            #TODO Mistake no entry for this warehouse.id in warehouseswithAvailab
943
            if warehouse.id not in warehousesAvailability:
944
                continue
945
            entry = warehousesAvailability[warehouse.id]
946
            if warehouse.billingWarehouseId in availabilityForBillingWarehouses:
947
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
8182 amar.kumar 948
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = availabilityForBillingWarehouses[warehouse.billingWarehouseId] + entry[0] - entry[1] - entry[2]  
5944 mandeep.dh 949
            else:
6013 amar.kumar 950
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
8182 amar.kumar 951
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = entry[0] - entry[1] - entry[2]
952
            if entry[0] <= (entry[1] + entry[2]):
5944 mandeep.dh 953
                continue
8182 amar.kumar 954
            total_availability += entry[0] - entry[1] - entry[2]
5944 mandeep.dh 955
 
956
        # Missing transfer price cases should not impact warehouse assignment
957
        transferPrice = None
958
        if item_pricing.has_key(warehouse.vendor_id):
6778 rajveer 959
            transferPrice = item_pricing[warehouse.vendor_id].nlc
5944 mandeep.dh 960
        if minTransferPrice is None or (transferPrice and minTransferPrice > transferPrice):
961
            warehouse_retid = warehouse.id
6013 amar.kumar 962
            billing_warehouse_retid = warehouse.billingWarehouseId
5944 mandeep.dh 963
            minTransferPrice = transferPrice
6013 amar.kumar 964
 
965
 
966
    if billing_warehouse_retid in availabilityForBillingWarehouses: 
967
        availability = availabilityForBillingWarehouses[billing_warehouse_retid]
968
    else:
969
        availability = total_availability
970
 
971
    return [warehouse_retid, availability]
5944 mandeep.dh 972
 
6540 rajveer 973
def __get_warehouse_with_min_transfer_delay(warehouses, ignoredWhs, item_id, item_pricing):
5944 mandeep.dh 974
    minTransferDelay = None
975
    minTransferDelayWarehouses = {}
976
    total_availability = 0
977
 
978
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 979
        entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 980
        entry.held = max(entry.held, 0)
5944 mandeep.dh 981
        if warehouses.has_key(entry.warehouse_id):
982
            warehouse = warehouses[entry.warehouse_id]
6013 amar.kumar 983
            #if entry.availability > entry.reserved:
6683 rajveer 984
            if entry.warehouse_id not in ignoredWhs:
8182 amar.kumar 985
                total_availability += entry.availability - entry.reserved - entry.held
986
            if entry.availability - entry.reserved - entry.held <= 0:
6780 amar.kumar 987
                continue
6013 amar.kumar 988
            transferDelay = warehouse.transferDelayInHours
989
            if minTransferDelay is None or minTransferDelay >= transferDelay:
990
                if minTransferDelay != transferDelay:
991
                    minTransferDelayWarehouses = {}
992
                minTransferDelayWarehouses[warehouse.id] = warehouse
993
                minTransferDelay = transferDelay
5944 mandeep.dh 994
 
6540 rajveer 995
    return [__get_warehouse_with_min_transfer_price(minTransferDelayWarehouses, ignoredWhs, item_id, item_pricing, False)[0], total_availability]
5944 mandeep.dh 996
 
997
def __get_warehouse_with_max_availability(warehouse_ids, item_id):
998
    warehouse_retid = -1
999
    max_availability = 0
1000
    total_availability = 0
1001
 
1002
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 1003
        entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 1004
        entry.held = max(entry.held, 0)
5944 mandeep.dh 1005
        if entry.warehouse_id in warehouse_ids:
1006
            availability = entry.availability - entry.reserved
1007
            if availability > max_availability:
1008
                warehouse_retid = entry.warehouse_id
1009
                max_availability = availability
1010
            total_availability += availability
1011
 
1012
    return [warehouse_retid, total_availability]
1013
 
8491 rajveer 1014
def __get_vendor_holiday_delay(vendor_id, expectedDelay):
1015
    ## If vendor is closed two days continuously
5944 mandeep.dh 1016
    holidayDelay = 0
8491 rajveer 1017
    currentDate = datetime.date.today()
1018
    expectedDate = currentDate + datetime.timedelta(days = expectedDelay)
1019
    holidays = VendorHolidays.query.filter(VendorHolidays.vendor_id == vendor_id).filter(VendorHolidays.date.between(currentDate, expectedDate)).all()
1020
    if holidays:
1021
        holidayDelay = holidayDelay + len(holidays)
5944 mandeep.dh 1022
    return holidayDelay 
1023
 
1024
def get_item_pricing(item_id, vendorId):
1025
    '''
1026
    if vendor id is -1 then we calculate an average transfer price to be populated
1027
    at the time of order creation. This will be later updated with actual transfer price
1028
    at the time of billing.
1029
    '''
1030
    if(vendorId == -1):
6778 rajveer 1031
        tp_total = 0
1032
        nlc_total = 0
5944 mandeep.dh 1033
        try:
1034
            item_pricings = []
1035
            item = __get_item_from_master(item_id)
1036
            if item.preferredVendor is not None:
1037
                item_pricing = VendorItemPricing.query.filter_by(item_id=item_id, vendor_id=item.preferredVendor).first()
1038
                if item_pricing:
1039
                    item_pricings.append(item_pricing)                    
1040
            else :
1041
                item_pricings = VendorItemPricing.query.filter_by(item_id=item_id).all()
1042
            if item_pricings:
1043
                for item_pricing in item_pricings:
6778 rajveer 1044
                    tp_total += item_pricing.transfer_price
1045
                    nlc_total += item_pricing.nlc
1046
                tp_avg = tp_total / len(item_pricings)
1047
                nlc_avg = nlc_total / len(item_pricings)
1048
                item_pricing.transfer_price = tp_avg
1049
                item_pricing.nlc = nlc_avg
5944 mandeep.dh 1050
            else:
1051
                item_pricing = VendorItemPricing()
1052
                item_pricing.transfer_price = item.sellingPrice
6778 rajveer 1053
                item_pricing.nlc = item.sellingPrice
5944 mandeep.dh 1054
                vendor = Vendor()
1055
                vendor.id = vendorId
1056
                item_pricing.vendor = vendor
1057
                item_pricing.item_id = item_id
1058
 
1059
            return item_pricing
1060
        except:
1061
            raise InventoryServiceException(101, "Item pricing not found ")
1062
    vendor = Vendor.get_by(id=vendorId)    
1063
    try:
1064
        item_pricing = VendorItemPricing.query.filter_by(vendor=vendor, item_id=item_id).one()
1065
        return item_pricing
1066
    except MultipleResultsFound:
1067
        raise InventoryServiceException(110, "Multiple pricing information present for Vendor: " + vendor.name + " and Item: " + str(item_id))
1068
    except NoResultFound:
1069
        raise InventoryServiceException(111, "Missing pricing information for Vendor: " + vendor.name + " and Item: " + str(item_id))
1070
 
1071
def get_all_item_pricing(item_id):
1072
    item_pricing = VendorItemPricing.query.filter_by(item_id=item_id).all()
1073
    return item_pricing
10126 amar.kumar 1074
def get_all_vendor_item_pricing(item_id, vendor_id):
1075
    query = VendorItemPricing.query
1076
    if item_id:
1077
        query = query.filter_by(item_id = item_id)
1078
    if item_id:
1079
        query = query.filter_by(vendor_id = vendor_id)
1080
    item_pricing = query.all()
1081
    return item_pricing
1082
 
5944 mandeep.dh 1083
def get_item_mappings(item_id):
1084
    item_mappings = VendorItemMapping.query.filter_by(item_id=item_id).all()
1085
    return item_mappings
1086
 
19247 kshitij.so 1087
def add_vendor_pricing(vendorItemPricing, sendMail = True):
5944 mandeep.dh 1088
    if not vendorItemPricing:
1089
        raise InventoryServiceException(108, "Bad vendorItemPricing in request")
1090
    vendorId = vendorItemPricing.vendorId
1091
    itemId = vendorItemPricing.itemId
1092
 
1093
    try:
1094
        vendor = Vendor.query.filter_by(id=vendorId).one()
1095
    except:
1096
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
1097
 
1098
    try:
1099
        item = __get_item_from_master(itemId)
1100
    except:
1101
        raise InventoryServiceException(101, "Item not found for itemId " + str(itemId))
1102
 
1103
    validate_vendor_prices(item, vendorItemPricing)
1104
 
1105
    try:
1106
        ds_vendorItemPricing = VendorItemPricing.query.filter(and_(VendorItemPricing.vendor==vendor, VendorItemPricing.item_id==itemId)).one()
1107
    except:
1108
        ds_vendorItemPricing = VendorItemPricing()
1109
        ds_vendorItemPricing.vendor = vendor
1110
        ds_vendorItemPricing.item_id = itemId
1111
 
1112
    subject = ""
1113
    message = ""
1114
    if vendorItemPricing.mop:
1115
        ds_vendorItemPricing.mop = vendorItemPricing.mop
1116
    if vendorItemPricing.dealerPrice:
1117
        ds_vendorItemPricing.dealerPrice = vendorItemPricing.dealerPrice
1118
    if vendorItemPricing.transferPrice:
1119
        if vendorItemPricing.transferPrice != ds_vendorItemPricing.transfer_price:
6617 amar.kumar 1120
            client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1121
            item = client.getItem(itemId)
1122
            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 1123
            subject = "Alert:Change in Transfer Price {0} {1} {2} {3} {4}".format(item.brand, item.modelName, item.modelNumber, item.color, itemId)
5944 mandeep.dh 1124
        ds_vendorItemPricing.transfer_price = vendorItemPricing.transferPrice
6751 amar.kumar 1125
    if vendorItemPricing.nlc:
1126
        if vendorItemPricing.nlc != ds_vendorItemPricing.nlc:
1127
            client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1128
            item = client.getItem(itemId)
7315 amit.gupta 1129
            message = message + "\nNLC for Item {0} {1} {2} {3} \nand Vendor:{4} is changed from {5} to {6}.".format(item.brand, item.modelName, item.modelNumber, item.color, vendor.name, ds_vendorItemPricing.nlc, vendorItemPricing.nlc)
6751 amar.kumar 1130
            subject = "Alert:Change in NLC {0} {1} {2} {3} {4}".format(item.brand, item.modelName, item.modelNumber, item.color, itemId)
1131
        ds_vendorItemPricing.nlc = vendorItemPricing.nlc
9895 vikram.rag 1132
    session.commit()    
1133
    client = CatalogClient("catalog_service_server_host_staging", "catalog_service_server_port").get_client()
1134
    client.updateNlcAtMarketplaces(itemId,vendorId,ds_vendorItemPricing.nlc)
19247 kshitij.so 1135
    if subject and sendMail:
5944 mandeep.dh 1136
        __send_mail(subject, message)
1137
    return
1138
 
1139
def add_vendor_item_mapping(key, vendorItemMapping):
1140
    if not vendorItemMapping:
1141
        raise InventoryServiceException(108, "Bad vendorItemMapping in request")
1142
    vendorId = vendorItemMapping.vendorId
1143
    itemId = vendorItemMapping.itemId
1144
 
1145
    try:
1146
        vendor = Vendor.query.filter_by(id=vendorId).one()
1147
    except:
1148
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
1149
 
1150
    try:
1151
        ds_vendorItemMapping = VendorItemMapping.query.filter(and_(VendorItemMapping.vendor==vendor, VendorItemMapping.item_id==itemId, VendorItemMapping.item_key==key)).one()
1152
    except:
1153
        ds_vendorItemMapping = VendorItemMapping()
1154
        ds_vendorItemMapping.vendor = vendor
1155
        ds_vendorItemMapping.item_id = itemId
1156
    ds_vendorItemMapping.item_key = vendorItemMapping.itemKey
1157
 
1158
    session.commit()
1159
 
1160
    # Marking the missed inventory as not ignored as the catalog dashboard user has updated their key
1161
    for missedInventoryUpdate in MissedInventoryUpdate.query.filter_by(itemKey = vendorItemMapping.itemKey).all():
1162
        missedInventoryUpdate.isIgnored = 0
1163
    session.commit()
1164
 
1165
    return
1166
 
1167
def validate_vendor_prices(item, vendorPrices):
1168
    if item.mrp != None and item.mrp != "" and vendorPrices.mop != "" and item.mrp <  vendorPrices.mop:
1169
        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))
1170
        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)))
18460 kshitij.so 1171
    return
18459 kshitij.so 1172
    #if vendorPrices.mop != "" and vendorPrices.transferPrice != "" and vendorPrices.transferPrice > vendorPrices.mop:
18460 kshitij.so 1173
#         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))
1174
#         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)))
1175
    #return 
5944 mandeep.dh 1176
 
1177
def get_all_vendors():
1178
    return Vendor.query.all()
1179
 
1180
def get_pending_orders_inventory(vendor_id=1):
1181
    """
1182
    Returns a list of inventory stock for items for which there are pending orders.
1183
    """
1184
 
1185
    warehouse_ids = [warehouse.id for warehouse in Warehouse.query.filter_by(vendor_id = vendor_id)]
1186
    pending_items_inventory = []
1187
    if warehouse_ids:
1188
        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()
1189
    return pending_items_inventory
1190
 
7149 amar.kumar 1191
def get_billable_inventory_and_pending_orders():
1192
    """
1193
    Returns a list of inventory Availability and Reserved Count for items which either have real inventory
1194
    or have pending orders.
1195
    """
1196
 
1197
    warehouse_ids = [warehouse.id for warehouse in Warehouse.query.filter(Warehouse.isAvailabilityMonitored == 1).filter(or_(Warehouse.inventoryType == 'GOOD', Warehouse.warehouseType == 'OURS'))]
1198
    items_inventory = []
1199
    reserved_items_inventory = []
1200
    available_items_inventory = []
1201
    if warehouse_ids:
1202
        reserved_items_inventory = session.query(CurrentInventorySnapshot.item_id, func.sum(CurrentInventorySnapshot.availability), func.sum(CurrentInventorySnapshot.reserved)).filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).group_by(CurrentInventorySnapshot.item_id).having(func.sum(CurrentInventorySnapshot.reserved) > 0).all()
1203
        available_items_inventory = session.query(CurrentInventorySnapshot.item_id, func.sum(CurrentInventorySnapshot.availability), func.sum(CurrentInventorySnapshot.reserved)).filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).group_by(CurrentInventorySnapshot.item_id).having(func.sum(CurrentInventorySnapshot.availability) > 0).all()
1204
 
1205
    items_inventory.extend(reserved_items_inventory)
1206
    items_inventory.extend(available_items_inventory)
1207
    return items_inventory
1208
 
1209
 
5944 mandeep.dh 1210
def close_session():
1211
    if session.is_active:
1212
        print "session is active. closing it."
1213
        session.close()
1214
 
1215
def is_alive():
1216
    try:
1217
        session.query(Vendor.id).limit(1).one()
1218
        return True
1219
    except:
1220
        return False
1221
 
1222
def add_vendor(vendor):
1223
    if not vendor:
1224
        raise InventoryServiceException(108, "Bad vendor")
1225
    if get_vendor(vendor.id):
1226
        #vendor is already present.
1227
        raise InventoryServiceException(101, "Vendor already present")
1228
 
1229
    ds_vendor = Vendor()
1230
    ds_vendor.id = vendor.id
1231
    ds_vendor.name = vendor.name
1232
    session.commit()
1233
    return ds_vendor.id
1234
 
1235
def add_warehouse_vendor_mapping(warehouse_id, VendorId):
1236
    return True
1237
 
1238
def mark_missed_inventory_updates_as_processed(itemKey, warehouseId):
1239
    MissedInventoryUpdate.query.filter_by(itemKey = itemKey, warehouseId = warehouseId).delete()
1240
    session.commit()
1241
 
1242
def get_item_keys_to_be_processed(warehouseId):
1243
    return [i.itemKey for i in MissedInventoryUpdate.query.filter_by(warehouseId = warehouseId, isIgnored = 0)]
1244
 
1245
def reset_availability(itemKey, vendorId, quantity, warehouseId):
1246
    vendorItemMapping = VendorItemMapping.get_by(vendor_id = vendorId, item_key = itemKey)
1247
    if vendorItemMapping:
1248
        itemId = vendorItemMapping.item_id
1249
 
1250
        if skippedItems.has_key(warehouseId) and itemId in skippedItems[warehouseId]:
1251
            quantity = 0
1252
 
1253
        currentInventorySnapshot = CurrentInventorySnapshot.get_by(item_id = itemId, warehouse_id = warehouseId)
1254
        if currentInventorySnapshot:
1255
            currentInventorySnapshot.availability = quantity
5978 rajveer 1256
            clear_item_availability_cache(itemId) 
5944 mandeep.dh 1257
        else:
1258
            add_inventory(itemId, warehouseId, quantity)
1259
 
1260
    else:
1261
        raise InventoryServiceException(101, 'VendorMapping not found for: ' + itemKey)
1262
    session.commit()
1263
 
1264
def reset_availability_for_warehouse(warehouseId):
13149 manish.sha 1265
    itemIds = []
5944 mandeep.dh 1266
    for currentInventorySnapshot in CurrentInventorySnapshot.query.filter_by(warehouse_id=warehouseId).all():
1267
        currentInventorySnapshot.availability = 0
13149 manish.sha 1268
        itemIds.append(currentInventorySnapshot.item_id)
1269
    clear_item_availability_cache(itemIds) 
5944 mandeep.dh 1270
    session.commit()
1271
 
7718 amar.kumar 1272
def get_our_warehouse_id_for_vendor(vendor_id, billing_warehouse_id):
6467 amar.kumar 1273
    try:
7718 amar.kumar 1274
        warehouse = Warehouse.query.filter_by(vendor_id = vendor_id, warehouseType = 'OURS', inventoryType = 'GOOD', billingWarehouseId = billing_warehouse_id).first()
6467 amar.kumar 1275
        return warehouse.id
1276
    except Exception as e:
1277
        print e;
7755 amar.kumar 1278
        raise InventoryServiceException(101, 'No our warehouse found for vendorId: ' + str(vendor_id))
5944 mandeep.dh 1279
 
1280
def __send_mail(subject, message):
1281
    try:
6029 rajveer 1282
        thread = threading.Thread(target=partial(mail, mail_user, mail_password, to_addresses, subject, message))
5944 mandeep.dh 1283
        thread.start()
1284
    except Exception as ex:
1285
        print ex    
1286
 
1287
def get_shipping_locations():
1288
    shippingLocationIds = {}
1289
    warehouses = Warehouse.query.all()
1290
    for warehouse in warehouses:
1291
        if warehouse.shippingWarehouseId:
1292
            shippingLocationIds[warehouse.shippingWarehouseId] = 1
1293
 
1294
    shippingLocations = []
1295
    for shippingLocationId in shippingLocationIds:
1296
        shippingLocations.append(get_Warehouse(shippingLocationId))
1297
 
1298
    return shippingLocations
1299
 
1300
def get_inventory_snapshot(warehouseId):
1301
    query = CurrentInventorySnapshot.query
1302
 
1303
    if warehouseId:
1304
        query = query.filter_by(warehouse_id = warehouseId)
1305
 
1306
    itemInventoryMap = {}
1307
    for row in query.all():
1308
        if not itemInventoryMap.has_key(row.item_id):
1309
            itemInventoryMap[row.item_id] = []
1310
 
1311
        itemInventoryMap[row.item_id].append(row)
1312
 
1313
    return itemInventoryMap
1314
 
1315
def update_vendor_string(warehouseId, vendorString):
1316
    warehouse = get_Warehouse(warehouseId)
1317
    warehouse.vendorString = vendorString
1318
    session.commit()
1319
 
1320
def __get_item_from_master(item_id):
1321
    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
5978 rajveer 1322
    return client.getItem(item_id)
1323
 
1324
def __check_risky_item(item_id, source_id):
1325
    ## We should get the list of strings which will identify to the catalog servers
1326
    if source_id == 1:
1327
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1328
        client.validateRiskyStatus(item_id)
1329
    if source_id == 2:
1330
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
1331
        client.validateRiskyStatus(item_id)
1332
 
1333
def __get_item_from_source(item_id, source_id):
1334
    if source_id == 1:
1335
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1336
        return client.getItem(item_id)
1337
    if source_id == 2:
1338
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
6531 vikram.rag 1339
        return client.getItem(item_id)
1340
 
1341
def get_monitored_warehouses_for_vendors(vendorIds):
1342
    w = []
1343
    for wh in Warehouse.query.filter_by(isAvailabilityMonitored = 1).all():
1344
        if wh.vendor.id in (vendorIds):
1345
            w.append(to_t_warehouse(wh).id)
1346
    return w
1347
def get_ignored_warehouseids_and_itemids():
1348
    iw = []
1349
    for i in IgnoredInventoryUpdateItems.query.all():
1350
        iw.append(to_t_itemidwarehouseid(i)) 
1351
    return iw
1352
def insert_item_to_ignore_inventory_update_list(item_id,warehouse_id):
1353
    try:
1354
        ds_warehouse=IgnoredInventoryUpdateItems()
1355
        ds_warehouse.item_id=item_id
1356
        ds_warehouse.warehouse_id=warehouse_id
6532 amit.gupta 1357
        clear_item_availability_cache(item_id)
6531 vikram.rag 1358
        session.commit()
1359
        return True
1360
    except:
1361
        return False       
1362
def delete_item_from_ignore_inventory_update_list(item_id,warehouse_id):
1363
    try:
1364
        session.query(IgnoredInventoryUpdateItems).filter_by(item_id=item_id,warehouse_id=warehouse_id).delete()
6532 amit.gupta 1365
        clear_item_availability_cache(item_id)
6531 vikram.rag 1366
        session.commit()
1367
        return True
1368
    except:
1369
        return False           
1370
 
1371
def get_all_ignored_inventoryupdate_items_count():
1372
    return  session.query(func.count(distinct(IgnoredInventoryUpdateItems.item_id))).scalar()
1373
 
1374
def get_ignored_inventoryupdate_itemids(offset=0,limit=None):
1375
    itemIds = session.query(distinct(IgnoredInventoryUpdateItems.item_id))
1376
    '''if limit is not None:
1377
        itemIds = itemIds.limit(limit)'''
1378
    print itemIds.all()
1379
    return [id for (id, ) in itemIds.all()]
6821 amar.kumar 1380
 
1381
def update_item_stock_purchase_params(item_id, numOfDaysStock, minStockLevel):
1382
    if numOfDaysStock is None or minStockLevel is None:
1383
        raise InventoryServiceException(108, "Bad params : numOfDaysStock = " + str(numOfDaysStock) + "minStockLevel = " + str(minStockLevel))
1384
    itemStockPurchaseParams = ItemStockPurchaseParams.query.filter_by(item_id = item_id).first()
1385
    if itemStockPurchaseParams is None:
1386
        itemStockPurchaseParams = ItemStockPurchaseParams()
1387
    itemStockPurchaseParams.item_id = item_id
1388
    itemStockPurchaseParams.numOfDaysStock = numOfDaysStock
1389
    itemStockPurchaseParams.minStockLevel = minStockLevel
1390
    session.commit()
1391
 
1392
def get_item_stock_purchase_params(item_id):
1393
    return ItemStockPurchaseParams.query.filter_by(item_id = item_id).first()
1394
 
1395
def add_oos_status_for_item(oosStatusMap, date):
1396
 
1397
    oosDate = to_py_date(date)
1398
    oosDate.replace(second=0, microsecond=0)
1399
 
1400
    cartAdditionStartDate = oosDate - datetime.timedelta(days = 1)
1401
 
1402
    client = TransactionClient().get_client()
1403
 
1404
    #Gets physical orders in the last day
1405
    orders = client.getPhysicalOrders(to_java_date(cartAdditionStartDate), to_java_date(oosDate))
8019 amar.kumar 1406
    rtoOrders = client.getAllOrders([20], 0, 0, 0)
9665 rajveer 1407
    orderCountByItemIdSourceId = {}
1408
    rtoOrderCountByItemIdSourceId = {}
1409
 
6821 amar.kumar 1410
    for order in orders:
9665 rajveer 1411
        if not orderCountByItemIdSourceId.has_key(order.lineitems[0].item_id):
1412
            orderCountByItemIdSourceId[order.lineitems[0].item_id] = {}
1413
 
1414
        if orderCountByItemIdSourceId[order.lineitems[0].item_id].has_key(order.source):
18430 manish.sha 1415
            orderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = orderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] + order.lineitems[0].quantity
6821 amar.kumar 1416
        else:
18430 manish.sha 1417
            orderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = order.lineitems[0].quantity
9665 rajveer 1418
 
8019 amar.kumar 1419
 
1420
    for order in rtoOrders:
9665 rajveer 1421
        if not rtoOrderCountByItemIdSourceId.has_key(order.lineitems[0].item_id):
1422
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id] = {}
1423
 
1424
        if rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id].has_key(order.source):
18430 manish.sha 1425
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] + order.lineitems[0].quantity 
8019 amar.kumar 1426
        else:
18430 manish.sha 1427
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = order.lineitems[0].quantity
9665 rajveer 1428
 
1429
 
6821 amar.kumar 1430
    for itemId, status in oosStatusMap.iteritems():
9665 rajveer 1431
        total_order_count = 0 
9791 rajveer 1432
        total_rto_count = 0
13726 manish.sha 1433
        for sid in (1,3,4,6,7,8):
6821 amar.kumar 1434
            oosStatus = OOSStatus()
1435
            oosStatus.item_id = itemId
1436
            oosStatus.date = oosDate
9791 rajveer 1437
            oosStatus.sourceId  = sid
1438
            order_count = 0
1439
            rto_count = 0
1440
            if orderCountByItemIdSourceId.has_key(itemId) and orderCountByItemIdSourceId[itemId].has_key(sid):
1441
                order_count = orderCountByItemIdSourceId[itemId][sid]
1442
            if rtoOrderCountByItemIdSourceId.has_key(itemId) and rtoOrderCountByItemIdSourceId[itemId].has_key(sid):
18430 manish.sha 1443
                rto_count = rtoOrderCountByItemIdSourceId[itemId][sid]
9791 rajveer 1444
            oosStatus.num_orders = order_count
1445
            oosStatus.rto_orders = rto_count
9666 rajveer 1446
            oosStatus.is_oos = status
9791 rajveer 1447
            if oosStatus.is_oos and order_count > 0:
1448
                oosStatus.is_oos = False
1449
            total_order_count = total_order_count + order_count
1450
            total_rto_count = total_rto_count + rto_count
1451
        oosStatus = OOSStatus()
1452
        oosStatus.item_id = itemId
1453
        oosStatus.date = oosDate
1454
        oosStatus.sourceId  = 0
1455
        oosStatus.num_orders = total_order_count
1456
        oosStatus.rto_orders = total_rto_count
9804 rajveer 1457
        if itemId in orderCountByItemIdSourceId and 1 in orderCountByItemIdSourceId[itemId]:
1458
            order_count = orderCountByItemIdSourceId[itemId][1]
9791 rajveer 1459
        oosStatus.is_oos = status
1460
        if oosStatus.is_oos and order_count > 0:
1461
            oosStatus.is_oos = False
6821 amar.kumar 1462
 
9791 rajveer 1463
        session.commit()
1464
 
9861 rajveer 1465
 
1466
    itemCountMap = {}
1467
    oosDate = oosDate - datetime.timedelta(days = 1) - datetime.timedelta(hours = 1)
1468
    lines = session.query(OOSStatus.item_id, func.sum(OOSStatus.num_orders)/func.count(OOSStatus.num_orders)).filter(OOSStatus.date >= oosDate).filter(OOSStatus.sourceId == 1).filter(OOSStatus.is_oos == 0).group_by(OOSStatus.item_id).all()
1469
    for line in lines:
1470
        item_id = line[0]
9896 rajveer 1471
        quantity = int(math.ceil(max(1,2*line[1])))
9861 rajveer 1472
        itemCountMap[item_id] = quantity
9862 rajveer 1473
    cl = CatalogClient('catalog_service_server_host_prod','catalog_service_server_port').get_client()
9861 rajveer 1474
    cl.updateItemHoldInventory(itemCountMap)
9791 rajveer 1475
 
9665 rajveer 1476
def get_oos_statuses_for_x_days_for_item(itemId, sourceId, days):
6832 amar.kumar 1477
    timestamp = datetime.datetime.now()
9640 amar.kumar 1478
    timestamp = timestamp - datetime.timedelta(days = days)
9665 rajveer 1479
    return OOSStatus.query.filter_by(item_id = itemId).filter_by(sourceId = sourceId).filter(OOSStatus.date > timestamp).all()
6857 amar.kumar 1480
 
10126 amar.kumar 1481
def get_oos_statuses_for_x_days(sourceId, days):
1482
    timestamp = datetime.datetime.now()
1483
    timestamp = timestamp - datetime.timedelta(days = days)
1484
    if sourceId == -1:
1485
        return OOSStatus.query.filter(OOSStatus.date > timestamp).all()
1486
    else:
1487
        return OOSStatus.query.filter_by(sourceId = sourceId).filter(OOSStatus.date > timestamp).all()
1488
 
6857 amar.kumar 1489
def get_non_zero_item_stock_purchase_params():
7281 kshitij.so 1490
    return ItemStockPurchaseParams.query.filter(or_("numOfDaysStock!=0","minStockLevel!=0"))
1491
 
7972 amar.kumar 1492
def get_last_n_day_sale_for_item(itemId, numberOfDays):
1493
    lastNdaySale = ""
9685 rajveer 1494
    oosStatuses = get_oos_statuses_for_x_days_for_item(itemId, 0, numberOfDays)
7972 amar.kumar 1495
    for oosStatus in oosStatuses:
1496
        if oosStatus.is_oos == True:
1497
            lastNdaySale +="X-"
1498
        else:
1499
            lastNdaySale +=str(oosStatus.num_orders) + "-"
1500
    return lastNdaySale[:-1] 
1501
 
7281 kshitij.so 1502
def get_warehouse_name(warehouseId):
1503
    row = Warehouse.get_by(id = warehouseId)
1504
    return row.displayName
1505
 
1506
def get_amazon_inventory_for_item(amazonItemId):
1507
    inventory = AmazonInventorySnapshot.get_by(item_id=amazonItemId)
1508
    return inventory
1509
 
1510
def get_all_amazon_inventory():
1511
    return session.query(AmazonInventorySnapshot).all()
1512
 
10450 vikram.rag 1513
def add_or_update_amazon_inventory_for_item(amazoninventorysnapshot,time):
7281 kshitij.so 1514
    inventory = AmazonInventorySnapshot.get_by(item_id = amazoninventorysnapshot.item_id)
1515
    if inventory is None:
1516
        amazon_inventory = AmazonInventorySnapshot()
1517
        amazon_inventory.item_id = amazoninventorysnapshot.item_id
1518
        amazon_inventory.availability = amazoninventorysnapshot.availability
1519
        amazon_inventory.reserved = amazoninventorysnapshot.reserved
10450 vikram.rag 1520
        amazon_inventory.is_oos = amazoninventorysnapshot.is_oos
1521
        if time != 0:
1522
            amazon_inventory.lastUpdatedOnAmazon = to_py_date(time)
1523
    else: 
7281 kshitij.so 1524
        inventory.availability = amazoninventorysnapshot.availability
1525
        inventory.reserved = amazoninventorysnapshot.reserved
10450 vikram.rag 1526
        if not inventory.is_oos and (to_py_date(time) - inventory.lastUpdatedOnAmazon).days == 0:
1527
            pass
1528
        else:
1529
            inventory.is_oos = amazoninventorysnapshot.is_oos
1530
        if time != 0:    
1531
            inventory.lastUpdatedOnAmazon = to_py_date(time)      
7281 kshitij.so 1532
    session.commit()
1533
 
8182 amar.kumar 1534
def add_update_hold_inventory(itemId, warehouseId, holdQuantity, source):
9762 amar.kumar 1535
    if holdQuantity <0:
1536
        print "Negative holdQuantity : " + str(holdQuantity) + " is not allowed"
1537
        raise InventoryServiceException(108, "Negative heldQuantity is not allowed")
8197 amar.kumar 1538
    hold_inventory_detail = HoldInventoryDetail.get_by(item_id = itemId, warehouse_id=warehouseId, source = source)
1539
    if  hold_inventory_detail is None:
8182 amar.kumar 1540
        diffTobeAddedInCIS = holdQuantity
1541
        hold_inventory_detail = HoldInventoryDetail()
1542
        hold_inventory_detail.item_id = itemId 
1543
        hold_inventory_detail.warehouse_id = warehouseId 
1544
        hold_inventory_detail.held = holdQuantity 
1545
        hold_inventory_detail.source = source
1546
    else:
8497 amar.kumar 1547
        diffTobeAddedInCIS = holdQuantity - hold_inventory_detail.held
8182 amar.kumar 1548
        hold_inventory_detail.held = holdQuantity
1549
 
1550
    current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
1551
    if not current_inventory_snapshot:
1552
        current_inventory_snapshot = CurrentInventorySnapshot()
1553
        current_inventory_snapshot.item_id = itemId
1554
        current_inventory_snapshot.warehouse_id = warehouseId
1555
        current_inventory_snapshot.availability = 0
1556
        current_inventory_snapshot.reserved = 0
1557
        current_inventory_snapshot.held = 0
1558
    current_inventory_snapshot.held = current_inventory_snapshot.held + diffTobeAddedInCIS
1559
    session.commit()
1560
    #**Update item availability cache**#
1561
    clear_item_availability_cache(itemId)
8282 kshitij.so 1562
 
1563
def add_or_update_amazon_fba_inventory(amazonfbainventorysnapshot):
11173 vikram.rag 1564
    inventory = AmazonFbaInventorySnapshot.query.filter_by(item_id = amazonfbainventorysnapshot.item_id,location=amazonfbainventorysnapshot.location).first()
8282 kshitij.so 1565
    if inventory is None:
1566
        amazon_fba_inventory = AmazonFbaInventorySnapshot()
1567
        amazon_fba_inventory.item_id = amazonfbainventorysnapshot.item_id
1568
        amazon_fba_inventory.availability = amazonfbainventorysnapshot.availability
11173 vikram.rag 1569
        amazon_fba_inventory.location = amazonfbainventorysnapshot.location
1570
        amazon_fba_inventory.reserved = amazonfbainventorysnapshot.reserved
1571
        amazon_fba_inventory.inbound = amazonfbainventorysnapshot.inbound
1572
        amazon_fba_inventory.unfulfillable = amazonfbainventorysnapshot.unfulfillable
1573
 
8282 kshitij.so 1574
    else:
11173 vikram.rag 1575
        print 'updating'
8282 kshitij.so 1576
        inventory.availability = amazonfbainventorysnapshot.availability
11173 vikram.rag 1577
        inventory.location = amazonfbainventorysnapshot.location
1578
        inventory.reserved = amazonfbainventorysnapshot.reserved
1579
        inventory.inbound = amazonfbainventorysnapshot.inbound
1580
        inventory.unfulfillable = amazonfbainventorysnapshot.unfulfillable
8282 kshitij.so 1581
 
1582
 
1583
def get_amazon_fba_inventory(itemId):
11173 vikram.rag 1584
    return AmazonFbaInventorySnapshot.query.filter_by(item_id = itemId)
8282 kshitij.so 1585
 
8363 vikram.rag 1586
def get_all_amazon_fba_inventory():
1587
    return AmazonFbaInventorySnapshot.query.all() 
1588
 
12799 manish.sha 1589
def get_oursgood_warehouseids_for_location(stateId):
8363 vikram.rag 1590
    warehouseId=[]
12799 manish.sha 1591
    x= session.query(Warehouse.id).filter(Warehouse.id==Warehouse.billingWarehouseId).filter(Warehouse.warehouseType=='OURS').filter(Warehouse.state_id==stateId).all()
8363 vikram.rag 1592
    for id in x:
1593
        warehouseId.append(id[0])
1594
    return session.query(Warehouse.id).filter(Warehouse.inventoryType=='GOOD').filter(Warehouse.warehouseType=='OURS').filter(Warehouse.billingWarehouseId.in_(warehouseId)).all()
8954 vikram.rag 1595
 
1596
def get_holdinventorydetail_forItem_forWarehouseId_exceptsource(item_id,warehouse_id,source):
1597
    holddetails = HoldInventoryDetail.query.filter(HoldInventoryDetail.item_id == item_id).all()
1598
    print holddetails
1599
    hold = 0
1600
    for holddetail in holddetails:
1601
        if holddetail.source !=source and holddetail.warehouse_id == warehouse_id:
1602
            hold = hold + holddetail.held
9404 vikram.rag 1603
    return hold
1604
 
1605
def get_snapdeal_inventory_for_item(id):
1606
    print SnapdealInventorySnapshot.get_by(item_id = id)
1607
    return SnapdealInventorySnapshot.get_by(item_id = id)
1608
 
1609
def add_or_update_snapdeal_inventor_for_item(snapdealinventoryitem):
1610
    snapdeal_inventory_item = SnapdealInventorySnapshot.get_by(item_id = snapdealinventoryitem.item_id)
1611
    if snapdeal_inventory_item is None:
1612
        snapdeal_inventory_item = SnapdealInventorySnapshot()
1613
        snapdeal_inventory_item.item_id = snapdealinventoryitem.item_id
1614
        snapdeal_inventory_item.availability = snapdealinventoryitem.availability
9495 vikram.rag 1615
        snapdeal_inventory_item.pendingOrders = snapdealinventoryitem.pendingOrders
9404 vikram.rag 1616
        snapdeal_inventory_item.lastUpdatedOnSnapdeal = to_py_date(snapdealinventoryitem.lastUpdatedOnSnapdeal)
10450 vikram.rag 1617
        snapdeal_inventory_item.is_oos = snapdealinventoryitem.is_oos
9404 vikram.rag 1618
    else:
1619
        snapdeal_inventory_item.availability = snapdealinventoryitem.availability
9495 vikram.rag 1620
        snapdeal_inventory_item.pendingOrders = snapdealinventoryitem.pendingOrders
10450 vikram.rag 1621
        if not snapdeal_inventory_item.is_oos and (to_py_date(snapdealinventoryitem.lastUpdatedOnSnapdeal) - snapdeal_inventory_item.lastUpdatedOnSnapdeal).days == 0:
1622
            pass
1623
        else:
1624
            snapdeal_inventory_item.is_oos = snapdealinventoryitem.is_oos
9404 vikram.rag 1625
        snapdeal_inventory_item.lastUpdatedOnSnapdeal = to_py_date(snapdealinventoryitem.lastUpdatedOnSnapdeal)
1626
    session.commit()
8954 vikram.rag 1627
 
9404 vikram.rag 1628
def get_nlc_for_warehouse(warehouse_id,itemid):
1629
    warehouse = Warehouse.get_by(id=warehouse_id)
1630
    if warehouse is None:
1631
        return 0
1632
    vendoritempricing = VendorItemPricing.query.filter_by(item_id=itemid, vendor_id=warehouse.vendor_id).first()
1633
    '''vendoritempricing = VendorItemPricing.get_by(id=warehouse.vendor_id,item_id=itemid)'''
1634
    if vendoritempricing is None:
1635
        return 0
9456 vikram.rag 1636
    return vendoritempricing.nlc
1637
 
9495 vikram.rag 1638
def get_snapdeal_inventory_snapshot():
9640 amar.kumar 1639
    return SnapdealInventorySnapshot.query.all()
10050 vikram.rag 1640
 
9640 amar.kumar 1641
def get_held_inventory_map_for_item(itemId, warehouseId):
1642
    heldInventoryMap = {}
1643
    holdInventories = HoldInventoryDetail.query.filter_by(item_id= itemId, warehouse_id = warehouseId).all()
1644
    for holdInventory in holdInventories:
1645
        heldInventoryMap[holdInventory.source] = holdInventory.held
1646
    return heldInventoryMap 
10050 vikram.rag 1647
 
9761 amar.kumar 1648
def get_hold_inventory_details(itemId, warehouseId, source):
1649
    heldInventoryQuery = HoldInventoryDetail.query
1650
    if itemId:
1651
        heldInventoryQuery = heldInventoryQuery.filter_by(item_id = itemId)
1652
    if warehouseId:
1653
        heldInventoryQuery = heldInventoryQuery.filter_by(warehouse_id = warehouseId)
1654
    if source:
1655
        heldInventoryQuery = heldInventoryQuery.filter_by(source = source)
1656
    holdInventoryDetails = heldInventoryQuery.all()
1657
    return holdInventoryDetails
9896 rajveer 1658
 
10450 vikram.rag 1659
def add_or_update_flipkart_inventory_snapshot(flipkartInventorySnapshot,time):
10050 vikram.rag 1660
    for snapshot in flipkartInventorySnapshot:
1661
        flipkart_inventory = FlipkartInventorySnapshot.get_by(item_id = snapshot.item_id)
1662
        if flipkart_inventory is None:
1663
            flipkart_inventory = FlipkartInventorySnapshot()
1664
            flipkart_inventory.item_id = snapshot.item_id
1665
            flipkart_inventory.availability = snapshot.availability
1666
            flipkart_inventory.createdOrders = snapshot.createdOrders
1667
            flipkart_inventory.heldOrders = snapshot.heldOrders
10450 vikram.rag 1668
            flipkart_inventory.is_oos = snapshot.is_oos
1669
            flipkart_inventory.lastUpdatedOnFlipkart = to_py_date(time) 
10050 vikram.rag 1670
        else:
1671
            flipkart_inventory.availability = snapshot.availability
1672
            flipkart_inventory.createdOrders = snapshot.createdOrders
1673
            flipkart_inventory.heldOrders = snapshot.heldOrders
10450 vikram.rag 1674
            if not flipkart_inventory.is_oos and (to_py_date(time) - flipkart_inventory.lastUpdatedOnFlipkart).days == 0:
1675
                pass
1676
            else:
1677
                flipkart_inventory.is_oos = snapshot.is_oos
1678
            flipkart_inventory.lastUpdatedOnFlipkart = to_py_date(time) 
10050 vikram.rag 1679
    session.commit()
1680
 
1681
def get_flipkart_inventory_snapshot():
1682
    return FlipkartInventorySnapshot.query.all()     
1683
 
10097 kshitij.so 1684
def get_flipkart_inventory_for_Item(itemId):
10485 vikram.rag 1685
    return FlipkartInventorySnapshot.get_by(item_id = itemId)
1686
 
1687
def get_state_master():
1688
    stateIdNameMap = {} 
1689
    statemaster = StateMaster.query.all()
1690
    for state in statemaster:
12280 amit.gupta 1691
        stateIdNameMap[state.id] = to_t_state(state)
10544 vikram.rag 1692
    return stateIdNameMap    
1693
 
1694
def update_snapdeal_stock_at_eod(allsnapdealstock):
1695
    for stockitem in allsnapdealstock:
1696
        snapdealstockateod = SnapdealStockAtEOD()
1697
        snapdealstockateod.item_id = stockitem.item_id
1698
        snapdealstockateod.availability = stockitem.availability
1699
        snapdealstockateod.date =  to_py_date(stockitem.date)
1700
    session.commit()
1701
 
1702
def update_flipkart_stock_at_eod(allflipkartstock):
1703
    for stockitem in allflipkartstock:
1704
        snapdealstockateod = FlipkartStockAtEOD()
1705
        snapdealstockateod.item_id = stockitem.item_id
1706
        snapdealstockateod.availability = stockitem.availability
1707
        snapdealstockateod.date =  to_py_date(stockitem.date)
1708
    session.commit()
10687 rajveer 1709
 
12363 kshitij.so 1710
def get_wanlc_for_source(item_id,sourceId):
1711
    stockWanlc = StockWeightedNlcInfo.query.filter(StockWeightedNlcInfo.itemId==item_id).filter(StockWeightedNlcInfo.source==sourceId).order_by(desc(StockWeightedNlcInfo.updatedTimestamp)).limit(1).all()
1712
    if stockWanlc is None or len(stockWanlc)==0:
1713
        return 0.0
1714
    else:
1715
        return stockWanlc[0].avgWeightedNlc
1716
 
1717
def get_all_available_amazon_inventory():
19247 kshitij.so 1718
    return AmazonFbaInventorySnapshot.query.filter(AmazonFbaInventorySnapshot.availability>0).all()
1719
 
1720
def add_vendor_item_pricing_in_bulk(vendorItemPricingList):
1721
    exceptionItems = []
1722
    for vendorItemPricing in vendorItemPricingList:
1723
        try:
1724
            add_vendor_pricing(vendorItemPricing, False)
1725
        except:
1726
            exceptionItems.append(vendorItemPricing.itemId)
1727
    return exceptionItems
1728
 
1729
def add_inventory_in_bulk(bulkInventoryList):
1730
    for item in bulkInventoryList:
19989 kshitij.so 1731
        add_inventory(item.item_id, item.warehouse_id, item.inventory, True)
19247 kshitij.so 1732
 
1733
 
12363 kshitij.so 1734