Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
94 ashish 1
'''
2
Created on 23-Mar-2010
3
 
4
@author: ashish
5
'''
6
from elixir import *
4748 mandeep.dh 7
from pydoc import Helper
8
from shop2020.clients.HelperClient import HelperClient
9
from shop2020.clients.TransactionClient import TransactionClient
10
from shop2020.config.client.ConfigClient import ConfigClient
94 ashish 11
from shop2020.model.v1.catalog.impl import DataService
4748 mandeep.dh 12
from shop2020.model.v1.catalog.impl.CategoryManager import CategoryManager
13
from shop2020.model.v1.catalog.impl.Convertors import to_t_item, \
3557 rajveer 14
    to_t_vendor_item_pricing, to_t_source
4748 mandeep.dh 15
from shop2020.model.v1.catalog.impl.DataService import Item, Warehouse, \
16
    ItemInventoryHistory, CurrentInventorySnapshot, ItemInfo, ItemChangeLog, \
17
    Category, EntityIDGenerator, VendorItemPricing, VendorItemMapping, Vendor, \
18
    SimilarItems, ProductNotification, Source, SourceItemPricing, AuthorizationLog, \
19
    MissingItemKey
20
from shop2020.thriftpy.model.v1.catalog.ttypes import InventoryServiceException, \
21
    status, ItemShippingInfo
22
from shop2020.thriftpy.model.v1.order.ttypes import AlertType
23
from shop2020.utils.EmailAttachmentSender import mail
2286 ankur.sing 24
from shop2020.utils.Utils import log_entry, to_py_date, log_risky_flag
621 chandransh 25
from sqlalchemy import desc, asc
3244 chandransh 26
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
3872 chandransh 27
from sqlalchemy.sql.expression import and_, or_, distinct, func
3086 rajveer 28
from string import Template
4748 mandeep.dh 29
from urllib2 import HTTPBasicAuthHandler
30
import datetime
31
import sys
3924 rajveer 32
import urllib2
94 ashish 33
 
34
def initialize():
35
    DataService.initialize()
36
 
3849 chandransh 37
def get_all_items_by_status(status, offset=0, limit=None):
38
    query = Item.query
4539 rajveer 39
    if status is not None:
3849 chandransh 40
        query = query.filter_by(status=status)
41
    query = query.order_by(Item.product_group, Item.brand, Item.model_number, Item.model_name).offset(offset)
42
    if limit:
43
        query = query.limit(limit)
44
    items = query.all()
45
    return items
46
 
47
def get_all_items(is_active, offset=0, limit=None):
103 ashish 48
    if is_active:
3849 chandransh 49
        items = get_all_items_by_status(status.ACTIVE, offset, limit)
103 ashish 50
    else:
3849 chandransh 51
        items = get_all_items_by_status(None, offset, limit)
766 rajveer 52
    return items
53
 
3849 chandransh 54
def get_item_count_by_status(use_status, status):
55
    if use_status:
56
        return Item.query.filter_by(status=status).count()
103 ashish 57
    else:
3849 chandransh 58
        return Item.query.count()
103 ashish 59
 
635 rajveer 60
def get_item(item_id):
766 rajveer 61
    item = Item.get_by(id=item_id)
62
    return item
94 ashish 63
 
635 rajveer 64
def get_items_by_catalog_id(catalog_id):
447 rajveer 65
    query = Item.query.filter_by(catalog_item_id=catalog_id)
437 rajveer 66
    try:
635 rajveer 67
        items = query.all()
68
        return get_thrift_item_list(items)
1399 rajveer 69
    except Exception as ex:
70
        print ex
437 rajveer 71
        raise InventoryServiceException(109, "Item not found")
72
 
576 chandransh 73
def is_active(item_id):
2983 chandransh 74
    t_item_shipping_info = ItemShippingInfo()
576 chandransh 75
    try:
635 rajveer 76
        item = get_item(item_id)
3281 chandransh 77
        t_item_shipping_info.isRisky = item.risky
4708 anupam.sin 78
        warehouse_ids = None
79
        if item.isWarehousePreferenceSticky :
80
            warehouse_ids = [item.preferredWarehouse]
81
        availability = __get_item_availability(item, warehouse_ids)
3281 chandransh 82
        if item.risky and availability <= 0 and item.status == status.ACTIVE:
83
            add_status_change_log(item, status.PAUSED_BY_RISK)
84
            item.status = status.PAUSED_BY_RISK
85
            item.status_description = "This item is currently out of stock"
86
            session.commit()
3924 rajveer 87
            #This will clear cache from tomcat
88
            __clear_homepage_cache()
2983 chandransh 89
        t_item_shipping_info.isActive = (item.status == status.ACTIVE)
3281 chandransh 90
        t_item_shipping_info.quantity = availability
576 chandransh 91
    except InventoryServiceException:
2983 chandransh 92
        print "[ERROR] Unexpected error:", sys.exc_info()[0]
93
    return t_item_shipping_info
94
 
2035 rajveer 95
def get_item_status_description(itemId):
96
    item = get_item(itemId)
97
    return item.status_description
563 chandransh 98
 
94 ashish 99
def get_Warehouse(warehouse_id):
100
    return Warehouse.get_by(id=warehouse_id)
101
 
4332 anupam.sin 102
def get_Vendor(vendorId):
103
    return Vendor.get_by(id=vendorId)
104
 
122 ashish 105
def get_all_warehouses_by_status(status):
106
    if not status:
766 rajveer 107
        warehouses = Warehouse.query.all()
122 ashish 108
    else:
851 chandransh 109
        warehouses = Warehouse.query.filter_by(status=status).all()
110
    return warehouses
122 ashish 111
 
94 ashish 112
def get_all_warehouses_for_item(item_id):
635 rajveer 113
    item = get_item(item_id)
94 ashish 114
    if not item:
122 ashish 115
        raise InventoryServiceException(108, "Some unforeseen error while obtaining item")
116
    return item.get_all_warehouses
94 ashish 117
 
122 ashish 118
def get_all_items_for_warehouse(warehouse_id):
119
    warehouse = get_Warehouse(warehouse_id)
120
    if not warehouse:
121
        raise InventoryServiceException(108, "bad warehouse")
122
    return warehouse.all_items
123
 
94 ashish 124
def add_warehouse(warehouse):
103 ashish 125
    if not warehouse:
122 ashish 126
        raise InventoryServiceException(108, "Bad warehouse")
103 ashish 127
    if get_Warehouse(warehouse.id):
128
        #warehouse is already present.
122 ashish 129
        raise InventoryServiceException(101, "Warehouse already present")
103 ashish 130
 
94 ashish 131
    ds_warehouse = Warehouse()
132
    ds_warehouse.id = warehouse.id
133
    ds_warehouse.location = warehouse.location
122 ashish 134
    ds_warehouse.status = status.ACTIVE
103 ashish 135
    ds_warehouse.addedOn = datetime.datetime.now()
483 rajveer 136
    ds_warehouse.lastCheckedOn = datetime.datetime.now()
137
    ds_warehouse.tinNumber = warehouse.tinNumber
138
    ds_warehouse.pincode = warehouse.pincode
139
    if warehouse.vendorString:
140
        ds_warehouse.vendorString = warehouse.vendorString
94 ashish 141
    session.commit()
103 ashish 142
    return ds_warehouse.id
94 ashish 143
 
122 ashish 144
def update_item(item):
145
    if not item:
146
        raise InventoryServiceException(108, "Bad item in request")
147
 
148
    if not item.id:
609 chandransh 149
        raise InventoryServiceException(101, "Missing id for update")
122 ashish 150
 
2120 ankur.sing 151
    validate_item_prices(item)
2065 ankur.sing 152
 
635 rajveer 153
    ds_item = get_item(item.id)
122 ashish 154
 
155
    if not ds_item:
609 chandransh 156
        raise InventoryServiceException(101, "Item missing in our database")
122 ashish 157
 
963 chandransh 158
    if item.productGroup:
159
        ds_item.product_group = item.productGroup 
160
    if item.brand:
161
        ds_item.brand = item.brand
511 rajveer 162
    if item.modelNumber:
163
        ds_item.model_number = item.modelNumber
2497 ankur.sing 164
    ds_item.color = item.color
165
    ds_item.model_name = item.modelName
166
    ds_item.category = item.category
167
    ds_item.comments = item.comments
511 rajveer 168
 
2497 ankur.sing 169
    ds_item.catalog_item_id = item.catalogItemId
483 rajveer 170
 
2129 ankur.sing 171
    ds_item.mrp = item.mrp
172
    ds_item.sellingPrice = item.sellingPrice
2497 ankur.sing 173
 
2174 ankur.sing 174
    ds_item.weight = item.weight
2129 ankur.sing 175
 
2358 ankur.sing 176
    if ds_item.status != item.itemStatus:
2402 rajveer 177
        add_status_change_log(ds_item, item.itemStatus)
2358 ankur.sing 178
        ds_item.status = item.itemStatus
2035 rajveer 179
    if item.status_description:
180
        ds_item.status_description = item.status_description
122 ashish 181
 
511 rajveer 182
    if item.startDate:
2116 ankur.sing 183
        ds_item.startDate = to_py_date(item.startDate)
2497 ankur.sing 184
    else:
185
        ds_item.startDate = None
