Subversion Repositories SmartDukaan

Rev

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