Subversion Repositories SmartDukaan

Rev

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