511 rajveer 186
    if item.retireDate:
2116 ankur.sing 187
        ds_item.retireDate = to_py_date(item.retireDate)
2497 ankur.sing 188
    else:
189
        ds_item.retireDate = None
511 rajveer 190
 
2497 ankur.sing 191
    ds_item.feature_id = item.featureId
192
    ds_item.feature_description = item.featureDescription
122 ashish 193
 
2129 ankur.sing 194
    ds_item.bestDealText = item.bestDealText
195
    ds_item.bestDealValue = item.bestDealValue
2065 ankur.sing 196
    ds_item.bestSellingRank = item.bestSellingRank
2497 ankur.sing 197
 
2065 ankur.sing 198
    ds_item.defaultForEntity = item.defaultForEntity
2251 ankur.sing 199
    ds_item.risky = item.risky
3359 chandransh 200
 
3459 chandransh 201
    if item.expectedDelay is not None:
3359 chandransh 202
        ds_item.expectedDelay = item.expectedDelay
203
 
204
    if item.preferredWarehouse:
205
        ds_item.preferredWarehouse = item.preferredWarehouse
4413 anupam.sin 206
 
207
    if item.defaultWarehouse:
208
        ds_item.defaultWarehouse = item.defaultWarehouse
4506 phani.kuma 209
 
210
    if item.preferredVendor:
211
        ds_item.preferredVendor = item.preferredVendor
4413 anupam.sin 212
 
213
    ds_item.isWarehousePreferenceSticky = item.isWarehousePreferenceSticky
3359 chandransh 214
 
2347 ankur.sing 215
    ds_item.updatedOn = datetime.datetime.now()
2065 ankur.sing 216
 
122 ashish 217
    session.commit();
218
    return ds_item.id
94 ashish 219
 
2116 ankur.sing 220
def check_vendor_item_mapping(product_group, brand, model_number, color, vendor_id, vendor_category):
221
    key = product_group.strip().lower() + '|' + brand.strip().lower() + '|' + model_number.strip().lower() + '|' + color.strip().lower()
222
    try:
223
        vim = VendorItemMapping.query.filter_by(vendor_id=vendor_id, item_key=key, vendor_category=vendor_category).one()
224
        return True
225
    except:
226
        return False
227
 
103 ashish 228
def add_item(item):
229
    if not item:
122 ashish 230
        raise InventoryServiceException(108, "Bad item in request")
635 rajveer 231
    if get_item(item.id):
122 ashish 232
        raise InventoryServiceException(101, "Item already exists")
2120 ankur.sing 233
 
234
    validate_item_prices(item)
235
 
103 ashish 236
    ds_item = Item()
963 chandransh 237
    if item.productGroup:
238
        ds_item.product_group = item.productGroup
239
    if item.brand:
240
        ds_item.brand = item.brand
515 rajveer 241
    if item.modelName:
242
        ds_item.model_name = item.modelName
243
    if item.modelNumber:
244
        ds_item.model_number = item.modelNumber
609 chandransh 245
    if item.color:
246
        ds_item.color = item.color
2116 ankur.sing 247
    if item.hotspotCategory:
248
        ds_item.hotspotCategory = item.hotspotCategory
249
        if item.hotspotCategory == 'Handsets':
2403 ankur.sing 250
            ds_item.preferredWarehouse = 1
2116 ankur.sing 251
        else:
2403 ankur.sing 252
            ds_item.preferredWarehouse = 2
2116 ankur.sing 253
 
483 rajveer 254
    if item.category:
255
        ds_item.category = item.category
256
    if item.comments:
257
        ds_item.comments = item.comments
258
 
103 ashish 259
    ds_item.addedOn = datetime.datetime.now()
609 chandransh 260
    ds_item.updatedOn = datetime.datetime.now()
2116 ankur.sing 261
    if item.startDate:
262
        ds_item.startDate = to_py_date(item.startDate)
263
    if item.retireDate:
264
        ds_item.retireDate = to_py_date(item.retireDate)
609 chandransh 265
 
483 rajveer 266
    if item.mrp:
267
        ds_item.mrp = item.mrp
268
    if item.sellingPrice:
269
        ds_item.sellingPrice = item.sellingPrice
122 ashish 270
    if item.weight:
271
        ds_item.weight = item.weight
272
 
273
    if item.featureId:
274
        ds_item.feature_id = item.featureId
275
    if item.featureDescription:
276
        ds_item.feature_description = item.featureDescription
277
 
103 ashish 278
    if item.otherInfo:
279
        for k,v in item.otherInfo.iteritems():
280
            info = ItemInfo()
281
            info.key = k
282
            info.value = v
283
            ds_item.iteminfo.append(info)
2116 ankur.sing 284
 
103 ashish 285
    #check if categories present. If yes, add them to system
122 ashish 286
 
609 chandransh 287
    if item.bestDealValue:
288
        ds_item.bestDealValue = item.bestDealValue
289
    if item.bestDealText:
290
        ds_item.bestDealText = item.bestDealText
2116 ankur.sing 291
    if item.bestSellingRank:
292
        ds_item.bestSellingRank = item.bestSellingRank
293
    ds_item.defaultForEntity = item.defaultForEntity
2251 ankur.sing 294
    ds_item.risky = item.risky
609 chandransh 295
 
3467 chandransh 296
    if item.expectedDelay is not None:
3359 chandransh 297
        ds_item.expectedDelay = item.expectedDelay
3467 chandransh 298
    else:
299
        ds_item.expectedDelay = 0
3359 chandransh 300
 
301
    if item.preferredWarehouse:
302
        ds_item.preferredWarehouse = item.preferredWarehouse
303
 
2116 ankur.sing 304
    # Check if a similar item already exists in our database
4725 phani.kuma 305
    similar_item = Item.query.filter_by(brand=item.brand, model_number=item.modelNumber, model_name=item.modelName).first()
306
    print "[SIMILAR ITEM FOUND:] FOR {0} {1} {2}".format(item.brand, item.modelNumber, item.modelName)
2116 ankur.sing 307
 
308
    if similar_item is None or similar_item.catalog_item_id is None:
309
        # If there is no similar item in the database from before,
310
        # use the entity_id_generator
311
        entity_id = EntityIDGenerator.query.first()
312
        ds_item.catalog_item_id = entity_id.id + 1
313
        ds_item.status = status.IN_PROCESS
314
        ds_item.status_description = "This item is in process."
315
        entity_id.id = entity_id.id  + 1
4725 phani.kuma 316
        if similar_item is not None and similar_item.catalog_item_id is None:
317
            similar_item.catalog_item_id = entity_id.id
2116 ankur.sing 318
    else:
319
        #If a similar item already exists for a product group, brand and model_number, set it as same.
320
        ds_item.catalog_item_id = similar_item.catalog_item_id
321
        ds_item.category = similar_item.category
322
        ds_item.status = similar_item.status
323
        ds_item.status_description = similar_item.status_description
324
 
103 ashish 325
    session.commit();
3325 chandransh 326
    return ds_item.id
327
 
328
def update_inventory_history(warehouse_id, timestamp, availability):
329
    warehouse = get_Warehouse(warehouse_id)
330
    if not warehouse:
331
        raise InventoryServiceException(107, "Warehouse? Where?")
4368 rajveer 332
    vendors = get_vendors_for_warehouse(warehouse_id)
333
    if len(vendors) > 1:
334
        raise InventoryServiceException(110, "Multiple vendors found for warehouse !")
335
    vendor = vendors[0]
3325 chandransh 336
    time = datetime.datetime.now()
337
    for item_key, quantity in availability.iteritems():
338
        try:
339
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
340
            item = vendor_item_mapping.item
341
        except:
342
            continue  
343
        try:
344
            item_inventory_history = ItemInventoryHistory()
345
            item_inventory_history.warehouse = warehouse
346
            item_inventory_history.item = item
347
            item_inventory_history.timestamp = time
348
            item_inventory_history.availibility = quantity
349
        except:
350
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
351
    session.commit()
103 ashish 352
 
483 rajveer 353
def update_inventory(warehouse_id, timestamp, availability):
354
    warehouse = get_Warehouse(warehouse_id)
355
    if not warehouse:
356
        raise InventoryServiceException(107, "Warehouse? Where?")
357
 
358
    time = datetime.datetime.now()
359
    warehouse.lastCheckedOn = time
360
    warehouse.vendorString = timestamp
4368 rajveer 361
    vendors = get_vendors_for_warehouse(warehouse_id)
362
    if len(vendors) > 1:
363
        raise InventoryServiceException(110, "Multiple vendors found for warehouse !")
364
    vendor = vendors[0]
2368 ankur.sing 365
    session.commit()
1368 chandransh 366
    for item_key, quantity in availability.iteritems():
483 rajveer 367
        try:
1368 chandransh 368
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
369
            item = vendor_item_mapping.item
494 rajveer 370
        except:
4748 mandeep.dh 371
            print 'Could not find item with key: ' + item_key
372
            __send_mail_for_missing_key(item_key, warehouse_id)
373
            continue
494 rajveer 374
        try:
483 rajveer 375
            current_inventory_snapshot = CurrentInventorySnapshot.get_by(item=item, warehouse=warehouse)
376
            if not current_inventory_snapshot:
377
                current_inventory_snapshot = CurrentInventorySnapshot()
