Subversion Repositories SmartDukaan

Rev

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