Subversion Repositories SmartDukaan

Rev

Rev 22721 | Rev 22991 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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