Subversion Repositories SmartDukaan

Rev

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