378
                current_inventory_snapshot.item = item
379
                current_inventory_snapshot.warehouse = warehouse
380
                current_inventory_snapshot.availibility = 0
871 chandransh 381
                current_inventory_snapshot.reserved = 0
483 rajveer 382
            # added the difference in the current inventory    
383
            current_inventory_snapshot.availibility = current_inventory_snapshot.availibility + quantity
4400 rajveer 384
            try:
385
                if quantity > 0 and __get_item_reserved(item) > 0:
386
                    cl = TransactionClient().get_client()
4448 rajveer 387
                    #FIXME hardcoding for warehouse id 
388
                    cl.addAlert(AlertType.NEW_INVENTORY_ALERT, 5, "Inventory received for item " + item.brand + " " + item.model_name + " " + item.model_number + " " +  item.color)
4400 rajveer 389
            except:
390
                print "Not able to raise alert for incoming inventory" 
483 rajveer 391
        except:
392
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
2368 ankur.sing 393
        session.commit() 
394
        check_risky_item(item)
483 rajveer 395
 
4748 mandeep.dh 396
def __send_mail_for_missing_key(item_key, warehouse_id):
397
    if not MissingItemKey.get_by(itemKey = item_key):
398
        missingItemKey = MissingItemKey()
399
        missingItemKey.itemKey = item_key
400
        missingItemKey.warehouseId = warehouse_id
401
        helperClient = HelperClient().get_client()
402
        helperClient.saveUserEmailForSending('mandeep.dhir@shop2020.in', 'inventory@shop2020.in', 'Item-key not found while inventory sync', item_key + ' warehouse id: ' + str(warehouse_id), None, 'inventory')
403
        session.commit()
404
 
4320 rajveer 405
def add_inventory(itemId, warehouseId, quantity):
406
    current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
407
    if not current_inventory_snapshot:
408
        current_inventory_snapshot = CurrentInventorySnapshot()
409
        current_inventory_snapshot.item_id = itemId
410
        current_inventory_snapshot.warehouse_id = warehouseId
411
        current_inventory_snapshot.availibility = 0
412
        current_inventory_snapshot.reserved = 0
413
    # added the difference in the current inventory    
414
    current_inventory_snapshot.availibility = current_inventory_snapshot.availibility + quantity
415
    session.commit() 
416
 
4431 phani.kuma 417
'''
94 ashish 418
def get_item_inventoy(item_id):
419
 
420
    inventory = Item.get_by(id=item_id).currentInventory
421
    if not inventory:
122 ashish 422
        raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
94 ashish 423
    return inventory
4431 phani.kuma 424
'''
94 ashish 425
 
635 rajveer 426
def get_item_inventory_by_item_id(item_id):
427
    inventory = Item.get_by(id=item_id).currentInventory
379 ashish 428
    if not inventory:
429
        raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
430
    return inventory
431
 
103 ashish 432
 
433
def retire_warehouse(warehouse_id):
434
    if not warehouse_id:
122 ashish 435
        raise InventoryServiceException(101, "Bad warehouse id")
103 ashish 436
    warehouse = get_Warehouse(warehouse_id)
437
    if not warehouse:
122 ashish 438
        raise InventoryServiceException(108, "warehouse id not present")
439
    warehouse.status = status.DELETED;
103 ashish 440
    session.commit()
441
 
442
def retire_item(item_id):
443
    if not item_id:
122 ashish 444
        raise InventoryServiceException(101, "bad item id")
635 rajveer 445
    item = get_item(item_id)
103 ashish 446
    if not item:
122 ashish 447
        raise InventoryServiceException(108, "item id not present")
448
    item.status = status.PHASED_OUT
449
    item.retireDate = datetime.datetime.now()
103 ashish 450
    session.commit()
122 ashish 451
 
452
#need to implement threads based solution here
103 ashish 453
def start_item_on(item_id, timestamp):
454
    if not item_id:
122 ashish 455
        raise InventoryServiceException(101, "bad item id")
635 rajveer 456
    item = get_item(item_id)
103 ashish 457
    if not item:
122 ashish 458
        raise InventoryServiceException(108, "item id not present")
103 ashish 459
 
122 ashish 460
    item.status = status.ACTIVE
461
    item.startDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))
462
    add_status_change_log(item, status.ACTIVE)
103 ashish 463
    session.commit()
464
 
122 ashish 465
#need to implement threads here
103 ashish 466
def retire_item_on(item_id, timestamp):
467
    if not item_id:
122 ashish 468
        raise InventoryServiceException(101, "bad item id")
635 rajveer 469
    item = get_item(item_id)
103 ashish 470
    if not item:
122 ashish 471
        raise InventoryServiceException(108, "item id not present")
103 ashish 472
 
122 ashish 473
    item.status = status.PHASED_OUT
474
    item.retireDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))
475
    add_status_change_log(item, status.PHASED_OUT)
103 ashish 476
    session.commit()
477
 
478
def add_status_change_log(item, new_status):
479
    item_change_log = ItemChangeLog()
480
    item_change_log.new_status = new_status
481
    item_change_log.old_status = item.status
482
    item_change_log.timestamp = datetime.datetime.now()
483
    item_change_log.item = item
484
    session.commit()
485
 
486
def change_item_status(item_id, new_status):
487
    if not item_id:
122 ashish 488
        raise InventoryServiceException(101, "bad item id")
635 rajveer 489
    item = get_item(item_id)
103 ashish 490
    if not item:
122 ashish 491
        raise InventoryServiceException(108, "item id not present")
2116 ankur.sing 492
    add_status_change_log(item, new_status)
122 ashish 493
    item.status = new_status
2251 ankur.sing 494
    if item.status == status.PHASED_OUT:
495
        item.status_description = "This item has been phased out"
496
    elif item.status == status.DELETED:
497
        item.status_description = "This item has been deleted"
3924 rajveer 498
    elif item.status == status.PAUSED:
499
        item.status_description = "This item is currently out of stock"      
500
    elif item.status == status.PAUSED_BY_RISK:
501
        item.status_description = "This item is currently out of stock"
502
        #This will clear cache from tomcat
503
        __clear_homepage_cache()  
2251 ankur.sing 504
    elif item.status == status.ACTIVE:
505
        item.status_description = "This item is active"
506
    elif item.status == status.IN_PROCESS:
507
        item.status_description = "This item is in process"
508
    elif item.status == status.CONTENT_COMPLETE:
509
        item.status_description = "This item is in process"
103 ashish 510
    session.commit()
511
 
512
def get_item_availability_for_warehouse(warehouse_id, item_id):
513
    if not warehouse_id:
122 ashish 514
        raise InventoryServiceException(101, "bad warehouse_id")
103 ashish 515
    if not item_id:
122 ashish 516
        raise InventoryServiceException(101, "bad item_id")
103 ashish 517
 
518
    warehouse = get_Warehouse(warehouse_id)
519
    if not warehouse:
122 ashish 520
        raise InventoryServiceException(108, "warehouse does not exist")
635 rajveer 521
    item = get_item(item_id)
504 rajveer 522
 
103 ashish 523
    if not item:
766 rajveer 524
        raise InventoryServiceException(108, "item does not exist")
122 ashish 525
 
494 rajveer 526
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id)
504 rajveer 527
    query = query.filter_by(item_id = item.id)
494 rajveer 528
    try:
529
        current_inventory_snapshot = query.one()
871 chandransh 530
        return current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
494 rajveer 531
    except:
532
        return 0
533
    """
534
    current_inventory_snapshot = CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id == warehouse_id, CurrentInventorySnapshot.item_id == item_id).one()
103 ashish 535
    if not current_inventory_snapshot:
536
        return 0
537
    else:
538
        return current_inventory_snapshot.availibility
494 rajveer 539
    """
643 chandransh 540
 
2368 ankur.sing 541
def check_risky_item(item):
2251 ankur.sing 542
    if not item.risky:
543
        return
4406 anupam.sin 544
    availability = __get_item_availability(item, None)
2983 chandransh 545
    if availability <= 0:
2251 ankur.sing 546
        if item.status == status.ACTIVE:
2984 rajveer 547
            change_item_status(item.id, status.PAUSED_BY_RISK)
4318 rajveer 548
            try:
4374 rajveer 549
                mail("cnc.center@shop2020.in", "5h0p2o2o", ["chaitnaya.vats@shop2020.in", "abhishek.mathur@shop2020.in"], "Item is out of stock. ID: " + str(item.id)  + " " + item.brand +  " " + item.model_name + " " + item.model_number, " ", [])
4318 rajveer 550
            except:
551
                print "Unable to send the report"
2251 ankur.sing 552
    else:
2984 rajveer 553
        if item.status == status.PAUSED_BY_RISK:
2251 ankur.sing 554
            change_item_status(item.id, status.ACTIVE)
2368 ankur.sing 555
    session.commit()
2251 ankur.sing 556
 
4406 anupam.sin 557
'''
558
This method returns quantity of a particular item across all warehouses whose ids is provided
559
if warehouse_ids is null it checks for inventory in all warehouses.
560
'''
561
def __get_item_availability(item, warehouse_ids):
562
    if warehouse_ids is None:
563
        all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
564
        availability = 0
565
        reserved = 0
566
        for currInv in all_inventory:
567
            availability = availability + currInv.availibility
