Subversion Repositories SmartDukaan

Rev

Rev 22722 | Rev 23029 | 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
22991 amit.gupta 54
 
55
#right now these warehouse ids are ignored.
22721 amit.gupta 56
physicalWarehouseIdsForFofo = [7678, 7681]
22722 amit.gupta 57
vendorWarehouseIdsForFofo = []
6498 vikram.rag 58
 
19413 amit.gupta 59
last_date = datetime.date.today()
60
adjusted_dates={}
61
 
5944 mandeep.dh 62
def initialize(dbname='inventory', db_hostname="localhost"):
63
    DataService.initialize(dbname, db_hostname)
19413 amit.gupta 64
    __populateWarehouseMap()
5944 mandeep.dh 65
 
19413 amit.gupta 66
def __populateWarehouseMap():
67
    warehouses = Warehouse.query.filter(Warehouse.warehouseType.in_(['OURS', 'THIRD_PARTY'])).filter(Warehouse.inventoryType == 'GOOD').all()
68
    for warehouse in warehouses:
69
        warehouseMap[warehouse.id] = warehouse
70
        if not logisticsLocationWarehouseMap.has_key(warehouse.logisticsLocation):
71
            logisticsLocationWarehouseMap[warehouse.logisticsLocation] = []
72
        logisticsLocationWarehouseMap[warehouse.logisticsLocation].append(warehouse.id)
22722 amit.gupta 73
        if warehouse.billingWarehouseId in physicalWarehouseIdsForFofo:
74
            vendorWarehouseIdsForFofo.append(warehouse.id)
19413 amit.gupta 75
 
76
 
5944 mandeep.dh 77
def get_Warehouse(warehouse_id):
78
    return Warehouse.get_by(id=warehouse_id)
79
 
80
def get_vendor(vendorId):
81
    return Vendor.get_by(id=vendorId)
82
 
7410 amar.kumar 83
def get_state(stateId):
84
    return StateMaster.get_by(id=stateId)
85
 
5944 mandeep.dh 86
def get_all_warehouses_by_status(status):
87
    return Warehouse.query.all()
88
 
89
def get_all_items_for_warehouse(warehouse_id):
90
    warehouse = get_Warehouse(warehouse_id)
91
    if not warehouse:
92
        raise InventoryServiceException(108, "bad warehouse")
93
    return warehouse.all_items
94
 
95
def add_warehouse(warehouse):
96
    if not warehouse:
97
        raise InventoryServiceException(108, "Bad warehouse")
98
    if get_Warehouse(warehouse.id):
99
        #warehouse is already present.
100
        raise InventoryServiceException(101, "Warehouse already present")
101
 
102
    ds_warehouse = Warehouse()
103
    ds_warehouse.location = warehouse.location
104
    ds_warehouse.status = 3
105
    ds_warehouse.addedOn = datetime.datetime.now()
106
    ds_warehouse.lastCheckedOn = datetime.datetime.now()
107
    ds_warehouse.tinNumber = warehouse.tinNumber
108
    ds_warehouse.pincode = warehouse.pincode
109
    ds_warehouse.billingType = warehouse.billingType
110
    ds_warehouse.billingWarehouseId = warehouse.billingWarehouseId
111
    ds_warehouse.displayName = warehouse.displayName
112
    ds_warehouse.inventoryType = InventoryType._VALUES_TO_NAMES[warehouse.inventoryType]
113
    ds_warehouse.isAvailabilityMonitored = warehouse.isAvailabilityMonitored
114
    ds_warehouse.logisticsLocation = warehouse.logisticsLocation
115
    ds_warehouse.shippingWarehouseId = warehouse.shippingWarehouseId
116
    ds_warehouse.transferDelayInHours = warehouse.transferDelayInHours
117
    ds_warehouse.vendor = get_vendor(warehouse.vendor.id)
7410 amar.kumar 118
    ds_warehouse.state = get_state(warehouse.stateId)
5944 mandeep.dh 119
    ds_warehouse.warehouseType = WarehouseType._VALUES_TO_NAMES[warehouse.warehouseType]    
120
    if warehouse.vendorString:
121
        ds_warehouse.vendorString = warehouse.vendorString
122
    session.commit()
123
    return ds_warehouse.id
124
 
6498 vikram.rag 125
def get_ignored_items(warehouse_id): 
6531 vikram.rag 126
    Ignored_inventory_items = IgnoredInventoryUpdateItems.query.filter_by(warehouse_id=warehouse_id).all()
6498 vikram.rag 127
    negativeItems = []
128
    for Ignored_inventory_item in Ignored_inventory_items:
129
        try:
130
            item_id = Ignored_inventory_item.item_id
131
            negativeItems.append(item_id)
132
        except:
133
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
134
    return negativeItems
135
 
22630 amit.gupta 136
def get_ignored_warehouses(item_id):
137
    warehouses = []
138
    #No item availability cache for Hotspot Specific Store
139
    #No virtual is allowed
6539 amit.gupta 140
    Ignored_inventory_items = IgnoredInventoryUpdateItems.query.filter_by(item_id=item_id).all()
6510 rajveer 141
    for Ignored_inventory_item in Ignored_inventory_items:
142
        warehouses.append(Ignored_inventory_item.warehouse_id)
22722 amit.gupta 143
    return warehouses + vendorWarehouseIdsForFofo
6510 rajveer 144
 
5944 mandeep.dh 145
def update_inventory_history(warehouse_id, timestamp, availability):
146
    warehouse = get_Warehouse(warehouse_id)
147
    if not warehouse:
148
        raise InventoryServiceException(107, "Warehouse? Where?")
149
    vendor = warehouse.vendor
150
    time = datetime.datetime.now()
151
    for item_key, quantity in availability.iteritems():
152
        try:
153
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
5960 mandeep.dh 154
            item_id = vendor_item_mapping.item_id
5944 mandeep.dh 155
        except:
6531 vikram.rag 156
            continue  
5944 mandeep.dh 157
        try:
6510 rajveer 158
            item_inventory_history = ItemInventoryHistory()
159
            item_inventory_history.warehouse = warehouse
160
            item_inventory_history.item_id = item_id
161
            item_inventory_history.timestamp = time
162
            item_inventory_history.availability = quantity
5944 mandeep.dh 163
        except:
164
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
165
    session.commit()
166
 
167
def update_inventory(warehouse_id, timestamp, availability):
168
    warehouse = get_Warehouse(warehouse_id)
169
    if not warehouse:
170
        raise InventoryServiceException(107, "Warehouse? Where?")
6510 rajveer 171
 
5944 mandeep.dh 172
    time = datetime.datetime.now()
173
    warehouse.lastCheckedOn = time
174
    warehouse.vendorString = timestamp
175
    vendor = warehouse.vendor
176
    item_ids = []
177
    for item_key, quantity in availability.iteritems():
178
        try:
179
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
180
            item_id = vendor_item_mapping.item_id
6510 rajveer 181
            item_ids.append(item_id)
5944 mandeep.dh 182
        except:
183
            print 'Skipping update for ' + item_key + ' quantity ' + str(quantity) + ' warehouse id: ' + str(warehouse_id)
184
            __send_mail_for_missing_key(item_key, quantity, warehouse_id)
185
            continue
186
        try:
187
            current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=item_id, warehouse=warehouse)
188
            if not current_inventory_snapshot:
189
                current_inventory_snapshot = CurrentInventorySnapshot()
190
                current_inventory_snapshot.item_id = item_id
191
                current_inventory_snapshot.warehouse = warehouse
192
                current_inventory_snapshot.availability = 0
193
                current_inventory_snapshot.reserved = 0
8204 amar.kumar 194
                current_inventory_snapshot.held = 0
5944 mandeep.dh 195
            # added the difference in the current inventory    
196
            current_inventory_snapshot.availability = current_inventory_snapshot.availability + quantity
197
            item = __get_item_from_master(item_id)
198
            try:
199
                if quantity > 0 and __get_item_reserved(item_id) > 0:
200
                    cl = TransactionClient().get_client()
201
                    #FIXME hardcoding for warehouse id 
202
                    cl.addAlert(AlertType.NEW_INVENTORY_ALERT, 5, "Inventory received for item " + item.brand + " " + item.modelName + " " + item.modelNumber + " " +  item.color)
203
            except:
204
                print "Not able to raise alert for incoming inventory" 
205
            if current_inventory_snapshot.availability < 0:
206
                __send_alert_for_negative_availability(item, current_inventory_snapshot.availability, warehouse)
207
        except:
208
            print "Some unforeseen error while updating inventory:", sys.exc_info()[0]
209
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
210
    session.commit()
211
 
212
    #**Update item availability cache**#
213
    for item_id in item_ids:
5978 rajveer 214
        clear_item_availability_cache(item_id)
5944 mandeep.dh 215
 
