Subversion Repositories SmartDukaan

Rev

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