Subversion Repositories SmartDukaan

Rev

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

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