216
def __send_alert_for_negative_reserved(item, reserved, warehouse):
217
    itemName = " ".join([str(item.id), str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
10253 manish.sha 218
    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 219
 
220
def __send_alert_for_negative_availability(item, availability, warehouse):
221
    itemName = " ".join([str(item.id), str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
5964 amar.kumar 222
    # 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 223
 
224
def __send_mail_for_missing_key(item_key, quantity, warehouse_id):
225
    missedInventoryUpdate = MissedInventoryUpdate.get_by(itemKey = item_key, warehouseId = warehouse_id)
226
    # One email per product key mismatch
227
    if not missedInventoryUpdate:
228
        missedInventoryUpdate = MissedInventoryUpdate()
229
        missedInventoryUpdate.itemKey = item_key
230
        missedInventoryUpdate.quantity = quantity
231
        missedInventoryUpdate.isIgnored = 1
232
        missedInventoryUpdate.timestamp = datetime.datetime.now()
233
        missedInventoryUpdate.warehouseId = warehouse_id
234
        session.commit()
6232 rajveer 235
        try:
8214 amar.kumar 236
            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 237
        except:
238
            print "Not able to send email. No issues, we can continue with updates."
5944 mandeep.dh 239
    else:
240
        missedInventoryUpdate.quantity += quantity
241
        session.commit()
242
 
19989 kshitij.so 243
def add_inventory(itemId, warehouseId, quantity, skipAddition=False):
5944 mandeep.dh 244
    current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
245
    if not current_inventory_snapshot:
246
        current_inventory_snapshot = CurrentInventorySnapshot()
247
        current_inventory_snapshot.item_id = itemId
248
        current_inventory_snapshot.warehouse_id = warehouseId
249
        current_inventory_snapshot.availability = 0
250
        current_inventory_snapshot.reserved = 0
8204 amar.kumar 251
        current_inventory_snapshot.held = 0
19989 kshitij.so 252
    # added the difference in the current inventory
253
    if skipAddition is None or not skipAddition:    
254
        current_inventory_snapshot.availability = current_inventory_snapshot.availability + quantity
255
    else:
256
        current_inventory_snapshot.availability = quantity
5944 mandeep.dh 257
    session.commit()
258
    #**Update item availability cache**#
20849 amit.gupta 259
    clear_item_availability_cache(itemId)
5944 mandeep.dh 260
    if current_inventory_snapshot.availability < 0:
261
        item = __get_item_from_master(itemId)
5978 rajveer 262
        __send_alert_for_negative_availability(item, current_inventory_snapshot.availability, get_Warehouse(warehouseId)) 
5944 mandeep.dh 263
 
264
def add_bad_inventory(itemId, warehouseId, quantity):
265
    bad_inventory_snapshot = BadInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
266
    if not bad_inventory_snapshot:
267
        bad_inventory_snapshot = BadInventorySnapshot()
268
        bad_inventory_snapshot.item_id = itemId
269
        bad_inventory_snapshot.warehouse_id = warehouseId
270
        bad_inventory_snapshot.availability = 0
271
    # added the difference in the current inventory    
272
    bad_inventory_snapshot.availability += quantity
273
    session.commit()
274
    if bad_inventory_snapshot.availability < 0:
275
        item = __get_item_from_master(itemId)
276
        __send_alert_for_negative_availability(item, bad_inventory_snapshot.availability, get_Warehouse(warehouseId))
277
 
278
def get_item_inventory_by_item_id(item_id):
279
    return CurrentInventorySnapshot.query.filter_by(item_id=item_id).all()
280
 
281
def retire_warehouse(warehouse_id):
282
    if not warehouse_id:
283
        raise InventoryServiceException(101, "Bad warehouse id")
284
    warehouse = get_Warehouse(warehouse_id)
285
    if not warehouse:
286
        raise InventoryServiceException(108, "warehouse id not present")
287
    warehouse.status = 0;
288
    session.commit()
289
 
290
def get_item_availability_for_warehouse(warehouse_id, item_id):
6545 rajveer 291
    ignore = IgnoredInventoryUpdateItems.query.filter_by(item_id=item_id).filter_by(warehouse_id = warehouse_id).all()
6544 rajveer 292
    if ignore:
293
        return 0
5944 mandeep.dh 294
 
295
    try:
6544 rajveer 296
        current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id).filter_by(item_id = item_id).one()
15958 amit.gupta 297
        return current_inventory_snapshot.availability - current_inventory_snapshot.reserved - current_inventory_snapshot.held
5944 mandeep.dh 298
    except:
299
        return 0
300
 
6484 amar.kumar 301
def get_item_availability_for_our_warehouses(item_ids):
7699 amar.kumar 302
    our_warehouses = Warehouse.query.filter_by(warehouseType = 'OURS', inventoryType = 'GOOD').all()
303
    our_thirdparty_warehouses = Warehouse.query.filter_by(warehouseType = 'OURS_THIRDPARTY').all()
6484 amar.kumar 304
    warehouse_ids = []
7699 amar.kumar 305
    for warehouse in our_warehouses :
6484 amar.kumar 306
        warehouse_ids.append(warehouse.id)
10170 amar.kumar 307
    #for warehouse in our_thirdparty_warehouses :
308
    #    warehouse_ids.append(warehouse.id)
7699 amar.kumar 309
 
6484 amar.kumar 310
    availability_map = dict()
311
 
312
    try :
313
        for item_id in item_ids :
314
            total_availability = 0
315
            for current_inventory_snapshot in CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).filter_by(item_id = item_id).all():
316
                total_availability += current_inventory_snapshot.availability
317
            if total_availability >0:
318
                availability_map[item_id] = total_availability
319
    except Exception as e:
320
        print e
321
        raise PurchaseServiceException(101, 'Exception while fetching availability of items in our warehouses')
322
 
323
    return availability_map
324
 
22991 amit.gupta 325
#As of now as warehouse can be managed independently we just need to return itemavailability cache for the item ids provided
22719 amit.gupta 326
def get_fofo_availability(item_ids):
327
    returnMap = {}
328
    if not item_ids:
329
        return returnMap
22991 amit.gupta 330
    for item_id in item_ids:
331
        returnMap[item_id] = get_item_availability_for_location(item_id, 1)[4]
22719 amit.gupta 332
    return returnMap
22991 amit.gupta 333
    #TODO: Amit Should be removed physicalWarehouseIdsForFofo
334
#    returnMap = {}
335
#    if not item_ids:
336
#        return returnMap
337
#    snapshots = CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(vendorWarehouseIdsForFofo)).filter(CurrentInventorySnapshot.item_id.in_(item_ids)).all()
338
#    for snapshot in snapshots:
339
#        if returnMap.has_key(snapshot.item_id):
340
#            returnMap[snapshot.item_id] += snapshot.availability - snapshot.reserved - snapshot.held
341
#        else:
342
#            returnMap[snapshot.item_id] = snapshot.availability - snapshot.reserved - snapshot.held 
343
#    return returnMap
22719 amit.gupta 344
 
22721 amit.gupta 345
def get_fofo_fulfilment_warehouse_map(itemIds):
346
    returnMap = {}
22722 amit.gupta 347
    snapshots = CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id.in_(vendorWarehouseIdsForFofo)).filter(CurrentInventorySnapshot.item_id.in_(itemIds)).all()
22721 amit.gupta 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
    Then how shoud we handle virtual because for both source virtual gonna mark
784
    """
785
    """
8954 vikram.rag 786
    Determines the warehouse that should be used to fulfil an order for the given item.
5944 mandeep.dh 787
    Algorithm explained at https://sites.google.com/a/shop2020.in/virtual-w-h-and-inventory/technical-details
788
 
789
    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.
790
    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.
791
 
792
    if item available at any OUR-GOOD warehouse
793
        // OUR-GOOD warehouses have inventory risk; So, we empty them first! 
794
        // We can start with minimum transfer price criterion but down the line we can also bring in Inventory age 
795
        assign OUR-GOOD warehouse with minimum transfer price
796
    else
797
        if Preferred vendor is specified and marked Sticky
798
            // Always purchase from Preferred if its marked sticky
799
            assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
800
        else 
801
            if item available in a THIRDPARTY GOOD/VIRTUAL warehouse
802
                assign THIRDPARTY GOOD/VIRTUAL warehouse where item is available with minimal transfer delay followed by minimum transfer price
803
            else 
804
                // Item not available at any warehouse, OURS or THIRDPARTY
805
                If Preferred vendor is specified
806
                    assign preferred vendor's THIRDPARTY GOOD/VIRTUAL warehouse
807
                else
808
                    assign THIRDPARTY GOOD/VIRTUAL warehouse with minimum transfer price
809
 
810
    Returns an ordered list of size 4 with following elements in the given order:
811
    1. Logistics location of the warehouse which was finally picked up to ship the order.
812
    2. Expected delay added by the category manager.
813
    3. Id of the warehouse which was finally picked up.
814
 
815
    Parameters:
816
     - itemId
817
    """
12963 amit.gupta 818
    if item is None:
819
        item = __get_item_from_source(item_id, source_id)
5944 mandeep.dh 820
    item_pricing = {}
821
    for vendorItemPricing in VendorItemPricing.query.filter_by(item_id=item_id).all():
822
        item_pricing[vendorItemPricing.vendor_id] = vendorItemPricing
823
 
6510 rajveer 824
    ignoredWhs = get_ignored_warehouses(item_id)
825
 
5944 mandeep.dh 826
    warehouses = {}
827
    ourGoodWarehouses = {}
828
    thirdpartyWarehouses = {}
829
    preferredThirdpartyWarehouses = {}
830
    for warehouse in Warehouse.query.all():
7410 amar.kumar 831
        if (warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.BAD] or warehouse.warehouseType == WarehouseType._VALUES_TO_NAMES[WarehouseType.OURS_THIRDPARTY]):
5944 mandeep.dh 832
            continue
833
        warehouses[warehouse.id] = warehouse
834
        if warehouse.warehouseType == WarehouseType._VALUES_TO_NAMES[WarehouseType.OURS]:
835
            if warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
836
                ourGoodWarehouses[warehouse.id] = warehouse
837
        else:
838
            thirdpartyWarehouses[warehouse.id] = warehouse
839
            if item.preferredVendor == warehouse.vendor_id and warehouse.inventoryType == InventoryType._VALUES_TO_NAMES[InventoryType.GOOD]:
840
                preferredThirdpartyWarehouses[warehouse.id] = warehouse
841
 
842
    warehouse_retid = -1
843
    total_availability = 0
844
 
6540 rajveer 845
    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(ourGoodWarehouses, ignoredWhs, item_id, item_pricing, False)
5944 mandeep.dh 846
    if warehouse_retid == -1:
847
        if item.preferredVendor and item.isWarehousePreferenceSticky:
6540 rajveer 848
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(preferredThirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 849
            if warehouse_retid == -1:
850
                warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
851
        else:
6540 rajveer 852
            [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_delay(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing)
5944 mandeep.dh 853
            if warehouse_retid == -1:
854
                if item.preferredVendor:
855
                    warehouse_retid = preferredThirdpartyWarehouses.keys()[0]
856
                else:
6540 rajveer 857
                    [warehouse_retid, total_availability] = __get_warehouse_with_min_transfer_price(thirdpartyWarehouses, ignoredWhs, item_id, item_pricing, True)
5944 mandeep.dh 858
 
859
    warehouse = warehouses[warehouse_retid]
860
    billingWarehouseId = warehouse.billingWarehouseId
861
 
862
    # Fetching billing warehouse of a Good billable warehouse corresponding to the virtual one
863
    if not warehouse.billingWarehouseId:
21152 amit.gupta 864
        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 865
            if w.billingWarehouseId:
866
                billingWarehouseId = w.billingWarehouseId
867
                break
868
 
869
    expectedDelay = item.expectedDelay 
870
    if expectedDelay is None:
871
        print 'expectedDelay field for this item was Null. Resetting it to 0'
872
        expectedDelay = 0
873
    else:
874
        expectedDelay = int(item.expectedDelay)
875
 
876
    if total_availability <= 0:
8026 amar.kumar 877
        if item.preferredVendor in [1, 5]:
6562 rajveer 878
            expectedDelay = expectedDelay + 3
879
        else:
880
            expectedDelay = expectedDelay + 2
6643 rajveer 881
    else:
882
        if warehouse.transferDelayInHours:
883
            expectedDelay = expectedDelay + warehouse.transferDelayInHours / 24
5944 mandeep.dh 884
 
18022 manish.sha 885
    if WarehouseType._NAMES_TO_VALUES[warehouse.warehouseType] == WarehouseType.THIRD_PARTY:
8491 rajveer 886
        expectedDelay = expectedDelay + __get_vendor_holiday_delay(warehouse.vendor_id, expectedDelay) 
887
 
5963 mandeep.dh 888
    total_availability = 0
16029 amit.gupta 889
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
6545 rajveer 890
        if entry.warehouse_id not in ignoredWhs:
16029 amit.gupta 891
            if entry.warehouse_id not in ourGoodWarehouses and entry.warehouse_id not in thirdpartyWarehouses:
16015 amit.gupta 892
                continue
893
            if entry.warehouse_id in ourGoodWarehouses and ourGoodWarehouses[entry.warehouse_id].billingWarehouseId == billingWarehouseId:
894
                total_availability += entry.availability - entry.reserved - entry.held
895
            elif entry.warehouse_id in thirdpartyWarehouses:
896
                vendorId = thirdpartyWarehouses[entry.warehouse_id].vendor_id
897
                for goodWarehouse in ourGoodWarehouses.values():
21152 amit.gupta 898
                    if goodWarehouse.vendor_id==vendorId and goodWarehouse.billingWarehouseId == billingWarehouseId and warehouse.state_id==goodWarehouse.state_id:
16015 amit.gupta 899
                        total_availability += entry.availability - entry.reserved - entry.held
900
                        break
5963 mandeep.dh 901
 
5978 rajveer 902
    item_availability_cache = ItemAvailabilityCache.get_by(itemId=item_id, sourceId=source_id)
5944 mandeep.dh 903
    if item_availability_cache is None:
904
        item_availability_cache = ItemAvailabilityCache()
905
        item_availability_cache.itemId = item_id
5978 rajveer 906
        item_availability_cache.sourceId = source_id
5944 mandeep.dh 907
    item_availability_cache.warehouseId = int(warehouse_retid)
908
    item_availability_cache.expectedDelay = expectedDelay
909
    item_availability_cache.billingWarehouseId = billingWarehouseId
910
    item_availability_cache.sellingPrice = item.sellingPrice
911
    item_availability_cache.totalAvailability = total_availability
16029 amit.gupta 912
    #item_availability_cache.location = warehouse.logisticsLocation 
7589 rajveer 913
    item_availability_cache.weight = 1000*item.weight if item.weight else 300
5944 mandeep.dh 914
    session.commit()
915
 
6540 rajveer 916
def __get_warehouse_with_min_transfer_price(warehouses, ignoredWhs, item_id, item_pricing, ignoreAvailability):
5944 mandeep.dh 917
    warehouse_retid = -1
918
    minTransferPrice = None
919
    total_availability = 0
6013 amar.kumar 920
    availabilityForBillingWarehouses = {}
921
    warehousesAvailability = {}
922
    availability = 0
923
    billing_warehouse_retid = None
5944 mandeep.dh 924
 
925
    if not ignoreAvailability:
926
        for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 927
            entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 928
            entry.held = max(entry.held, 0)
6013 amar.kumar 929
            #if entry.availability > entry.reserved:
8182 amar.kumar 930
            warehousesAvailability[entry.warehouse_id] = [entry.availability, entry.reserved, entry.held] 
5944 mandeep.dh 931
 
6540 rajveer 932
    if len(ignoredWhs) > 0:
933
        for whid in ignoredWhs:
934
            if warehousesAvailability.has_key(whid):
6542 rajveer 935
                warehousesAvailability[whid][0] = 0
6683 rajveer 936
                warehousesAvailability[whid][1] = 0
8182 amar.kumar 937
                warehousesAvailability[whid][2] = 0
6540 rajveer 938
 
5944 mandeep.dh 939
    for warehouse in warehouses.values():
940
        if not ignoreAvailability:
6013 amar.kumar 941
            #TODO Mistake no entry for this warehouse.id in warehouseswithAvailab
942
            if warehouse.id not in warehousesAvailability:
943
                continue
944
            entry = warehousesAvailability[warehouse.id]
945
            if warehouse.billingWarehouseId in availabilityForBillingWarehouses:
946
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
8182 amar.kumar 947
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = availabilityForBillingWarehouses[warehouse.billingWarehouseId] + entry[0] - entry[1] - entry[2]  
5944 mandeep.dh 948
            else:
6013 amar.kumar 949
                if warehouse.billingWarehouseId is not None or warehouse.billingWarehouseId != 0: 
8182 amar.kumar 950
                    availabilityForBillingWarehouses[warehouse.billingWarehouseId] = entry[0] - entry[1] - entry[2]
951
            if entry[0] <= (entry[1] + entry[2]):
5944 mandeep.dh 952
                continue
8182 amar.kumar 953
            total_availability += entry[0] - entry[1] - entry[2]
5944 mandeep.dh 954
 
955
        # Missing transfer price cases should not impact warehouse assignment
956
        transferPrice = None
957
        if item_pricing.has_key(warehouse.vendor_id):
6778 rajveer 958
            transferPrice = item_pricing[warehouse.vendor_id].nlc
5944 mandeep.dh 959
        if minTransferPrice is None or (transferPrice and minTransferPrice > transferPrice):
960
            warehouse_retid = warehouse.id
6013 amar.kumar 961
            billing_warehouse_retid = warehouse.billingWarehouseId
5944 mandeep.dh 962
            minTransferPrice = transferPrice
6013 amar.kumar 963
 
964
 
965
    if billing_warehouse_retid in availabilityForBillingWarehouses: 
966
        availability = availabilityForBillingWarehouses[billing_warehouse_retid]
967
    else:
968
        availability = total_availability
969
 
970
    return [warehouse_retid, availability]
5944 mandeep.dh 971
 
6540 rajveer 972
def __get_warehouse_with_min_transfer_delay(warehouses, ignoredWhs, item_id, item_pricing):
5944 mandeep.dh 973
    minTransferDelay = None
974
    minTransferDelayWarehouses = {}
975
    total_availability = 0
976
 
977
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 978
        entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 979
        entry.held = max(entry.held, 0)
5944 mandeep.dh 980
        if warehouses.has_key(entry.warehouse_id):
981
            warehouse = warehouses[entry.warehouse_id]
6013 amar.kumar 982
            #if entry.availability > entry.reserved:
6683 rajveer 983
            if entry.warehouse_id not in ignoredWhs:
8182 amar.kumar 984
                total_availability += entry.availability - entry.reserved - entry.held
985
            if entry.availability - entry.reserved - entry.held <= 0:
6780 amar.kumar 986
                continue
6013 amar.kumar 987
            transferDelay = warehouse.transferDelayInHours
988
            if minTransferDelay is None or minTransferDelay >= transferDelay:
989
                if minTransferDelay != transferDelay:
990
                    minTransferDelayWarehouses = {}
991
                minTransferDelayWarehouses[warehouse.id] = warehouse
992
                minTransferDelay = transferDelay
5944 mandeep.dh 993
 
6540 rajveer 994
    return [__get_warehouse_with_min_transfer_price(minTransferDelayWarehouses, ignoredWhs, item_id, item_pricing, False)[0], total_availability]
5944 mandeep.dh 995
 
996
def __get_warehouse_with_max_availability(warehouse_ids, item_id):
997
    warehouse_retid = -1
998
    max_availability = 0
999
    total_availability = 0
1000
 
1001
    for entry in CurrentInventorySnapshot.query.filter_by(item_id = item_id).all():
7242 amar.kumar 1002
        entry.reserved = max(entry.reserved, 0)
8524 amar.kumar 1003
        entry.held = max(entry.held, 0)
5944 mandeep.dh 1004
        if entry.warehouse_id in warehouse_ids:
1005
            availability = entry.availability - entry.reserved
1006
            if availability > max_availability:
1007
                warehouse_retid = entry.warehouse_id
1008
                max_availability = availability
1009
            total_availability += availability
1010
 
1011
    return [warehouse_retid, total_availability]
1012
 
8491 rajveer 1013
def __get_vendor_holiday_delay(vendor_id, expectedDelay):
1014
    ## If vendor is closed two days continuously
5944 mandeep.dh 1015
    holidayDelay = 0
8491 rajveer 1016
    currentDate = datetime.date.today()
1017
    expectedDate = currentDate + datetime.timedelta(days = expectedDelay)
1018
    holidays = VendorHolidays.query.filter(VendorHolidays.vendor_id == vendor_id).filter(VendorHolidays.date.between(currentDate, expectedDate)).all()
1019
    if holidays:
1020
        holidayDelay = holidayDelay + len(holidays)
5944 mandeep.dh 1021
    return holidayDelay 
1022
 
1023
def get_item_pricing(item_id, vendorId):
1024
    '''
1025
    if vendor id is -1 then we calculate an average transfer price to be populated
1026
    at the time of order creation. This will be later updated with actual transfer price
1027
    at the time of billing.
1028
    '''
1029
    if(vendorId == -1):
6778 rajveer 1030
        tp_total = 0
1031
        nlc_total = 0
5944 mandeep.dh 1032
        try:
1033
            item_pricings = []
1034
            item = __get_item_from_master(item_id)
1035
            if item.preferredVendor is not None:
1036
                item_pricing = VendorItemPricing.query.filter_by(item_id=item_id, vendor_id=item.preferredVendor).first()
1037
                if item_pricing:
1038
                    item_pricings.append(item_pricing)                    
1039
            else :
1040
                item_pricings = VendorItemPricing.query.filter_by(item_id=item_id).all()
1041
            if item_pricings:
1042
                for item_pricing in item_pricings:
6778 rajveer 1043
                    tp_total += item_pricing.transfer_price
1044
                    nlc_total += item_pricing.nlc
1045
                tp_avg = tp_total / len(item_pricings)
1046
                nlc_avg = nlc_total / len(item_pricings)
1047
                item_pricing.transfer_price = tp_avg
1048
                item_pricing.nlc = nlc_avg
5944 mandeep.dh 1049
            else:
1050
                item_pricing = VendorItemPricing()
1051
                item_pricing.transfer_price = item.sellingPrice
6778 rajveer 1052
                item_pricing.nlc = item.sellingPrice
5944 mandeep.dh 1053
                vendor = Vendor()
1054
                vendor.id = vendorId
1055
                item_pricing.vendor = vendor
1056
                item_pricing.item_id = item_id
1057
 
1058
            return item_pricing
1059
        except:
1060
            raise InventoryServiceException(101, "Item pricing not found ")
1061
    vendor = Vendor.get_by(id=vendorId)    
1062
    try:
1063
        item_pricing = VendorItemPricing.query.filter_by(vendor=vendor, item_id=item_id).one()
1064
        return item_pricing
1065
    except MultipleResultsFound:
1066
        raise InventoryServiceException(110, "Multiple pricing information present for Vendor: " + vendor.name + " and Item: " + str(item_id))
1067
    except NoResultFound:
1068
        raise InventoryServiceException(111, "Missing pricing information for Vendor: " + vendor.name + " and Item: " + str(item_id))
1069
 
1070
def get_all_item_pricing(item_id):
1071
    item_pricing = VendorItemPricing.query.filter_by(item_id=item_id).all()
1072
    return item_pricing
10126 amar.kumar 1073
def get_all_vendor_item_pricing(item_id, vendor_id):
1074
    query = VendorItemPricing.query
1075
    if item_id:
1076
        query = query.filter_by(item_id = item_id)
1077
    if item_id:
1078
        query = query.filter_by(vendor_id = vendor_id)
1079
    item_pricing = query.all()
1080
    return item_pricing
1081
 
5944 mandeep.dh 1082
def get_item_mappings(item_id):
1083
    item_mappings = VendorItemMapping.query.filter_by(item_id=item_id).all()
1084
    return item_mappings
1085
 
19247 kshitij.so 1086
def add_vendor_pricing(vendorItemPricing, sendMail = True):
5944 mandeep.dh 1087
    if not vendorItemPricing:
1088
        raise InventoryServiceException(108, "Bad vendorItemPricing in request")
1089
    vendorId = vendorItemPricing.vendorId
1090
    itemId = vendorItemPricing.itemId
1091
 
1092
    try:
1093
        vendor = Vendor.query.filter_by(id=vendorId).one()
1094
    except:
1095
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
1096
 
1097
    try:
1098
        item = __get_item_from_master(itemId)
1099
    except:
1100
        raise InventoryServiceException(101, "Item not found for itemId " + str(itemId))
1101
 
1102
    validate_vendor_prices(item, vendorItemPricing)
1103
 
1104
    try:
1105
        ds_vendorItemPricing = VendorItemPricing.query.filter(and_(VendorItemPricing.vendor==vendor, VendorItemPricing.item_id==itemId)).one()
1106
    except:
1107
        ds_vendorItemPricing = VendorItemPricing()
1108
        ds_vendorItemPricing.vendor = vendor
1109
        ds_vendorItemPricing.item_id = itemId
1110
 
1111
    subject = ""
1112
    message = ""
1113
    if vendorItemPricing.mop:
1114
        ds_vendorItemPricing.mop = vendorItemPricing.mop
1115
    if vendorItemPricing.dealerPrice:
1116
        ds_vendorItemPricing.dealerPrice = vendorItemPricing.dealerPrice
1117
    if vendorItemPricing.transferPrice:
1118
        if vendorItemPricing.transferPrice != ds_vendorItemPricing.transfer_price:
6617 amar.kumar 1119
            client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1120
            item = client.getItem(itemId)
1121
            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 1122
            subject = "Alert:Change in Transfer Price {0} {1} {2} {3} {4}".format(item.brand, item.modelName, item.modelNumber, item.color, itemId)
5944 mandeep.dh 1123
        ds_vendorItemPricing.transfer_price = vendorItemPricing.transferPrice
6751 amar.kumar 1124
    if vendorItemPricing.nlc:
1125
        if vendorItemPricing.nlc != ds_vendorItemPricing.nlc:
1126
            client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1127
            item = client.getItem(itemId)
7315 amit.gupta 1128
            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 1129
            subject = "Alert:Change in NLC {0} {1} {2} {3} {4}".format(item.brand, item.modelName, item.modelNumber, item.color, itemId)
1130
        ds_vendorItemPricing.nlc = vendorItemPricing.nlc
9895 vikram.rag 1131
    session.commit()    
1132
    client = CatalogClient("catalog_service_server_host_staging", "catalog_service_server_port").get_client()
1133
    client.updateNlcAtMarketplaces(itemId,vendorId,ds_vendorItemPricing.nlc)
19247 kshitij.so 1134
    if subject and sendMail:
5944 mandeep.dh 1135
        __send_mail(subject, message)
1136
    return
1137
 
1138
def add_vendor_item_mapping(key, vendorItemMapping):
1139
    if not vendorItemMapping:
1140
        raise InventoryServiceException(108, "Bad vendorItemMapping in request")
1141
    vendorId = vendorItemMapping.vendorId
1142
    itemId = vendorItemMapping.itemId
1143
 
1144
    try:
1145
        vendor = Vendor.query.filter_by(id=vendorId).one()
1146
    except:
1147
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
1148
 
1149
    try:
1150
        ds_vendorItemMapping = VendorItemMapping.query.filter(and_(VendorItemMapping.vendor==vendor, VendorItemMapping.item_id==itemId, VendorItemMapping.item_key==key)).one()
1151
    except:
1152
        ds_vendorItemMapping = VendorItemMapping()
1153
        ds_vendorItemMapping.vendor = vendor
1154
        ds_vendorItemMapping.item_id = itemId
1155
    ds_vendorItemMapping.item_key = vendorItemMapping.itemKey
1156
 
1157
    session.commit()
1158
 
1159
    # Marking the missed inventory as not ignored as the catalog dashboard user has updated their key
1160
    for missedInventoryUpdate in MissedInventoryUpdate.query.filter_by(itemKey = vendorItemMapping.itemKey).all():
1161
        missedInventoryUpdate.isIgnored = 0
1162
    session.commit()
1163
 
1164
    return
1165
 
1166
def validate_vendor_prices(item, vendorPrices):
1167
    if item.mrp != None and item.mrp != "" and vendorPrices.mop != "" and item.mrp <  vendorPrices.mop:
1168
        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))
1169
        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 1170
    return
18459 kshitij.so 1171
    #if vendorPrices.mop != "" and vendorPrices.transferPrice != "" and vendorPrices.transferPrice > vendorPrices.mop:
18460 kshitij.so 1172
#         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))
1173
#         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)))
1174
    #return 
5944 mandeep.dh 1175
 
1176
def get_all_vendors():
1177
    return Vendor.query.all()
1178
 
1179
def get_pending_orders_inventory(vendor_id=1):
1180
    """
1181
    Returns a list of inventory stock for items for which there are pending orders.
1182
    """
1183
 
1184
    warehouse_ids = [warehouse.id for warehouse in Warehouse.query.filter_by(vendor_id = vendor_id)]
1185
    pending_items_inventory = []
1186
    if warehouse_ids:
1187
        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()
1188
    return pending_items_inventory
1189
 
7149 amar.kumar 1190
def get_billable_inventory_and_pending_orders():
1191
    """
1192
    Returns a list of inventory Availability and Reserved Count for items which either have real inventory
1193
    or have pending orders.
1194
    """
1195
 
1196
    warehouse_ids = [warehouse.id for warehouse in Warehouse.query.filter(Warehouse.isAvailabilityMonitored == 1).filter(or_(Warehouse.inventoryType == 'GOOD', Warehouse.warehouseType == 'OURS'))]
1197
    items_inventory = []
1198
    reserved_items_inventory = []
1199
    available_items_inventory = []
1200
    if warehouse_ids:
1201
        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()
1202
        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()
1203
 
1204
    items_inventory.extend(reserved_items_inventory)
1205
    items_inventory.extend(available_items_inventory)
1206
    return items_inventory
1207
 
1208
 
5944 mandeep.dh 1209
def close_session():
1210
    if session.is_active:
1211
        print "session is active. closing it."
1212
        session.close()
1213
 
1214
def is_alive():
1215
    try:
1216
        session.query(Vendor.id).limit(1).one()
1217
        return True
1218
    except:
1219
        return False
1220
 
1221
def add_vendor(vendor):
1222
    if not vendor:
1223
        raise InventoryServiceException(108, "Bad vendor")
1224
    if get_vendor(vendor.id):
1225
        #vendor is already present.
1226
        raise InventoryServiceException(101, "Vendor already present")
1227
 
1228
    ds_vendor = Vendor()
1229
    ds_vendor.id = vendor.id
1230
    ds_vendor.name = vendor.name
1231
    session.commit()
1232
    return ds_vendor.id
1233
 
1234
def add_warehouse_vendor_mapping(warehouse_id, VendorId):
1235
    return True
1236
 
1237
def mark_missed_inventory_updates_as_processed(itemKey, warehouseId):
1238
    MissedInventoryUpdate.query.filter_by(itemKey = itemKey, warehouseId = warehouseId).delete()
1239
    session.commit()
1240
 
1241
def get_item_keys_to_be_processed(warehouseId):
1242
    return [i.itemKey for i in MissedInventoryUpdate.query.filter_by(warehouseId = warehouseId, isIgnored = 0)]
1243
 
1244
def reset_availability(itemKey, vendorId, quantity, warehouseId):
1245
    vendorItemMapping = VendorItemMapping.get_by(vendor_id = vendorId, item_key = itemKey)
1246
    if vendorItemMapping:
1247
        itemId = vendorItemMapping.item_id
1248
 
1249
        if skippedItems.has_key(warehouseId) and itemId in skippedItems[warehouseId]:
1250
            quantity = 0
1251
 
1252
        currentInventorySnapshot = CurrentInventorySnapshot.get_by(item_id = itemId, warehouse_id = warehouseId)
1253
        if currentInventorySnapshot:
1254
            currentInventorySnapshot.availability = quantity
5978 rajveer 1255
            clear_item_availability_cache(itemId) 
5944 mandeep.dh 1256
        else:
1257
            add_inventory(itemId, warehouseId, quantity)
1258
 
1259
    else:
1260
        raise InventoryServiceException(101, 'VendorMapping not found for: ' + itemKey)
1261
    session.commit()
1262
 
1263
def reset_availability_for_warehouse(warehouseId):
13149 manish.sha 1264
    itemIds = []
5944 mandeep.dh 1265
    for currentInventorySnapshot in CurrentInventorySnapshot.query.filter_by(warehouse_id=warehouseId).all():
1266
        currentInventorySnapshot.availability = 0
13149 manish.sha 1267
        itemIds.append(currentInventorySnapshot.item_id)
1268
    clear_item_availability_cache(itemIds) 
5944 mandeep.dh 1269
    session.commit()
1270
 
7718 amar.kumar 1271
def get_our_warehouse_id_for_vendor(vendor_id, billing_warehouse_id):
6467 amar.kumar 1272
    try:
7718 amar.kumar 1273
        warehouse = Warehouse.query.filter_by(vendor_id = vendor_id, warehouseType = 'OURS', inventoryType = 'GOOD', billingWarehouseId = billing_warehouse_id).first()
6467 amar.kumar 1274
        return warehouse.id
1275
    except Exception as e:
1276
        print e;
7755 amar.kumar 1277
        raise InventoryServiceException(101, 'No our warehouse found for vendorId: ' + str(vendor_id))
5944 mandeep.dh 1278
 
1279
def __send_mail(subject, message):
1280
    try:
6029 rajveer 1281
        thread = threading.Thread(target=partial(mail, mail_user, mail_password, to_addresses, subject, message))
5944 mandeep.dh 1282
        thread.start()
1283
    except Exception as ex:
1284
        print ex    
1285
 
1286
def get_shipping_locations():
1287
    shippingLocationIds = {}
1288
    warehouses = Warehouse.query.all()
1289
    for warehouse in warehouses:
1290
        if warehouse.shippingWarehouseId:
1291
            shippingLocationIds[warehouse.shippingWarehouseId] = 1
1292
 
1293
    shippingLocations = []
1294
    for shippingLocationId in shippingLocationIds:
1295
        shippingLocations.append(get_Warehouse(shippingLocationId))
1296
 
1297
    return shippingLocations
1298
 
1299
def get_inventory_snapshot(warehouseId):
1300
    query = CurrentInventorySnapshot.query
1301
 
1302
    if warehouseId:
1303
        query = query.filter_by(warehouse_id = warehouseId)
1304
 
1305
    itemInventoryMap = {}
1306
    for row in query.all():
1307
        if not itemInventoryMap.has_key(row.item_id):
1308
            itemInventoryMap[row.item_id] = []
1309
 
1310
        itemInventoryMap[row.item_id].append(row)
1311
 
1312
    return itemInventoryMap
1313
 
1314
def update_vendor_string(warehouseId, vendorString):
1315
    warehouse = get_Warehouse(warehouseId)
1316
    warehouse.vendorString = vendorString
1317
    session.commit()
1318
 
1319
def __get_item_from_master(item_id):
1320
    client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
5978 rajveer 1321
    return client.getItem(item_id)
1322
 
1323
def __check_risky_item(item_id, source_id):
1324
    ## We should get the list of strings which will identify to the catalog servers
1325
    if source_id == 1:
1326
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1327
        client.validateRiskyStatus(item_id)
1328
    if source_id == 2:
1329
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
1330
        client.validateRiskyStatus(item_id)
1331
 
1332
def __get_item_from_source(item_id, source_id):
1333
    if source_id == 1:
1334
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
1335
        return client.getItem(item_id)
1336
    if source_id == 2:
1337
        client = CatalogClient("catalog_service_server_host_hotspot", "catalog_service_server_port").get_client()
6531 vikram.rag 1338
        return client.getItem(item_id)
1339
 
1340
def get_monitored_warehouses_for_vendors(vendorIds):
1341
    w = []
1342
    for wh in Warehouse.query.filter_by(isAvailabilityMonitored = 1).all():
1343
        if wh.vendor.id in (vendorIds):
1344
            w.append(to_t_warehouse(wh).id)
1345
    return w
1346
def get_ignored_warehouseids_and_itemids():
1347
    iw = []
1348
    for i in IgnoredInventoryUpdateItems.query.all():
1349
        iw.append(to_t_itemidwarehouseid(i)) 
1350
    return iw
1351
def insert_item_to_ignore_inventory_update_list(item_id,warehouse_id):
1352
    try:
1353
        ds_warehouse=IgnoredInventoryUpdateItems()
1354
        ds_warehouse.item_id=item_id
1355
        ds_warehouse.warehouse_id=warehouse_id
6532 amit.gupta 1356
        clear_item_availability_cache(item_id)
6531 vikram.rag 1357
        session.commit()
1358
        return True
1359
    except:
1360
        return False       
1361
def delete_item_from_ignore_inventory_update_list(item_id,warehouse_id):
1362
    try:
1363
        session.query(IgnoredInventoryUpdateItems).filter_by(item_id=item_id,warehouse_id=warehouse_id).delete()
6532 amit.gupta 1364
        clear_item_availability_cache(item_id)
6531 vikram.rag 1365
        session.commit()
1366
        return True
1367
    except:
1368
        return False           
1369
 
1370
def get_all_ignored_inventoryupdate_items_count():
1371
    return  session.query(func.count(distinct(IgnoredInventoryUpdateItems.item_id))).scalar()
1372
 
1373
def get_ignored_inventoryupdate_itemids(offset=0,limit=None):
1374
    itemIds = session.query(distinct(IgnoredInventoryUpdateItems.item_id))
1375
    '''if limit is not None:
1376
        itemIds = itemIds.limit(limit)'''
1377
    print itemIds.all()
1378
    return [id for (id, ) in itemIds.all()]
6821 amar.kumar 1379
 
1380
def update_item_stock_purchase_params(item_id, numOfDaysStock, minStockLevel):
1381
    if numOfDaysStock is None or minStockLevel is None:
1382
        raise InventoryServiceException(108, "Bad params : numOfDaysStock = " + str(numOfDaysStock) + "minStockLevel = " + str(minStockLevel))
1383
    itemStockPurchaseParams = ItemStockPurchaseParams.query.filter_by(item_id = item_id).first()
1384
    if itemStockPurchaseParams is None:
1385
        itemStockPurchaseParams = ItemStockPurchaseParams()
1386
    itemStockPurchaseParams.item_id = item_id
1387
    itemStockPurchaseParams.numOfDaysStock = numOfDaysStock
1388
    itemStockPurchaseParams.minStockLevel = minStockLevel
1389
    session.commit()
1390
 
1391
def get_item_stock_purchase_params(item_id):
1392
    return ItemStockPurchaseParams.query.filter_by(item_id = item_id).first()
1393
 
1394
def add_oos_status_for_item(oosStatusMap, date):
1395
 
1396
    oosDate = to_py_date(date)
1397
    oosDate.replace(second=0, microsecond=0)
1398
 
1399
    cartAdditionStartDate = oosDate - datetime.timedelta(days = 1)
1400
 
1401
    client = TransactionClient().get_client()
1402
 
1403
    #Gets physical orders in the last day
1404
    orders = client.getPhysicalOrders(to_java_date(cartAdditionStartDate), to_java_date(oosDate))
8019 amar.kumar 1405
    rtoOrders = client.getAllOrders([20], 0, 0, 0)
9665 rajveer 1406
    orderCountByItemIdSourceId = {}
1407
    rtoOrderCountByItemIdSourceId = {}
1408
 
6821 amar.kumar 1409
    for order in orders:
9665 rajveer 1410
        if not orderCountByItemIdSourceId.has_key(order.lineitems[0].item_id):
1411
            orderCountByItemIdSourceId[order.lineitems[0].item_id] = {}
1412
 
1413
        if orderCountByItemIdSourceId[order.lineitems[0].item_id].has_key(order.source):
18430 manish.sha 1414
            orderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = orderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] + order.lineitems[0].quantity
6821 amar.kumar 1415
        else:
18430 manish.sha 1416
            orderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = order.lineitems[0].quantity
9665 rajveer 1417
 
8019 amar.kumar 1418
 
1419
    for order in rtoOrders:
9665 rajveer 1420
        if not rtoOrderCountByItemIdSourceId.has_key(order.lineitems[0].item_id):
1421
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id] = {}
1422
 
1423
        if rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id].has_key(order.source):
18430 manish.sha 1424
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] + order.lineitems[0].quantity 
8019 amar.kumar 1425
        else:
18430 manish.sha 1426
            rtoOrderCountByItemIdSourceId[order.lineitems[0].item_id][order.source] = order.lineitems[0].quantity
9665 rajveer 1427
 
1428
 
6821 amar.kumar 1429
    for itemId, status in oosStatusMap.iteritems():
9665 rajveer 1430
        total_order_count = 0 
9791 rajveer 1431
        total_rto_count = 0
13726 manish.sha 1432
        for sid in (1,3,4,6,7,8):
6821 amar.kumar 1433
            oosStatus = OOSStatus()
1434
            oosStatus.item_id = itemId
1435
            oosStatus.date = oosDate
9791 rajveer 1436
            oosStatus.sourceId  = sid
1437
            order_count = 0
1438
            rto_count = 0
1439
            if orderCountByItemIdSourceId.has_key(itemId) and orderCountByItemIdSourceId[itemId].has_key(sid):
1440
                order_count = orderCountByItemIdSourceId[itemId][sid]
1441
            if rtoOrderCountByItemIdSourceId.has_key(itemId) and rtoOrderCountByItemIdSourceId[itemId].has_key(sid):
18430 manish.sha 1442
                rto_count = rtoOrderCountByItemIdSourceId[itemId][sid]
9791 rajveer 1443
            oosStatus.num_orders = order_count
1444
            oosStatus.rto_orders = rto_count
9666 rajveer 1445
            oosStatus.is_oos = status
9791 rajveer 1446
            if oosStatus.is_oos and order_count > 0:
1447
                oosStatus.is_oos = False
1448
            total_order_count = total_order_count + order_count
1449
            total_rto_count = total_rto_count + rto_count
1450
        oosStatus = OOSStatus()
1451
        oosStatus.item_id = itemId
1452
        oosStatus.date = oosDate
1453
        oosStatus.sourceId  = 0
1454
        oosStatus.num_orders = total_order_count
1455
        oosStatus.rto_orders = total_rto_count
9804 rajveer 1456
        if itemId in orderCountByItemIdSourceId and 1 in orderCountByItemIdSourceId[itemId]:
1457
            order_count = orderCountByItemIdSourceId[itemId][1]
9791 rajveer 1458
        oosStatus.is_oos = status
1459
        if oosStatus.is_oos and order_count > 0:
1460
            oosStatus.is_oos = False
6821 amar.kumar 1461
 
9791 rajveer 1462
        session.commit()
1463
 
9861 rajveer 1464
 
1465
    itemCountMap = {}
1466
    oosDate = oosDate - datetime.timedelta(days = 1) - datetime.timedelta(hours = 1)
1467
    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()
1468
    for line in lines:
1469
        item_id = line[0]
9896 rajveer 1470
        quantity = int(math.ceil(max(1,2*line[1])))
9861 rajveer 1471
        itemCountMap[item_id] = quantity
9862 rajveer 1472
    cl = CatalogClient('catalog_service_server_host_prod','catalog_service_server_port').get_client()
9861 rajveer 1473
    cl.updateItemHoldInventory(itemCountMap)
9791 rajveer 1474
 
9665 rajveer 1475
def get_oos_statuses_for_x_days_for_item(itemId, sourceId, days):
6832 amar.kumar 1476
    timestamp = datetime.datetime.now()
9640 amar.kumar 1477
    timestamp = timestamp - datetime.timedelta(days = days)
9665 rajveer 1478
    return OOSStatus.query.filter_by(item_id = itemId).filter_by(sourceId = sourceId).filter(OOSStatus.date > timestamp).all()
6857 amar.kumar 1479
 
10126 amar.kumar 1480
def get_oos_statuses_for_x_days(sourceId, days):
1481
    timestamp = datetime.datetime.now()
1482
    timestamp = timestamp - datetime.timedelta(days = days)
1483
    if sourceId == -1:
1484
        return OOSStatus.query.filter(OOSStatus.date > timestamp).all()
1485
    else:
1486
        return OOSStatus.query.filter_by(sourceId = sourceId).filter(OOSStatus.date > timestamp).all()
1487
 
6857 amar.kumar 1488
def get_non_zero_item_stock_purchase_params():
7281 kshitij.so 1489
    return ItemStockPurchaseParams.query.filter(or_("numOfDaysStock!=0","minStockLevel!=0"))
1490
 
7972 amar.kumar 1491
def get_last_n_day_sale_for_item(itemId, numberOfDays):
1492
    lastNdaySale = ""
9685 rajveer 1493
    oosStatuses = get_oos_statuses_for_x_days_for_item(itemId, 0, numberOfDays)
7972 amar.kumar 1494
    for oosStatus in oosStatuses:
1495
        if oosStatus.is_oos == True:
1496
            lastNdaySale +="X-"
1497
        else:
1498
            lastNdaySale +=str(oosStatus.num_orders) + "-"
1499
    return lastNdaySale[:-1] 
1500
 
7281 kshitij.so 1501
def get_warehouse_name(warehouseId):
1502
    row = Warehouse.get_by(id = warehouseId)
1503
    return row.displayName
1504
 
1505
def get_amazon_inventory_for_item(amazonItemId):
1506
    inventory = AmazonInventorySnapshot.get_by(item_id=amazonItemId)
1507
    return inventory
1508
 
1509
def get_all_amazon_inventory():
1510
    return session.query(AmazonInventorySnapshot).all()
1511
 
10450 vikram.rag 1512
def add_or_update_amazon_inventory_for_item(amazoninventorysnapshot,time):
7281 kshitij.so 1513
    inventory = AmazonInventorySnapshot.get_by(item_id = amazoninventorysnapshot.item_id)
1514
    if inventory is None:
1515
        amazon_inventory = AmazonInventorySnapshot()
1516
        amazon_inventory.item_id = amazoninventorysnapshot.item_id
1517
        amazon_inventory.availability = amazoninventorysnapshot.availability
1518
        amazon_inventory.reserved = amazoninventorysnapshot.reserved
10450 vikram.rag 1519
        amazon_inventory.is_oos = amazoninventorysnapshot.is_oos
1520
        if time != 0:
1521
            amazon_inventory.lastUpdatedOnAmazon = to_py_date(time)
1522
    else: 
7281 kshitij.so 1523
        inventory.availability = amazoninventorysnapshot.availability
1524
        inventory.reserved = amazoninventorysnapshot.reserved
10450 vikram.rag 1525
        if not inventory.is_oos and (to_py_date(time) - inventory.lastUpdatedOnAmazon).days == 0:
1526
            pass
1527
        else:
1528
            inventory.is_oos = amazoninventorysnapshot.is_oos
1529
        if time != 0:    
1530
            inventory.lastUpdatedOnAmazon = to_py_date(time)      
7281 kshitij.so 1531
    session.commit()
1532
 
8182 amar.kumar 1533
def add_update_hold_inventory(itemId, warehouseId, holdQuantity, source):
9762 amar.kumar 1534
    if holdQuantity <0:
1535
        print "Negative holdQuantity : " + str(holdQuantity) + " is not allowed"
1536
        raise InventoryServiceException(108, "Negative heldQuantity is not allowed")
8197 amar.kumar 1537
    hold_inventory_detail = HoldInventoryDetail.get_by(item_id = itemId, warehouse_id=warehouseId, source = source)
1538
    if  hold_inventory_detail is None:
8182 amar.kumar 1539
        diffTobeAddedInCIS = holdQuantity
1540
        hold_inventory_detail = HoldInventoryDetail()
1541
        hold_inventory_detail.item_id = itemId 
1542
        hold_inventory_detail.warehouse_id = warehouseId 
1543
        hold_inventory_detail.held = holdQuantity 
1544
        hold_inventory_detail.source = source
1545
    else:
8497 amar.kumar 1546
        diffTobeAddedInCIS = holdQuantity - hold_inventory_detail.held
8182 amar.kumar 1547
        hold_inventory_detail.held = holdQuantity
1548
 
1549
    current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
1550
    if not current_inventory_snapshot:
1551
        current_inventory_snapshot = CurrentInventorySnapshot()
1552
        current_inventory_snapshot.item_id = itemId
1553
        current_inventory_snapshot.warehouse_id = warehouseId
1554
        current_inventory_snapshot.availability = 0
1555
        current_inventory_snapshot.reserved = 0
1556
        current_inventory_snapshot.held = 0
1557
    current_inventory_snapshot.held = current_inventory_snapshot.held + diffTobeAddedInCIS
1558
    session.commit()
1559
    #**Update item availability cache**#
1560
    clear_item_availability_cache(itemId)
8282 kshitij.so 1561
 
1562
def add_or_update_amazon_fba_inventory(amazonfbainventorysnapshot):
11173 vikram.rag 1563
    inventory = AmazonFbaInventorySnapshot.query.filter_by(item_id = amazonfbainventorysnapshot.item_id,location=amazonfbainventorysnapshot.location).first()
8282 kshitij.so 1564
    if inventory is None:
1565
        amazon_fba_inventory = AmazonFbaInventorySnapshot()
1566
        amazon_fba_inventory.item_id = amazonfbainventorysnapshot.item_id
1567
        amazon_fba_inventory.availability = amazonfbainventorysnapshot.availability
11173 vikram.rag 1568
        amazon_fba_inventory.location = amazonfbainventorysnapshot.location
1569
        amazon_fba_inventory.reserved = amazonfbainventorysnapshot.reserved
1570
        amazon_fba_inventory.inbound = amazonfbainventorysnapshot.inbound
1571
        amazon_fba_inventory.unfulfillable = amazonfbainventorysnapshot.unfulfillable
1572
 
8282 kshitij.so 1573
    else:
11173 vikram.rag 1574
        print 'updating'
8282 kshitij.so 1575
        inventory.availability = amazonfbainventorysnapshot.availability
11173 vikram.rag 1576
        inventory.location = amazonfbainventorysnapshot.location
1577
        inventory.reserved = amazonfbainventorysnapshot.reserved
1578
        inventory.inbound = amazonfbainventorysnapshot.inbound
1579
        inventory.unfulfillable = amazonfbainventorysnapshot.unfulfillable
8282 kshitij.so 1580
 
1581
 
1582
def get_amazon_fba_inventory(itemId):
11173 vikram.rag 1583
    return AmazonFbaInventorySnapshot.query.filter_by(item_id = itemId)
8282 kshitij.so 1584
 
8363 vikram.rag 1585
def get_all_amazon_fba_inventory():
1586
    return AmazonFbaInventorySnapshot.query.all() 
1587
 
12799 manish.sha 1588
def get_oursgood_warehouseids_for_location(stateId):
8363 vikram.rag 1589
    warehouseId=[]
12799 manish.sha 1590
    x= session.query(Warehouse.id).filter(Warehouse.id==Warehouse.billingWarehouseId).filter(Warehouse.warehouseType=='OURS').filter(Warehouse.state_id==stateId).all()
8363 vikram.rag 1591
    for id in x:
1592
        warehouseId.append(id[0])
1593
    return session.query(Warehouse.id).filter(Warehouse.inventoryType=='GOOD').filter(Warehouse.warehouseType=='OURS').filter(Warehouse.billingWarehouseId.in_(warehouseId)).all()
8954 vikram.rag 1594
 
1595
def get_holdinventorydetail_forItem_forWarehouseId_exceptsource(item_id,warehouse_id,source):
1596
    holddetails = HoldInventoryDetail.query.filter(HoldInventoryDetail.item_id == item_id).all()
1597
    print holddetails
1598
    hold = 0
1599
    for holddetail in holddetails:
1600
        if holddetail.source !=source and holddetail.warehouse_id == warehouse_id:
1601
            hold = hold + holddetail.held
9404 vikram.rag 1602
    return hold
1603
 
1604
def get_snapdeal_inventory_for_item(id):
1605
    print SnapdealInventorySnapshot.get_by(item_id = id)
1606
    return SnapdealInventorySnapshot.get_by(item_id = id)
1607
 
1608
def add_or_update_snapdeal_inventor_for_item(snapdealinventoryitem):
1609
    snapdeal_inventory_item = SnapdealInventorySnapshot.get_by(item_id = snapdealinventoryitem.item_id)
1610
    if snapdeal_inventory_item is None:
1611
        snapdeal_inventory_item = SnapdealInventorySnapshot()
1612
        snapdeal_inventory_item.item_id = snapdealinventoryitem.item_id
1613
        snapdeal_inventory_item.availability = snapdealinventoryitem.availability
9495 vikram.rag 1614
        snapdeal_inventory_item.pendingOrders = snapdealinventoryitem.pendingOrders
9404 vikram.rag 1615
        snapdeal_inventory_item.lastUpdatedOnSnapdeal = to_py_date(snapdealinventoryitem.lastUpdatedOnSnapdeal)
10450 vikram.rag 1616
        snapdeal_inventory_item.is_oos = snapdealinventoryitem.is_oos
9404 vikram.rag 1617
    else:
1618
        snapdeal_inventory_item.availability = snapdealinventoryitem.availability
9495 vikram.rag 1619
        snapdeal_inventory_item.pendingOrders = snapdealinventoryitem.pendingOrders
10450 vikram.rag 1620
        if not snapdeal_inventory_item.is_oos and (to_py_date(snapdealinventoryitem.lastUpdatedOnSnapdeal) - snapdeal_inventory_item.lastUpdatedOnSnapdeal).days == 0:
1621
            pass
1622
        else:
1623
            snapdeal_inventory_item.is_oos = snapdealinventoryitem.is_oos
9404 vikram.rag 1624
        snapdeal_inventory_item.lastUpdatedOnSnapdeal = to_py_date(snapdealinventoryitem.lastUpdatedOnSnapdeal)
1625
    session.commit()
8954 vikram.rag 1626
 
9404 vikram.rag 1627
def get_nlc_for_warehouse(warehouse_id,itemid):
1628
    warehouse = Warehouse.get_by(id=warehouse_id)
1629
    if warehouse is None:
1630
        return 0
1631
    vendoritempricing = VendorItemPricing.query.filter_by(item_id=itemid, vendor_id=warehouse.vendor_id).first()
1632
    '''vendoritempricing = VendorItemPricing.get_by(id=warehouse.vendor_id,item_id=itemid)'''
1633
    if vendoritempricing is None:
1634
        return 0
9456 vikram.rag 1635
    return vendoritempricing.nlc
1636
 
9495 vikram.rag 1637
def get_snapdeal_inventory_snapshot():
9640 amar.kumar 1638
    return SnapdealInventorySnapshot.query.all()
10050 vikram.rag 1639
 
9640 amar.kumar 1640
def get_held_inventory_map_for_item(itemId, warehouseId):
1641
    heldInventoryMap = {}
1642
    holdInventories = HoldInventoryDetail.query.filter_by(item_id= itemId, warehouse_id = warehouseId).all()
1643
    for holdInventory in holdInventories:
1644
        heldInventoryMap[holdInventory.source] = holdInventory.held
1645
    return heldInventoryMap 
10050 vikram.rag 1646
 
9761 amar.kumar 1647
def get_hold_inventory_details(itemId, warehouseId, source):
1648
    heldInventoryQuery = HoldInventoryDetail.query
1649
    if itemId:
1650
        heldInventoryQuery = heldInventoryQuery.filter_by(item_id = itemId)
1651
    if warehouseId:
1652
        heldInventoryQuery = heldInventoryQuery.filter_by(warehouse_id = warehouseId)
1653
    if source:
1654
        heldInventoryQuery = heldInventoryQuery.filter_by(source = source)
1655
    holdInventoryDetails = heldInventoryQuery.all()
1656
    return holdInventoryDetails
9896 rajveer 1657
 
10450 vikram.rag 1658
def add_or_update_flipkart_inventory_snapshot(flipkartInventorySnapshot,time):
10050 vikram.rag 1659
    for snapshot in flipkartInventorySnapshot:
1660
        flipkart_inventory = FlipkartInventorySnapshot.get_by(item_id = snapshot.item_id)
1661
        if flipkart_inventory is None:
1662
            flipkart_inventory = FlipkartInventorySnapshot()
1663
            flipkart_inventory.item_id = snapshot.item_id
1664
            flipkart_inventory.availability = snapshot.availability
1665
            flipkart_inventory.createdOrders = snapshot.createdOrders
1666
            flipkart_inventory.heldOrders = snapshot.heldOrders
10450 vikram.rag 1667
            flipkart_inventory.is_oos = snapshot.is_oos
1668
            flipkart_inventory.lastUpdatedOnFlipkart = to_py_date(time) 
10050 vikram.rag 1669
        else:
1670
            flipkart_inventory.availability = snapshot.availability
1671
            flipkart_inventory.createdOrders = snapshot.createdOrders
1672
            flipkart_inventory.heldOrders = snapshot.heldOrders
10450 vikram.rag 1673
            if not flipkart_inventory.is_oos and (to_py_date(time) - flipkart_inventory.lastUpdatedOnFlipkart).days == 0:
1674
                pass
1675
            else:
1676
                flipkart_inventory.is_oos = snapshot.is_oos
1677
            flipkart_inventory.lastUpdatedOnFlipkart = to_py_date(time) 
10050 vikram.rag 1678
    session.commit()
1679
 
1680
def get_flipkart_inventory_snapshot():
1681
    return FlipkartInventorySnapshot.query.all()     
1682
 
10097 kshitij.so 1683
def get_flipkart_inventory_for_Item(itemId):
10485 vikram.rag 1684
    return FlipkartInventorySnapshot.get_by(item_id = itemId)
1685
 
1686
def get_state_master():
1687
    stateIdNameMap = {} 
1688
    statemaster = StateMaster.query.all()
1689
    for state in statemaster:
12280 amit.gupta 1690
        stateIdNameMap[state.id] = to_t_state(state)
10544 vikram.rag 1691
    return stateIdNameMap    
1692
 
1693
def update_snapdeal_stock_at_eod(allsnapdealstock):
1694
    for stockitem in allsnapdealstock:
1695
        snapdealstockateod = SnapdealStockAtEOD()
1696
        snapdealstockateod.item_id = stockitem.item_id
1697
        snapdealstockateod.availability = stockitem.availability
1698
        snapdealstockateod.date =  to_py_date(stockitem.date)
1699
    session.commit()
1700
 
1701
def update_flipkart_stock_at_eod(allflipkartstock):
1702
    for stockitem in allflipkartstock:
1703
        snapdealstockateod = FlipkartStockAtEOD()
1704
        snapdealstockateod.item_id = stockitem.item_id
1705
        snapdealstockateod.availability = stockitem.availability
1706
        snapdealstockateod.date =  to_py_date(stockitem.date)
1707
    session.commit()
10687 rajveer 1708
 
12363 kshitij.so 1709
def get_wanlc_for_source(item_id,sourceId):
1710
    stockWanlc = StockWeightedNlcInfo.query.filter(StockWeightedNlcInfo.itemId==item_id).filter(StockWeightedNlcInfo.source==sourceId).order_by(desc(StockWeightedNlcInfo.updatedTimestamp)).limit(1).all()
1711
    if stockWanlc is None or len(stockWanlc)==0:
1712
        return 0.0
1713
    else:
1714
        return stockWanlc[0].avgWeightedNlc
1715
 
1716
def get_all_available_amazon_inventory():
19247 kshitij.so 1717
    return AmazonFbaInventorySnapshot.query.filter(AmazonFbaInventorySnapshot.availability>0).all()
1718
 
1719
def add_vendor_item_pricing_in_bulk(vendorItemPricingList):
1720
    exceptionItems = []
1721
    for vendorItemPricing in vendorItemPricingList:
1722
        try:
1723
            add_vendor_pricing(vendorItemPricing, False)
1724
        except:
1725
            exceptionItems.append(vendorItemPricing.itemId)
1726
    return exceptionItems
1727
 
1728
def add_inventory_in_bulk(bulkInventoryList):
1729
    for item in bulkInventoryList:
19989 kshitij.so 1730
        add_inventory(item.item_id, item.warehouse_id, item.inventory, True)
19247 kshitij.so 1731
 
1732
 
12363 kshitij.so 1733