Subversion Repositories SmartDukaan

Rev

Rev 19413 | Rev 19989 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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