568
            reserved = reserved + currInv.reserved
569
        return availability - reserved
570
    else:
571
        total_availability = 0
572
        for warehouse_id in warehouse_ids:
573
            try:
574
                current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item.id).one()
575
                availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
576
            except Exception as e:
577
                print e
578
                availability = 0    
579
            total_availability = total_availability + availability
580
        return total_availability 
4400 rajveer 581
 
582
def __get_item_reserved(item):
583
    all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
584
    reserved = 0
585
    for currInv in all_inventory:
586
        reserved = reserved + currInv.reserved
587
    return reserved
2983 chandransh 588
 
871 chandransh 589
def reserve_item_in_warehouse(item_id, warehouse_id, quantity):    
590
    if not warehouse_id:
591
        raise InventoryServiceException(101, "bad warehouse_id")
2251 ankur.sing 592
    item = get_item(item_id)
593
    if not item:
871 chandransh 594
        raise InventoryServiceException(101, "bad item_id")
595
 
596
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
597
    try:
598
        current_inventory_snapshot = query.one()
599
    except:
4103 chandransh 600
        current_inventory_snapshot = CurrentInventorySnapshot()
601
        current_inventory_snapshot.warehouse_id = warehouse_id
602
        current_inventory_snapshot.item_id = item_id
603
        current_inventory_snapshot.availibility = 0
604
        current_inventory_snapshot.reserved = 0
605
 
606
    current_inventory_snapshot.reserved = current_inventory_snapshot.reserved + quantity
607
    session.commit()
608
    check_risky_item(item)
609
    return True
871 chandransh 610
 
611
def reduce_reservation_count(item_id, warehouse_id, quantity):
612
    if not warehouse_id:
613
        raise InventoryServiceException(101, "bad warehouse_id")
2251 ankur.sing 614
    item = get_item(item_id)
615
    if not item:
871 chandransh 616
        raise InventoryServiceException(101, "bad item_id")
617
 
618
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
619
    try:
620
        current_inventory_snapshot = query.one()
621
        current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
4318 rajveer 622
        ##FIXME In case of our own warehouse reduce availability also
623
        if warehouse_id == 7:
4335 rajveer 624
            current_inventory_snapshot.availibility = current_inventory_snapshot.availibility - quantity
871 chandransh 625
        session.commit()
2368 ankur.sing 626
        check_risky_item(item)
871 chandransh 627
        return True
628
    except:
629
        print "Unexpected error:", sys.exc_info()[0]
630
        return False
631
 
2075 rajveer 632
def mark_item_as_content_complete(entity_id, category, brand, modelName, modelNumber):
2828 rajveer 633
    '''
634
    Get all the items for this entityID and update category, brand, modelName and modelNumber for all.
635
    Update Status for only IN_PROCESS items to CONTENT_COMPLETE
636
    '''
723 chandransh 637
    content_complete_status = status.CONTENT_COMPLETE
2828 rajveer 638
    items = Item.query.filter_by(catalog_item_id=entity_id).all()
723 chandransh 639
    current_timestamp = datetime.datetime.now()
640
    for item in items:
2828 rajveer 641
        if item.status == status.IN_PROCESS:
642
            item.status = content_complete_status
643
            item_change_log = ItemChangeLog()
644
            item_change_log.old_status = item.status
645
            item_change_log.new_status = content_complete_status
646
            item_change_log.timestamp = current_timestamp
647
            item_change_log.item = item
723 chandransh 648
 
2075 rajveer 649
        item.category = category
650
        item.brand = brand
2081 rajveer 651
        item.model_name = modelName
652
        item.model_number = modelNumber
723 chandransh 653
        item.updatedOn = current_timestamp
654
    session.commit()
655
    return True
1294 chandransh 656
 
643 chandransh 657
def get_item_availability_for_location(warehouse_loc, item_id):
3355 chandransh 658
    """
659
    Determines the warehouse that should be used to fulfil an order for the given item.
4406 anupam.sin 660
    It first checks whether the preferred warehouse for that item is set or not. If set 
661
    and preference is sticky then that warehouse is used for fulfilment.
662
    If preference is not sticky then we see if item is available in the preferred WH,
663
    in which case that warehouse is used otherwise we use that warehouse which has the max
664
    availability. And if there is no inventory for that item in any warehouses then we use
665
    default warehouse.
666
    If preference is not set in that case we just find the warehouse with max availability
667
    and in case of zero inventory we use default warehouse
3355 chandransh 668
 
669
    Returns an ordered list of size 4 with following elements in the given order:
670
    1. Logistics location of the warehouse which was finally picked up to ship the order.
671
    2. Id of the warehouse which was finally picked up.
672
    3. Inventory size in the selected warehouse.
673
    4. Expected delay added by the category manager.
674
 
675
    Parameters:
676
     - warehouse_loc
677
     - item_id
678
    """
643 chandransh 679
    if warehouse_loc is None:
680
        raise InventoryServiceException(101, "Bad Warehouse Location")
681
    if not item_id:
1416 chandransh 682
        raise InventoryServiceException(101, "Bad Item id")
643 chandransh 683
 
1416 chandransh 684
    item = Item.get_by(id=item_id)
4406 anupam.sin 685
    logisticsLocation = warehouse_loc
686
    warehouses = Warehouse.query.filter_by(logisticsLocation=logisticsLocation).all()
643 chandransh 687
    warehouse_ids = [warehouse.id for warehouse in warehouses]
688
    warehouse_retid = -1
4406 anupam.sin 689
 
3503 chandransh 690
    total_availability = 0
4406 anupam.sin 691
    '''
692
    If warehouse preference is set and it is sticky then we should fulfil this order from this warehouse only.
693
    But we still need to calculate total availability across warehouses.
694
    '''
695
    if (item.isWarehousePreferenceSticky and item.preferredWarehouse is not None) :
696
        warehouse_retid = item.preferredWarehouse
697
        warehouse = Warehouse.get_by(id=warehouse_retid)
698
        logisticsLocation = warehouse.logisticsLocation
4476 anupam.sin 699
        total_availability = __get_item_availability(item, [warehouse_retid])
4406 anupam.sin 700
 
701
    #If preference is not sticky then this order should be fulfilled from preferred WH if inventory available
702
    #otherwise we should check for its availability elsewhere and fulfil this order from there, but if it is not available anywhere
703
    #then we should fulfil this order from its default warehouse.
704
 
705
    elif (not item.isWarehousePreferenceSticky and item.preferredWarehouse is not None) :
785 rajveer 706
        try:
4406 anupam.sin 707
            current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = item.preferredWarehouse, item_id = item_id).one()
871 chandransh 708
            availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
4317 varun.gupt 709
        except Exception as e:
710
            print e
785 rajveer 711
            availability = 0    
4406 anupam.sin 712
        if availability > 0:
713
            warehouse_retid = item.preferredWarehouse
4476 anupam.sin 714
            total_availability = availability
4406 anupam.sin 715
        else :
716
            [logisticsLocation, warehouse_retid, total_availability] = \
717
                        __get_warehouse_with_max_availability(warehouse_loc = warehouse_loc, \
718
                                                            warehouse_ids = warehouse_ids, item = item)
719
 
720
    else :
721
        [logisticsLocation, warehouse_retid, total_availability] = \
722
                        __get_warehouse_with_max_availability(warehouse_loc = warehouse_loc, \
723
                                                            warehouse_ids = warehouse_ids, item = item)
2341 chandransh 724
 
4406 anupam.sin 725
    if item.expectedDelay is None:
726
        print 'expectedDelay field for this item was Null. Resetting it to 0'
727
        item.expectedDelay = 0
728
 
729
    ## FIXME Assign warehouse 5 (9D2) for all the hotspot products.
730
    #if warehouse_retid in [warehouse.id for warehouse in get_warehouses_for_vendor(1)]:
4433 anupam.sin 731
    if int(warehouse_retid) in [1,2,3,4,5]:
4406 anupam.sin 732
        warehouse_retid = 5
733
        warehouse = Warehouse.get_by(id=warehouse_retid)
734
        logisticsLocation = warehouse.logisticsLocation  
735
 
736
    return [logisticsLocation, int(warehouse_retid), total_availability, int(item.expectedDelay)]
737
 
738
def __get_warehouse_with_max_availability(warehouse_loc, warehouse_ids, item):
739
 
740
    warehouse_retid = -1
741
    max_availability = 0
742
    total_availability = 0
743
 
744
    for warehouse_id in warehouse_ids:
745
            try:
746
                current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item.id).one()
747
                availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
748
            except Exception as e:
749
                print e
750
                availability = 0    
751
            if availability > max_availability:
752
                warehouse_retid = warehouse_id
753
                max_availability = availability
754
            total_availability = total_availability + availability
755
 
756
    #If no warehouse could be found, use the default warehouse for this item
643 chandransh 757
    if warehouse_retid == -1:
759 chandransh 758
        # This is the case when all warehouses have exhausted their
759
        # inventory of this item or no warehouse is available in this
760
        # location.
4406 anupam.sin 761
        warehouse_retid = int(item.defaultWarehouse)
2344 chandransh 762
        warehouse = Warehouse.get_by(id=warehouse_retid)
4406 anupam.sin 763
        warehouse_loc = warehouse.logisticsLocation
2341 chandransh 764
        try:
4406 anupam.sin 765
            current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_retid, item_id = item.id).one()
3503 chandransh 766
            max_availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
4317 varun.gupt 767
        except Exception as e:
768
            print e
3503 chandransh 769
            max_availability = 0
770
        total_availability = max_availability
643 chandransh 771
 
4406 anupam.sin 772
    return [warehouse_loc, warehouse_retid, total_availability]
773
'''    
774
def calculate_total_availability(warehouse_ids, item_id):
775
    total_availability = 0
776
    for warehouse_id in warehouse_ids:
777
            try:
778
                current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).one()
779
                availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
780
            except Exception as e:
781
                print e
782
                availability = 0    
783
            total_availability = total_availability + availability
784
    return total_availability
785
'''
2341 chandransh 786
 
122 ashish 787
def get_warehouses_for_item(item_id):
643 chandransh 788
 
122 ashish 789
    if not item_id:
790
        raise InventoryServiceException(101, "bad item_id")
635 rajveer 791
    item = get_item(item_id)
122 ashish 792
 
793
    if not item:
794
        raise InventoryServiceException(101, "bad item")
795
 
483 rajveer 796
    warehouses = item.currentInventory.warehouse
501 rajveer 797
    return warehouses
798
 
2404 chandransh 799
def get_child_categories(category):
800
    cm = CategoryManager()
2621 varun.gupt 801
    cat = cm.getCategory(category)
802
    return cat.children_category_ids if cat else None
2404 chandransh 803
 
626 chandransh 804
def get_best_sellers(start_index, stop_index, category=-1):
2404 chandransh 805
    '''
806
    Returns the Best Sellers between the start and the stop index in the given category
807
    '''
1926 rajveer 808
    query = get_best_sellers_query(category, None)
1098 chandransh 809
    best_sellers = query.all()[start_index:stop_index]
621 chandransh 810
    return get_thrift_item_list(best_sellers)
811
 
2093 chandransh 812
def get_best_sellers_count(category=-1):
2404 chandransh 813
    '''
814
    Returns the number of best sellers in the given category
815
    '''
1926 rajveer 816
    count = get_best_sellers_query(category, None).count()
1120 rajveer 817
    if count is None:
818
        count = 0
766 rajveer 819
    return count
621 chandransh 820
 
1926 rajveer 821
def get_best_sellers_catalog_ids(start_index, stop_index, brand, category=-1):
2404 chandransh 822
    '''
823
    Returns the Best sellers for the given brand and category between the start and the stop index.
824
    Ignores the category if it's passed as -1 and the brand if it's passed as None. 
825
    '''
1926 rajveer 826
    query = get_best_sellers_query(category, brand)
1098 chandransh 827
    best_sellers = query.all()[start_index:stop_index]
621 chandransh 828
    return [item.catalog_item_id for item in best_sellers]
1970 rajveer 829
 
1926 rajveer 830
def get_best_sellers_query(category, brand):
2404 chandransh 831
    '''
832
    Returns the query to be used for getting Best Sellers.
833
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
834
    '''
1098 chandransh 835
    query = Item.query.filter_by(status=status.ACTIVE).filter(Item.bestSellingRank != None)
626 chandransh 836
    if category != -1:
1970 rajveer 837
        all_categories = [category]
838
        child_categories = get_child_categories(category)
839
        if child_categories is not None:
840
            all_categories = all_categories + child_categories 
841
        query = query.filter(Item.category.in_(all_categories))
1926 rajveer 842
    if brand is not None:
843
        query = query.filter_by(brand=brand)
1098 chandransh 844
    query = query.order_by(asc(Item.bestSellingRank))
621 chandransh 845
    return query
609 chandransh 846
 
1098 chandransh 847
def get_best_deals(category=-1):
2404 chandransh 848
    '''
849
    Returns the Best deals in the given category. Ignores the category if it's passed as -1.
850
    '''
851
    query = get_best_deals_query(Item, category, None)
1098 chandransh 852
    items = query.all()
609 chandransh 853
    return get_thrift_item_list(items)
854
 
1098 chandransh 855
def get_best_deals_count(category=-1):
2404 chandransh 856
    '''
857
    Returns the count of best deals in the given category.
858
    Ignores the category if it's -1.
859
    '''
860
    count = get_best_deals_counting_query(func.count(distinct(Item.catalog_item_id)), category, None).scalar()
1120 rajveer 861
    if count is None:
862
        count = 0
766 rajveer 863
    return count
501 rajveer 864
 
1926 rajveer 865
def get_best_deals_catalog_ids(start_index, stop_index, brand, category=-1):
2404 chandransh 866
    '''
867
    Returns the catalog_item_ids of best deal items for the given brand and category.
868
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
869
    '''
870
    query = get_best_deals_query(Item, category, brand)
1098 chandransh 871
    best_deal_items = query.all()[start_index:stop_index]
872
    return [item.catalog_item_id for item in best_deal_items]
873
 
2404 chandransh 874
def get_best_deals_counting_query(obj, category, brand):
875
    '''
876
    Returns the query to be used to select the best deals in the given brand and category.
877
    Ignores the category if it's passed as -1 and the brand if it's passed as None. 
878
    '''
879
    query = session.query(obj).filter_by(status=status.ACTIVE).filter(Item.bestDealValue != None)
626 chandransh 880
    if category != -1:
1970 rajveer 881
        all_categories = [category]
882
        child_categories = get_child_categories(category)
883
        if child_categories is not None:
884
            all_categories = all_categories + child_categories 
885
        query = query.filter(Item.category.in_(all_categories))
1926 rajveer 886
    if brand is not None:
887
        query = query.filter_by(brand=brand)
2404 chandransh 888
    return query
889
 
890
def get_best_deals_query(obj, category, brand):
891
    '''
892
    Returns the query to be used to get the best deals in the given category and brand.
893
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
894
    '''
895
    query = get_best_deals_counting_query(obj, category, brand)
1098 chandransh 896
    query = query.group_by(Item.catalog_item_id).order_by(desc(Item.bestDealValue))
897
    return query
609 chandransh 898
 
1098 chandransh 899
def get_latest_arrivals(limit, category=-1):
2404 chandransh 900
    '''
901
    Returns up to limit number of Latest Arrivals in the given category.
902
    '''
2975 chandransh 903
    categories = []
904
    if category != -1:
905
        categories = [category]
906
    query = get_latest_arrivals_query(Item, categories, None)
1098 chandransh 907
    items = query.all()[0:limit]
609 chandransh 908
    return get_thrift_item_list(items)
598 chandransh 909
 
1098 chandransh 910
def get_latest_arrivals_count(limit, category=-1):
2404 chandransh 911
    '''
912
    Returns the number of latest arrivals which will be displayed on the website.
3016 chandransh 913
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 914
    '''
2975 chandransh 915
    categories = []
916
    if category != -1:
917
        categories = [category]
918
    count = get_latest_arrivals_counting_query(func.count(distinct(Item.catalog_item_id)), categories, None).scalar()
1120 rajveer 919
    if count is None:
920
        count = 0
921
    count = min(count, limit)
766 rajveer 922
    return count
602 chandransh 923
 
2975 chandransh 924
def get_latest_arrivals_catalog_ids(start_index, stop_index, brand, categories=[]):
2404 chandransh 925
    '''
926
    Returns the catalog_item_ids of the latest arrivals between the start and the stop index
3016 chandransh 927
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 928
    '''
2975 chandransh 929
    query = get_latest_arrivals_query(Item, categories, brand)
1098 chandransh 930
    latest_arrivals = query.all()[start_index:stop_index]
931
    return [item.catalog_item_id for item in latest_arrivals]
932
 
2975 chandransh 933
def get_latest_arrivals_counting_query(obj, categories, brand):
2404 chandransh 934
    '''
935
    Returns the query to be used to count Latest arrivals.
3016 chandransh 936
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 937
    '''
938
    query = session.query(obj).filter_by(status=status.ACTIVE)
2975 chandransh 939
 
940
    all_categories = []
941
    for category in categories:
942
        all_categories.append(category)
1970 rajveer 943
        child_categories = get_child_categories(category)
2975 chandransh 944
        if child_categories:
945
            all_categories = all_categories + child_categories
946
    if all_categories: 
1970 rajveer 947
        query = query.filter(Item.category.in_(all_categories))
2975 chandransh 948
 
1926 rajveer 949
    if brand is not None:
950
        query = query.filter_by(brand=brand)
2404 chandransh 951
    return query
952
 
2975 chandransh 953
def get_latest_arrivals_query(obj, categories, brand):
2404 chandransh 954
    '''
955
    Returns the query to be used to retrieve Latest Arrivals.
956
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
957
    '''
2975 chandransh 958
    query = get_latest_arrivals_counting_query(obj, categories, brand)
1098 chandransh 959
    query = query.group_by(Item.catalog_item_id).order_by(desc(Item.startDate))
960
    return query
609 chandransh 961
 
962
def get_thrift_item_list(items):
1098 chandransh 963
    return [to_t_item(item) for item in items if item != None]
635 rajveer 964
 
1155 rajveer 965
def generate_new_entity_id():
966
    generator =  EntityIDGenerator.query.one()
967
    id = generator.id + 1
968
    generator.id = id
969
    session.commit()
970
    return id
971
 
635 rajveer 972
def put_category_object(object):
973
    category = Category.get_by(id=1)
