Subversion Repositories SmartDukaan

Rev

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