Subversion Repositories SmartDukaan

Rev

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