974
    if category is None:
975
        category = Category()
976
    category.object = object    
977
    session.commit()
978
    return True
979
 
980
def get_category_object():
766 rajveer 981
    object = Category.get_by(id=1).object
982
    return object
983
 
4283 anupam.sin 984
def get_item_pricing(item_id, vendorId):
1341 chandransh 985
    item = Item.query.filter_by(id=item_id).first()
986
    if item is None:
987
        raise InventoryServiceException(101, "Bad Item")
4307 anupam.sin 988
    '''
989
    if vendor id is -1 then we calculate an average transfer price to be populated
990
    at the time of order creation. This will be later updated with actual transfer price
991
    at the time of billing.
992
    '''
993
    if(vendorId == -1):
4543 anupam.sin 994
        total = 0
4307 anupam.sin 995
        try:
996
            item_pricings = VendorItemPricing.query.filter_by(item=item).all()
4315 anupam.sin 997
            if item_pricings:
4307 anupam.sin 998
                for item_pricing in item_pricings:
4543 anupam.sin 999
                    total += item_pricing.transfer_price
4315 anupam.sin 1000
                avg = total / len(item_pricings)
1001
                item_pricing.transfer_price = avg
4543 anupam.sin 1002
            else:
1003
                item_pricing = VendorItemPricing()
1004
                item_pricing.transfer_price = item.sellingPrice
1005
                vendor = Vendor()
1006
                vendor.id = vendorId
1007
                item_pricing.vendor = vendor
1008
                item_pricing.item = item
1009
 
1010
            return item_pricing
4307 anupam.sin 1011
        except:
1012
            raise InventoryServiceException(101, "Item pricing not found ")
4283 anupam.sin 1013
    vendor = Vendor.get_by(id=vendorId)    
1341 chandransh 1014
    try:
1015
        item_pricing = VendorItemPricing.query.filter_by(vendor=vendor, item=item).one()
1347 chandransh 1016
        return item_pricing
3244 chandransh 1017
    except MultipleResultsFound:
1341 chandransh 1018
        raise InventoryServiceException(110, "Multiple pricing information present for Vendor: " + vendor.name + " and Item: " + str(item_id))
3244 chandransh 1019
    except NoResultFound:
1341 chandransh 1020
        raise InventoryServiceException(111, "Missing pricing information for Vendor: " + vendor.name + " and Item: " + str(item_id))
1021
 
1970 rajveer 1022
def add_category(t_category):
1023
    category = Category.get_by(id=t_category.id)
1024
    if category is None:
1025
        category = Category()
1026
    category.id = t_category.id 
1027
    category.label = t_category.label
1028
    category.description = t_category.description
1029
    category.parent_category_id = t_category.parent_category_id 
1030
    session.commit()
1031
    return True
1032
 
1033
def get_category(id):
1034
    return Category.query.filter_by(id=id).first()
1035
 
1036
def get_all_categories():
1037
    return Category.query.all()
1038
 
1991 ankur.sing 1039
 
1040
def get_all_item_pricing(item_id):
1041
    item = Item.query.filter_by(id=item_id).first()
1042
    if item is None:
1043
        raise InventoryServiceException(101, "Bad Item")
1044
    item_pricing = VendorItemPricing.query.filter_by(item=item).all()
1045
    return item_pricing
1046
 
2116 ankur.sing 1047
def get_item_mappings(item_id):
1048
    item = Item.query.filter_by(id=item_id).first()
1049
    if item is None:
1050
        raise InventoryServiceException(101, "Bad Item")
1051
    item_mappings = VendorItemMapping.query.filter_by(item=item).all()
1052
    return item_mappings
1053
 
1054
def add_vendor_pricing(vendorItemPricing):
1991 ankur.sing 1055
    if not vendorItemPricing:
1056
        raise InventoryServiceException(108, "Bad vendorItemPricing in request")
1057
    vendorId = vendorItemPricing.vendorId
1058
    itemId = vendorItemPricing.itemId
1059
 
1060
    try:
1061
        vendor = Vendor.query.filter_by(id=vendorId).one()
1062
    except:
1063
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
1064
 
1065
    try:
1066
        item = Item.query.filter_by(id=itemId).one()
1067
    except:
1068
        raise InventoryServiceException(101, "Item not found for vendorId " + str(itemId))
1069
 
2120 ankur.sing 1070
    validate_vendor_prices(to_t_item(item), vendorItemPricing)
2065 ankur.sing 1071
 
1991 ankur.sing 1072
    try:
1073
        ds_vendorItemPricing = VendorItemPricing.query.filter(and_(VendorItemPricing.vendor==vendor, VendorItemPricing.item==item)).one()
1074
    except:
2116 ankur.sing 1075
        ds_vendorItemPricing = VendorItemPricing()
1076
        ds_vendorItemPricing.vendor = vendor
1077
        ds_vendorItemPricing.item = item
1991 ankur.sing 1078
 
1079
    if vendorItemPricing.mop:
1080
        ds_vendorItemPricing.mop = vendorItemPricing.mop
1081
    if vendorItemPricing.dealerPrice:
1082
        ds_vendorItemPricing.dealerPrice = vendorItemPricing.dealerPrice
1083
    if vendorItemPricing.transferPrice:
2065 ankur.sing 1084
        ds_vendorItemPricing.transfer_price = vendorItemPricing.transferPrice
1991 ankur.sing 1085
 
1086
    session.commit()
1087
    return
1088
 
2358 ankur.sing 1089
def add_vendor_item_mapping(key, vendorItemMapping):
2116 ankur.sing 1090
    if not vendorItemMapping:
1091
        raise InventoryServiceException(108, "Bad vendorItemMapping in request")
1092
    vendorId = vendorItemMapping.vendorId
1093
    itemId = vendorItemMapping.itemId
1094
 
1095
    try:
1096
        vendor = Vendor.query.filter_by(id=vendorId).one()
1097
    except:
1098
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
1099
 
1100
    try:
1101
        item = Item.query.filter_by(id=itemId).one()
1102
    except:
1103
        raise InventoryServiceException(101, "Item not found for vendorId " + str(itemId))
1104
 
1105
    try:
2358 ankur.sing 1106
        ds_vendorItemMapping = VendorItemMapping.query.filter(and_(VendorItemMapping.vendor==vendor, VendorItemMapping.item==item, VendorItemMapping.item_key==key)).one()
2116 ankur.sing 1107
    except:
1108
        ds_vendorItemMapping = VendorItemMapping()
1109
        ds_vendorItemMapping.vendor = vendor
1110
        ds_vendorItemMapping.item = item
2497 ankur.sing 1111
    ds_vendorItemMapping.vendor_category = vendorItemMapping.vendorCategory
2116 ankur.sing 1112
    ds_vendorItemMapping.item_key = vendorItemMapping.itemKey
1113
 
1114
    session.commit()
1115
    return
1116
 
2120 ankur.sing 1117
def validate_item_prices(item):
2129 ankur.sing 1118
    if item.mrp == None or item.sellingPrice == None or item.mrp == "" or item.sellingPrice == "":
1119
        return
1120
    if item.mrp < item.sellingPrice:
2120 ankur.sing 1121
        print "[BAD MRP and SP:] for {0} {1} {2} {3}. MRP={4}, SP={5}".format(item.productGroup, item.brand, item.modelNumber, item.color, str(item.mrp), str(item.sellingPrice))
1122
        raise InventoryServiceException(101, "[BAD MRP and SP:] for {0} {1} {2} {3}. MRP={4}, SP={5}".format(item.productGroup, item.brand, item.modelNumber, item.color, str(item.mrp), str(item.sellingPrice)))
2065 ankur.sing 1123
    return
2120 ankur.sing 1124
 
1125
def validate_vendor_prices(item, vendorPrices):
2129 ankur.sing 1126
    if item.mrp != None and item.mrp != "" and vendorPrices.mop != "" and item.mrp <  vendorPrices.mop:
2120 ankur.sing 1127
        print "[BAD MRP and MOP:] for {0} {1} {2} {3}. MRP={4}. MOP={5}, Vendor={6}".format(item.productGroup, item.brand, item.modelNumber, item.color, str(item.mrp), str(vendorPrices.mop), str(vendorPrices.vendorId))
1128
        raise InventoryServiceException(101, "[BAD MRP and MOP:] for {0} {1} {2} {3}. MRP={4}. MOP={5}, Vendor={6}".format(item.productGroup, item.brand, item.modelNumber, item.color, str(item.mrp), str(vendorPrices.mop), str(vendorPrices.vendorId)))
1129
    if vendorPrices.mop != "" and vendorPrices.transferPrice != "" and vendorPrices.transferPrice > vendorPrices.mop:
1130
        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))
1131
        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)))
1132
    return
2065 ankur.sing 1133
 
1134
def get_all_vendors():
1135
    return Vendor.query.all()
1136
 
4725 phani.kuma 1137
def check_color_valid(color):
1138
    if color is not None:
1139
        color = color.strip().lower()
1140
        if color != '' and color != 'na' and color != 'blank' and color != '(blank)':
1141
            return True
1142
    return False
1143
 
1144
def check_similar_item(brand, model_number, model_name, color):
2129 ankur.sing 1145
    query = Item.query
2428 ankur.sing 1146
    query = query.filter_by(brand=brand)
