Subversion Repositories SmartDukaan

Rev

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