1147
    query = query.filter_by(model_number=model_number)
4725 phani.kuma 1148
    query = query.filter_by(model_name=model_name)
1149
    similar_items = query.all()
1150
    item = None
1151
    # Check if a similar item already exists in our database
1152
    for old_item in similar_items:
1153
        if old_item.color != None and old_item.color.strip().lower() == color.strip().lower():
1154
            item = old_item
1155
            break
1156
 
1157
    # Check if a similar item already exists in our database with out valid color if similar item with same color is not found
2116 ankur.sing 1158
    if item is None:
4725 phani.kuma 1159
        for old_item in similar_items:
1160
            if not check_color_valid(old_item.color):
1161
                item = old_item
1162
                break
1163
    i = 0
1164
    color_of_similar_item = None
1165
    # Check if a similar item already exists in our database to be used to get catalog_item_id
1166
    for old_item in similar_items:
1167
        # get a similar item already existing in our database with valid color
1168
        if check_color_valid(old_item.color):
1169
            similar_item = old_item
1170
            color_of_similar_item = similar_item.color
1171
            break
1172
        i = i + 1
1173
        # get a similar item already existing in our database if similar item with valid color is not found
1174
        if i == len(similar_items):
1175
            similar_item = old_item
1176
            color_of_similar_item = similar_item.color
1177
 
1178
    # Check if a similar item that is obtained above is having a valid color
1179
    if check_color_valid(color_of_similar_item):
1180
        # if a similar item that is obtained above is having a valid color and new item is about to be created with out valid color it is not done.
1181
        # since for example if their is a item with red color in our database and we are creating a new item with no color for the same product which is wrong.
1182
        if item is None and not check_color_valid(color):
1183
            return similar_item.id
1184
 
1185
    if item is None:
2116 ankur.sing 1186
        return 0
1187
    else:
1188
        return item.id
2286 ankur.sing 1189
 
1190
def change_risky_flag(item_id, risky):
1191
    item = get_item(item_id)
1192
    if not item:
1193
        raise InventoryServiceException(101, "Item missing in our database")
1194
    try:
1195
        log_risky_flag(item_id, risky)
1196
    except:
1197
        print "Not able to log risky flag change"
1198
    item.risky = risky
4295 varun.gupt 1199
    if not risky and item.status == status.PAUSED_BY_RISK:
2368 ankur.sing 1200
        change_item_status(item.id, status.ACTIVE)
2286 ankur.sing 1201
    session.commit()
1202
 
2358 ankur.sing 1203
def get_items_by_vendor_category(vendor_category):
1204
    if not vendor_category:
1205
        raise InventoryServiceException(101, "Invalid vendor category in request")
1206
    query = Item.query.filter(and_(Item.hotspotCategory==vendor_category, Item.status != status.PHASED_OUT))
1207
    items = query.all()
1208
    return items
2116 ankur.sing 1209
 
2358 ankur.sing 1210
def get_risky_items():
1211
    items = Item.query.filter_by(risky=True).all()
1212
    return items
3008 rajveer 1213
 
2809 rajveer 1214
def get_similar_items_catalog_ids(start_index, stop_index, itemId):
3008 rajveer 1215
    query = SimilarItems.query.filter_by(item_id=itemId).limit(stop_index-start_index)
1216
    similar_items = query.all()
3289 rajveer 1217
    return_list = []
1218
    for similar_item in similar_items:
1219
        isActive = False
1220
        try:
1221
            all_items = Item.query.filter_by(catalog_item_id=similar_item.catalog_item_id).all()
1222
        except:
1223
            continue
1224
        for item in all_items:
1225
            isActive = isActive or item.status == status.ACTIVE
1226
        if isActive:
1227
            return_list.append(similar_item.catalog_item_id)
1228
    return return_list
4423 phani.kuma 1229
 
1230
def get_all_similar_items_catalog_ids(itemId):
1231
    query = SimilarItems.query.filter_by(item_id=itemId)
1232
    similar_items = query.all()
1233
    return_list = []
1234
    for similar_item in similar_items:
1235
        item_query = Item.query.filter_by(catalog_item_id=similar_item.catalog_item_id).limit(1)
1236
        item = item_query.one()
1237
        return_list.append(item)
2809 rajveer 1238
 
4423 phani.kuma 1239
    return get_thrift_item_list(return_list)
1240
 
1241
def add_similar_item_catalog_id(itemId, catalog_item_id):
1242
    if not itemId or not catalog_item_id:
1243
        raise InventoryServiceException(101, "Bad itemId or catalogItemId in request")
1244
    items_for_entity = get_items_by_catalog_id(catalog_item_id)
1245
    if not len(items_for_entity):
1246
        raise InventoryServiceException(101, "catalogItemId does not exists in database")
1247
 
1248
    s_items = SimilarItems.query.filter_by(item_id=itemId, catalog_item_id=catalog_item_id).all()
1249
    if not len(s_items):
1250
        s_item = SimilarItems()
1251
        s_item.item_id=itemId
1252
        s_item.catalog_item_id=catalog_item_id
1253
        session.commit()
1254
        return items_for_entity[0]
1255
    else:
1256
        raise InventoryServiceException(101, "Already exists")
1257
 
1258
def delete_similar_item_catalog_id(itemId, catalog_item_id):
1259
    if not itemId or not catalog_item_id:
1260
        raise InventoryServiceException(101, "Bad itemId or catalogItemId in request")
1261
 
1262
    similar_item = SimilarItems.query.filter_by(item_id=itemId, catalog_item_id=catalog_item_id).all()
1263
    if len(similar_item):
1264
        similar_item[0].delete()
1265
    session.commit()
1266
    return True
1267
 
3079 rajveer 1268
def add_product_notification(itemId, email):
1269
    try:
3470 rajveer 1270
        try:
1271
            product_notification = ProductNotification.query.filter_by(item_id=itemId, email=email).one()
1272
        except:
1273
            product_notification = ProductNotification()
1274
            product_notification.email = email
1275
            product_notification.item_id = itemId
3079 rajveer 1276
        product_notification.addedOn = datetime.datetime.now()
1277
        session.commit()
1278
        return True
1279
    except:
1280
        return False
3086 rajveer 1281
 
1282
 
1283
def send_product_notifications():
1284
    product_notifications = ProductNotification.query.all()
1285
    for product_notification in product_notifications:
1286
        item = product_notification.item
4406 anupam.sin 1287
        availability = __get_item_availability(item, None)
3309 rajveer 1288
        if availability > 0 and item.status == status.ACTIVE:
3086 rajveer 1289
            __enque_product_notification_email(product_notification.email, __get_product_name(item) , product_notification.addedOn, __get_product_url(item), item.id)
1290
            product_notification.delete()
1291
    session.commit()
1292
    return True
1293
 
1294
def __get_product_name(item):
1295
    product_name = item.brand + " " + item.model_name + " " + item.model_number
1296
    color = item.color
1297
    if color is not None and color != 'NA':
1298
        product_name = product_name + " (" + color + ")"
3201 rajveer 1299
    product_name = product_name.replace("  "," ")
3086 rajveer 1300
    return product_name
1301
 
1302
 
1303
def __get_product_url(item):
1304
    product_url = "http://www.saholic.com/mobile-phones/" + item.brand + "-" + item.model_name + "-" + item.model_number + "-" + str(item.catalog_item_id)
1305
    product_url = product_url.replace("--","-")
1306
    product_url = product_url.replace(" ","")
1307
    return product_url
1308
 
3348 varun.gupt 1309
def get_all_brands_by_category(category_id):
1310
    catm = CategoryManager()
1311
    child_categories = catm.getCategory(category_id).children_category_ids
1312
    brands = session.query(distinct(Item.brand)).filter(Item.category.in_(child_categories)).all()
1313
 
1314
    return [brand[0] for brand in brands]
3086 rajveer 1315
 
1316
def __enque_product_notification_email(email, product, date, url, itemId):
1317
 
1318
    html = """
1319
        <html>
1320
        <body>
1321
        <div>
1322
        <p>
1323
            Hi,<br /><br />
1324
            The product requested by you on $date is now available on saholic.com.
1325
        </p>
1326
 
1327
        <p>    
1328
        <strong>Product: $product </strong>
1329
        </p>
1330
 
1331
        <p>
1332
        Click the link below to visit the product: 
1333
        <br/>
1334
        $url
1335
        </p>
1336
        <p>
1337
        Regards,<br/>
1338
        Saholic Customer Support Team<br/>
1339
        www.saholic.com<br/>
1340
        Email: help@saholic.com<br/>
1341
        </p>
1342
        </div>
1343
        </body>
1344
        </html>
1345
        """
1346
 
1347
    html = Template(html).substitute(dict(product=product,date=date,url=url))
3079 rajveer 1348
 
3086 rajveer 1349
    try:
1350
        helper_client = HelperClient().get_client()
1351
        helper_client.saveUserEmailForSending(email, "", "Product requested by you is available now.", html, str(itemId), "ProductNotification")
1352
    except Exception as e:
1353
        print e
1354
 
3557 rajveer 1355
def get_all_sources():
1356
    sources = Source.query.all()
1357
    return [to_t_source(source) for source in sources]
3086 rajveer 1358
 
3557 rajveer 1359
def get_item_pricing_by_source(itemId, sourceId):
1360
    item = Item.query.filter_by(id=itemId).first()
1361
    if item is None:
1362
        raise InventoryServiceException(101, "Bad Item")
1363
 
1364
    source = Source.query.filter_by(id=sourceId).first()
1365
    if source is None:
1366
        raise InventoryServiceException(101, "Source not found for sourceId " + str(sourceId))
1367
 
1368
    item_pricing = SourceItemPricing.query.filter_by(source=source, item=item).first()
1369
    if item_pricing is None:
1370
        raise InventoryServiceException(101, "Pricing information not found for sourceId " + str(sourceId))
1371
    return item_pricing
1372
 
1373
def add_source_item_pricing(sourceItemPricing):
1374
    if not sourceItemPricing:
1375
        raise InventoryServiceException(108, "Bad sourceItemPricing in request")
1376
 
1377
    if not sourceItemPricing.sellingPrice:
4326 mandeep.dh 1378
        raise InventoryServiceException(101, "Selling Price is not defined for sourceId " + str(sourceItemPricing.sourceId))
3557 rajveer 1379
 
1380
    sourceId = sourceItemPricing.sourceId
1381
    itemId = sourceItemPricing.itemId
1382
 
1383
    item = Item.query.filter_by(id=itemId).first()
1384
    if item is None:
1385
        raise InventoryServiceException(101, "Bad Item")
1386
 
1387
    source = Source.query.filter_by(id=sourceId).first()
1388
    if source is None:
1389
        raise InventoryServiceException(101, "Source not found for sourceId " + str(sourceId))
1390
 
3564 rajveer 1391
    ds_sourceItemPricing = SourceItemPricing.get_by(source=source, item=item)
3557 rajveer 1392
    if ds_sourceItemPricing is None:
1393
        ds_sourceItemPricing = SourceItemPricing()
1394
        ds_sourceItemPricing.source = source
1395
        ds_sourceItemPricing.item = item
1396
 
1397
    if sourceItemPricing.mrp:
1398
        ds_sourceItemPricing.mrp = sourceItemPricing.mrp
1399
    ds_sourceItemPricing.sellingPrice = sourceItemPricing.sellingPrice
1400
 
1401
    session.commit()
1402
    return
1403
 
1404
def get_all_source_pricing(itemId):
1405
    item = Item.query.filter_by(id=itemId).first()
1406
    if item is None:
1407
        raise InventoryServiceException(101, "Bad Item")
1408
    source_pricing = SourceItemPricing.query.filter_by(item=item).all()
1409
    return source_pricing
1410
 
1411
 
1412
def get_item_for_source(item_id, sourceId):
1413
    item = get_item(item_id)
1414
    if sourceId == -1:
1415
        return item
1416
    try:
1417
        sip = get_item_pricing_by_source(item_id, sourceId)
1418
        item.sellingPrice = sip.sellingPrice
1419
        if sip.mrp:
1420
            item.mrp = sip.mrp
1421
    except:
1422
        print "No source pricing"
1423
    return item
1424
 
3872 chandransh 1425
def search_items(search_terms, offset, limit):
1426
    query = Item.query
1427
 
1428
    query_clause = []
1429
 
1430
    search_terms = ['%' + search_term + '%' for search_term in search_terms]
1431
 
1432
    for search_term in search_terms:
1433
        query_clause.append(Item.brand.like(search_term))
1434
        query_clause.append(Item.model_number.like(search_term))
1435
        query_clause.append(Item.model_name.like(search_term))
1436
 
1437
    query = query.filter(or_(*query_clause))
1438
 
1439
    query = query.order_by(Item.product_group, Item.brand, Item.model_number, Item.model_name).offset(offset)
1440
    if limit:
1441
        query = query.limit(limit)
1442
    items = query.all()
1443
    return items
1444
 
1445
def get_search_result_count(search_terms):
1446
    query = Item.query
1447
 
1448
    query_clause = []
1449
 
1450
    search_terms = ['%' + search_term + '%' for search_term in search_terms]
1451
 
1452
    for search_term in search_terms:
1453
        query_clause.append(Item.brand.like(search_term))
1454
        query_clause.append(Item.model_number.like(search_term))
1455
        query_clause.append(Item.model_name.like(search_term))
1456
 
1457
    query = query.filter(or_(*query_clause))
1458
 
1459
    return query.count()
1460
 
3924 rajveer 1461
def __clear_homepage_cache():
1462
    try:
1463
        # create a password manager
1464
        password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
1465
        # Add the username and password.
1466
        configclient = ConfigClient()
4310 rajveer 1467
        ips = configclient.get_property("production_servers_private_ips");
3924 rajveer 1468
        ips = ips.split(" ")
1469
 
1470
        for ip in ips:
4310 rajveer 1471
            try:
1472
                top_level_url = "http://" + ip + ":8080/"
1473
                password_mgr.add_password(None, top_level_url, "saholic", "shop2020")
1474
                handler = urllib2.HTTPBasicAuthHandler(password_mgr)
3924 rajveer 1475
 
4310 rajveer 1476
                opener = urllib2.build_opener(handler)
3924 rajveer 1477
 
4310 rajveer 1478
                # use the opener to fetch a URL
1479
                res = opener.open(top_level_url + "cache-admin/HomePageSnippets?_method=delete")
1480
                print "Successfully cleared home page cache" + res.read()
1481
            except:
1482
                print "Unable to clear home page cache" + res.read()
3924 rajveer 1483
    except:
1484
        print "Unable to clear cache, still should continue with other operations"
4024 chandransh 1485
 
4062 chandransh 1486
def get_pending_orders_inventory(vendor_id=1):
4024 chandransh 1487
    """
1488
    Returns a list of inventory stock for items for which there are pending orders.
1489
    """
4341 rajveer 1490
 
4368 rajveer 1491
    warehouse_ids = [warehouse.id for warehouse in get_warehouses_for_vendor(vendor_id)]
4064 chandransh 1492
    pending_items_inventory = []
1493
    if warehouse_ids:
1494
        pending_items_inventory = session.query(CurrentInventorySnapshot.item_id, func.sum(CurrentInventorySnapshot.availibility), func.sum(CurrentInventorySnapshot.reserved)).filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).group_by(CurrentInventorySnapshot.item_id).having(func.sum(CurrentInventorySnapshot.reserved) > 0).all()
4024 chandransh 1495
    return pending_items_inventory
4295 varun.gupt 1496
 
1497
def get_product_notifications(start_datetime):
1498
    '''
1499
    Returns a list of Product Notification objects each representing user requests for notification
1500
    '''
1501
    query = ProductNotification.query
3924 rajveer 1502
 
4295 varun.gupt 1503
    if start_datetime:
1504
        query = query.filter(ProductNotification.addedOn > start_datetime)
1505
 
1506
    notifications = query.order_by(desc('addedOn')).all()
1507
    return notifications
1508
 
1509
def get_product_notification_request_count(start_datetime):
1510
    '''
1511
    Returns list of items and the counts of product notification requests
1512
    '''
1513
    print start_datetime
1514
    query = session.query(ProductNotification, func.count(ProductNotification.email).label('count'))
1515
 
1516
    if start_datetime:
1517
        query = query.filter(ProductNotification.addedOn > start_datetime)
1518
 
1519
    counts = query.group_by(ProductNotification.item_id).order_by(desc('count')).all()
1520
    return counts
1521
 
766 rajveer 1522
def close_session():
1523
    if session.is_active:
1524
        print "session is active. closing it."
1399 rajveer 1525
        session.close()
3376 rajveer 1526
 
1527
def is_alive():
1528
    try:
1529
        session.query(Item.id).limit(1).one()
1530
        return True
1531
    except:
1532
        return False
4332 anupam.sin 1533
 
1534
def add_vendor(vendor):
1535
    if not vendor:
1536
        raise InventoryServiceException(108, "Bad vendor")
1537
    if get_Vendor(vendor.id):
1538
        #vendor is already present.
1539
        raise InventoryServiceException(101, "Vendor already present")
1540
 
1541
    ds_vendor = Vendor()
1542
    ds_vendor.id = vendor.id
1543
    ds_vendor.name = vendor.name
1544
    session.commit()
1545
    return ds_vendor.id
1546
 
1547
def add_warehouse_vendor_mapping(warehouse_id, VendorId):
1548
    return True
1549
 
1550
def get_vendors_for_warehouse(warehouse_id):
1551
    try:
1552
        warehouse = Warehouse.get_by(id=warehouse_id)
1553
        return warehouse.vendors
1554
    except:
1555
        raise InventoryServiceException(108, "Bad Warehouse Id")
1556
 
1557
def get_warehouses_for_vendor(vendorId):
1558
    try:
1559
        vendor = get_Vendor(vendorId)
1560
        return vendor.warehouses
1561
    except:
4649 phani.kuma 1562
        raise InventoryServiceException(108, "Bad Vendor Id")
1563
 
1564
def add_authorization_log_for_item(itemId, username, reason):
1565
    if not itemId or not username:
1566
        raise InventoryServiceException(101, "Bad itemId or Invalid username in request")
1567
    authorize_log = AuthorizationLog()
1568
    authorize_log.item_id = itemId
1569
    authorize_log.username = username
1570
    authorize_log.reason = reason
1571
    session.commit()
1572
    return True