Subversion Repositories SmartDukaan

Rev

Rev 3467 | Rev 3503 | 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 *
7
from shop2020.model.v1.catalog.impl import DataService
122 ashish 8
from shop2020.model.v1.catalog.impl.DataService import Item, \
103 ashish 9
    Warehouse, ItemInventoryHistory, CurrentInventorySnapshot, ItemInfo,\
1368 chandransh 10
    ItemChangeLog, Category, EntityIDGenerator, VendorItemPricing,\
3079 rajveer 11
    VendorItemMapping, Vendor, SimilarItems, ProductNotification
122 ashish 12
from shop2020.thriftpy.model.v1.catalog.ttypes import \
2983 chandransh 13
    InventoryServiceException, status, ItemShippingInfo
2065 ankur.sing 14
from shop2020.model.v1.catalog.impl.Convertors import to_t_item,\
15
    to_t_vendor_item_pricing
94 ashish 16
import datetime
871 chandransh 17
import sys
2286 ankur.sing 18
from shop2020.utils.Utils import log_entry, to_py_date, log_risky_flag
621 chandransh 19
from sqlalchemy import desc, asc
3244 chandransh 20
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
1970 rajveer 21
from shop2020.model.v1.catalog.impl.CategoryManager import CategoryManager
2404 chandransh 22
from sqlalchemy.sql.expression import and_, distinct, func
3086 rajveer 23
from string import Template
24
from shop2020.clients.HelperClient import HelperClient
94 ashish 25
 
26
def initialize():
27
    DataService.initialize()
28
 
29
 
103 ashish 30
def get_all_items(is_active):
31
    if is_active:
766 rajveer 32
        items = Item.query.filter_by(status= status.ACTIVE).all()
103 ashish 33
    else:
766 rajveer 34
        items = Item.query.all()
35
    return items
36
 
103 ashish 37
def get_all_items_by_status(status):
2174 ankur.sing 38
    if status == None:
103 ashish 39
        #return all items
766 rajveer 40
        items = get_all_items(False)
103 ashish 41
    else:
766 rajveer 42
        items = Item.query.filter_by(status=status).all()
43
    return items
103 ashish 44
 
635 rajveer 45
def get_item(item_id):
766 rajveer 46
    item = Item.get_by(id=item_id)
47
    return item
94 ashish 48
 
635 rajveer 49
def get_items_by_catalog_id(catalog_id):
447 rajveer 50
    query = Item.query.filter_by(catalog_item_id=catalog_id)
437 rajveer 51
    try:
635 rajveer 52
        items = query.all()
53
        return get_thrift_item_list(items)
1399 rajveer 54
    except Exception as ex:
55
        print ex
437 rajveer 56
        raise InventoryServiceException(109, "Item not found")
57
 
576 chandransh 58
def is_active(item_id):
2983 chandransh 59
    t_item_shipping_info = ItemShippingInfo()
576 chandransh 60
    try:
635 rajveer 61
        item = get_item(item_id)
3281 chandransh 62
        t_item_shipping_info.isRisky = item.risky
63
        availability = __get_item_availability(item)
64
        if item.risky and availability <= 0 and item.status == status.ACTIVE:
65
            add_status_change_log(item, status.PAUSED_BY_RISK)
66
            item.status = status.PAUSED_BY_RISK
67
            item.status_description = "This item is currently out of stock"
68
            session.commit()
2983 chandransh 69
        t_item_shipping_info.isActive = (item.status == status.ACTIVE)
3281 chandransh 70
        t_item_shipping_info.quantity = availability
576 chandransh 71
    except InventoryServiceException:
2983 chandransh 72
        print "[ERROR] Unexpected error:", sys.exc_info()[0]
73
    return t_item_shipping_info
74
 
2035 rajveer 75
def get_item_status_description(itemId):
76
    item = get_item(itemId)
77
    return item.status_description
563 chandransh 78
 
94 ashish 79
def get_Warehouse(warehouse_id):
80
    return Warehouse.get_by(id=warehouse_id)
81
 
122 ashish 82
def get_all_warehouses_by_status(status):
83
    if not status:
766 rajveer 84
        warehouses = Warehouse.query.all()
122 ashish 85
    else:
851 chandransh 86
        warehouses = Warehouse.query.filter_by(status=status).all()
87
    return warehouses
122 ashish 88
 
94 ashish 89
def get_all_warehouses_for_item(item_id):
635 rajveer 90
    item = get_item(item_id)
94 ashish 91
    if not item:
122 ashish 92
        raise InventoryServiceException(108, "Some unforeseen error while obtaining item")
93
    return item.get_all_warehouses
94 ashish 94
 
122 ashish 95
def get_all_items_for_warehouse(warehouse_id):
96
    warehouse = get_Warehouse(warehouse_id)
97
    if not warehouse:
98
        raise InventoryServiceException(108, "bad warehouse")
99
    return warehouse.all_items
100
 
94 ashish 101
def add_warehouse(warehouse):
103 ashish 102
    if not warehouse:
122 ashish 103
        raise InventoryServiceException(108, "Bad warehouse")
103 ashish 104
    if get_Warehouse(warehouse.id):
105
        #warehouse is already present.
122 ashish 106
        raise InventoryServiceException(101, "Warehouse already present")
103 ashish 107
 
94 ashish 108
    ds_warehouse = Warehouse()
109
    ds_warehouse.id = warehouse.id
110
    ds_warehouse.location = warehouse.location
122 ashish 111
    ds_warehouse.status = status.ACTIVE
103 ashish 112
    ds_warehouse.addedOn = datetime.datetime.now()
483 rajveer 113
    ds_warehouse.lastCheckedOn = datetime.datetime.now()
114
    ds_warehouse.tinNumber = warehouse.tinNumber
115
    ds_warehouse.pincode = warehouse.pincode
116
    if warehouse.vendorString:
117
        ds_warehouse.vendorString = warehouse.vendorString
94 ashish 118
    session.commit()
103 ashish 119
    return ds_warehouse.id
94 ashish 120
 
122 ashish 121
def update_item(item):
122
    if not item:
123
        raise InventoryServiceException(108, "Bad item in request")
124
 
125
    if not item.id:
609 chandransh 126
        raise InventoryServiceException(101, "Missing id for update")
122 ashish 127
 
2120 ankur.sing 128
    validate_item_prices(item)
2065 ankur.sing 129
 
635 rajveer 130
    ds_item = get_item(item.id)
122 ashish 131
 
132
    if not ds_item:
609 chandransh 133
        raise InventoryServiceException(101, "Item missing in our database")
122 ashish 134
 
963 chandransh 135
    if item.productGroup:
136
        ds_item.product_group = item.productGroup 
137
    if item.brand:
138
        ds_item.brand = item.brand
511 rajveer 139
    if item.modelNumber:
140
        ds_item.model_number = item.modelNumber
2497 ankur.sing 141
    ds_item.color = item.color
142
    ds_item.model_name = item.modelName
143
    ds_item.category = item.category
144
    ds_item.comments = item.comments
511 rajveer 145
 
2497 ankur.sing 146
    ds_item.catalog_item_id = item.catalogItemId
483 rajveer 147
 
2129 ankur.sing 148
    ds_item.mrp = item.mrp
149
    ds_item.sellingPrice = item.sellingPrice
2497 ankur.sing 150
 
2174 ankur.sing 151
    ds_item.weight = item.weight
2129 ankur.sing 152
 
2358 ankur.sing 153
    if ds_item.status != item.itemStatus:
2402 rajveer 154
        add_status_change_log(ds_item, item.itemStatus)
2358 ankur.sing 155
        ds_item.status = item.itemStatus
2035 rajveer 156
    if item.status_description:
157
        ds_item.status_description = item.status_description
122 ashish 158
 
511 rajveer 159
    if item.startDate:
2116 ankur.sing 160
        ds_item.startDate = to_py_date(item.startDate)
2497 ankur.sing 161
    else:
162
        ds_item.startDate = None
511 rajveer 163
    if item.retireDate:
2116 ankur.sing 164
        ds_item.retireDate = to_py_date(item.retireDate)
2497 ankur.sing 165
    else:
166
        ds_item.retireDate = None
511 rajveer 167
 
2497 ankur.sing 168
    ds_item.feature_id = item.featureId
169
    ds_item.feature_description = item.featureDescription
122 ashish 170
 
2129 ankur.sing 171
    ds_item.bestDealText = item.bestDealText
172
    ds_item.bestDealValue = item.bestDealValue
2065 ankur.sing 173
    ds_item.bestSellingRank = item.bestSellingRank
2497 ankur.sing 174
 
2065 ankur.sing 175
    ds_item.defaultForEntity = item.defaultForEntity
2251 ankur.sing 176
    ds_item.risky = item.risky
3359 chandransh 177
 
3459 chandransh 178
    if item.expectedDelay is not None:
3359 chandransh 179
        ds_item.expectedDelay = item.expectedDelay
180
 
181
    if item.preferredWarehouse:
182
        ds_item.preferredWarehouse = item.preferredWarehouse
183
 
2347 ankur.sing 184
    ds_item.updatedOn = datetime.datetime.now()
2065 ankur.sing 185
 
122 ashish 186
    session.commit();
187
    return ds_item.id
94 ashish 188
 
2116 ankur.sing 189
def check_vendor_item_mapping(product_group, brand, model_number, color, vendor_id, vendor_category):
190
    key = product_group.strip().lower() + '|' + brand.strip().lower() + '|' + model_number.strip().lower() + '|' + color.strip().lower()
191
    try:
192
        vim = VendorItemMapping.query.filter_by(vendor_id=vendor_id, item_key=key, vendor_category=vendor_category).one()
193
        return True
194
    except:
195
        return False
196
 
103 ashish 197
def add_item(item):
198
    if not item:
122 ashish 199
        raise InventoryServiceException(108, "Bad item in request")
635 rajveer 200
    if get_item(item.id):
122 ashish 201
        raise InventoryServiceException(101, "Item already exists")
2120 ankur.sing 202
 
203
    validate_item_prices(item)
204
 
103 ashish 205
    ds_item = Item()
963 chandransh 206
    if item.productGroup:
207
        ds_item.product_group = item.productGroup
208
    if item.brand:
209
        ds_item.brand = item.brand
515 rajveer 210
    if item.modelName:
211
        ds_item.model_name = item.modelName
212
    if item.modelNumber:
213
        ds_item.model_number = item.modelNumber
609 chandransh 214
    if item.color:
215
        ds_item.color = item.color
2116 ankur.sing 216
    if item.hotspotCategory:
217
        ds_item.hotspotCategory = item.hotspotCategory
218
        if item.hotspotCategory == 'Handsets':
2403 ankur.sing 219
            ds_item.preferredWarehouse = 1
2116 ankur.sing 220
        else:
2403 ankur.sing 221
            ds_item.preferredWarehouse = 2
2116 ankur.sing 222
 
483 rajveer 223
    if item.category:
224
        ds_item.category = item.category
225
    if item.comments:
226
        ds_item.comments = item.comments
227
 
103 ashish 228
    ds_item.addedOn = datetime.datetime.now()
609 chandransh 229
    ds_item.updatedOn = datetime.datetime.now()
2116 ankur.sing 230
    if item.startDate:
231
        ds_item.startDate = to_py_date(item.startDate)
232
    if item.retireDate:
233
        ds_item.retireDate = to_py_date(item.retireDate)
609 chandransh 234
 
483 rajveer 235
    if item.mrp:
236
        ds_item.mrp = item.mrp
237
    if item.sellingPrice:
238
        ds_item.sellingPrice = item.sellingPrice
122 ashish 239
    if item.weight:
240
        ds_item.weight = item.weight
241
 
242
    if item.featureId:
243
        ds_item.feature_id = item.featureId
244
    if item.featureDescription:
245
        ds_item.feature_description = item.featureDescription
246
 
103 ashish 247
    if item.otherInfo:
248
        for k,v in item.otherInfo.iteritems():
249
            info = ItemInfo()
250
            info.key = k
251
            info.value = v
252
            ds_item.iteminfo.append(info)
2116 ankur.sing 253
 
103 ashish 254
    #check if categories present. If yes, add them to system
122 ashish 255
 
609 chandransh 256
    if item.bestDealValue:
257
        ds_item.bestDealValue = item.bestDealValue
258
    if item.bestDealText:
259
        ds_item.bestDealText = item.bestDealText
2116 ankur.sing 260
    if item.bestSellingRank:
261
        ds_item.bestSellingRank = item.bestSellingRank
262
    ds_item.defaultForEntity = item.defaultForEntity
2251 ankur.sing 263
    ds_item.risky = item.risky
609 chandransh 264
 
3467 chandransh 265
    if item.expectedDelay is not None:
3359 chandransh 266
        ds_item.expectedDelay = item.expectedDelay
3467 chandransh 267
    else:
268
        ds_item.expectedDelay = 0
3359 chandransh 269
 
270
    if item.preferredWarehouse:
271
        ds_item.preferredWarehouse = item.preferredWarehouse
272
 
2116 ankur.sing 273
    # Check if a similar item already exists in our database
274
    similar_item = Item.query.filter_by(product_group=item.productGroup, brand = item.brand, model_number=item.modelNumber, hotspotCategory=item.hotspotCategory).first()
275
    print "[SIMILAR ITEM FOUND:] FOR {0} {1} {2} {3} {4}".format(item.productGroup, item.brand, item.modelNumber, item.hotspotCategory, item.color)
276
 
277
    if similar_item is None or similar_item.catalog_item_id is None:
278
        # If there is no similar item in the database from before,
279
        # use the entity_id_generator
280
        entity_id = EntityIDGenerator.query.first()
281
        ds_item.catalog_item_id = entity_id.id + 1
282
        ds_item.status = status.IN_PROCESS
283
        ds_item.status_description = "This item is in process."
284
        entity_id.id = entity_id.id  + 1
285
    else:
286
        #If a similar item already exists for a product group, brand and model_number, set it as same.
287
        ds_item.catalog_item_id = similar_item.catalog_item_id
288
        ds_item.category = similar_item.category
289
        ds_item.status = similar_item.status
290
        ds_item.status_description = similar_item.status_description
291
 
103 ashish 292
    session.commit();
3325 chandransh 293
    return ds_item.id
294
 
295
def update_inventory_history(warehouse_id, timestamp, availability):
296
    warehouse = get_Warehouse(warehouse_id)
297
    if not warehouse:
298
        raise InventoryServiceException(107, "Warehouse? Where?")
299
    vendor = warehouse.vendor 
300
    time = datetime.datetime.now()
301
    for item_key, quantity in availability.iteritems():
302
        try:
303
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
304
            item = vendor_item_mapping.item
305
        except:
306
            continue  
307
        try:
308
            item_inventory_history = ItemInventoryHistory()
309
            item_inventory_history.warehouse = warehouse
310
            item_inventory_history.item = item
311
            item_inventory_history.timestamp = time
312
            item_inventory_history.availibility = quantity
313
        except:
314
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
315
    session.commit()
103 ashish 316
 
483 rajveer 317
def update_inventory(warehouse_id, timestamp, availability):
318
    warehouse = get_Warehouse(warehouse_id)
319
    if not warehouse:
320
        raise InventoryServiceException(107, "Warehouse? Where?")
321
 
322
    time = datetime.datetime.now()
323
    warehouse.lastCheckedOn = time
324
    warehouse.vendorString = timestamp
1368 chandransh 325
    vendor = warehouse.vendor
2368 ankur.sing 326
    session.commit()
1368 chandransh 327
    for item_key, quantity in availability.iteritems():
483 rajveer 328
        try:
1368 chandransh 329
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
330
            item = vendor_item_mapping.item
494 rajveer 331
        except:
332
            continue  
333
        try:
483 rajveer 334
            current_inventory_snapshot = CurrentInventorySnapshot.get_by(item=item, warehouse=warehouse)
335
            if not current_inventory_snapshot:
336
                current_inventory_snapshot = CurrentInventorySnapshot()
337
                current_inventory_snapshot.item = item
338
                current_inventory_snapshot.warehouse = warehouse
339
                current_inventory_snapshot.availibility = 0
871 chandransh 340
                current_inventory_snapshot.reserved = 0
483 rajveer 341
            # added the difference in the current inventory    
342
            current_inventory_snapshot.availibility = current_inventory_snapshot.availibility + quantity
343
        except:
344
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
2368 ankur.sing 345
        session.commit() 
346
        check_risky_item(item)
483 rajveer 347
 
94 ashish 348
def get_item_inventoy(item_id):
349
 
350
    inventory = Item.get_by(id=item_id).currentInventory
351
    if not inventory:
122 ashish 352
        raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
94 ashish 353
    return inventory
354
 
635 rajveer 355
def get_item_inventory_by_item_id(item_id):
356
    inventory = Item.get_by(id=item_id).currentInventory
379 ashish 357
    if not inventory:
358
        raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
359
    return inventory
360
 
103 ashish 361
 
362
def retire_warehouse(warehouse_id):
363
    if not warehouse_id:
122 ashish 364
        raise InventoryServiceException(101, "Bad warehouse id")
103 ashish 365
    warehouse = get_Warehouse(warehouse_id)
366
    if not warehouse:
122 ashish 367
        raise InventoryServiceException(108, "warehouse id not present")
368
    warehouse.status = status.DELETED;
103 ashish 369
    session.commit()
370
 
371
def retire_item(item_id):
372
    if not item_id:
122 ashish 373
        raise InventoryServiceException(101, "bad item id")
635 rajveer 374
    item = get_item(item_id)
103 ashish 375
    if not item:
122 ashish 376
        raise InventoryServiceException(108, "item id not present")
377
    item.status = status.PHASED_OUT
378
    item.retireDate = datetime.datetime.now()
103 ashish 379
    session.commit()
122 ashish 380
 
381
#need to implement threads based solution here
103 ashish 382
def start_item_on(item_id, timestamp):
383
    if not item_id:
122 ashish 384
        raise InventoryServiceException(101, "bad item id")
635 rajveer 385
    item = get_item(item_id)
103 ashish 386
    if not item:
122 ashish 387
        raise InventoryServiceException(108, "item id not present")
103 ashish 388
 
122 ashish 389
    item.status = status.ACTIVE
390
    item.startDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))
391
    add_status_change_log(item, status.ACTIVE)
103 ashish 392
    session.commit()
393
 
122 ashish 394
#need to implement threads here
103 ashish 395
def retire_item_on(item_id, timestamp):
396
    if not item_id:
122 ashish 397
        raise InventoryServiceException(101, "bad item id")
635 rajveer 398
    item = get_item(item_id)
103 ashish 399
    if not item:
122 ashish 400
        raise InventoryServiceException(108, "item id not present")
103 ashish 401
 
122 ashish 402
    item.status = status.PHASED_OUT
403
    item.retireDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))
404
    add_status_change_log(item, status.PHASED_OUT)
103 ashish 405
    session.commit()
406
 
407
def add_status_change_log(item, new_status):
408
    item_change_log = ItemChangeLog()
409
    item_change_log.new_status = new_status
410
    item_change_log.old_status = item.status
411
    item_change_log.timestamp = datetime.datetime.now()
412
    item_change_log.item = item
413
    session.commit()
414
 
415
def change_item_status(item_id, new_status):
416
    if not item_id:
122 ashish 417
        raise InventoryServiceException(101, "bad item id")
635 rajveer 418
    item = get_item(item_id)
103 ashish 419
    if not item:
122 ashish 420
        raise InventoryServiceException(108, "item id not present")
2116 ankur.sing 421
    add_status_change_log(item, new_status)
122 ashish 422
    item.status = new_status
2251 ankur.sing 423
    if item.status == status.PHASED_OUT:
424
        item.status_description = "This item has been phased out"
425
    elif item.status == status.DELETED:
426
        item.status_description = "This item has been deleted"
2984 rajveer 427
    elif item.status == status.PAUSED or item.status == status.PAUSED_BY_RISK:
2251 ankur.sing 428
        item.status_description = "This item is currently out of stock"        
429
    elif item.status == status.ACTIVE:
430
        item.status_description = "This item is active"
431
    elif item.status == status.IN_PROCESS:
432
        item.status_description = "This item is in process"
433
    elif item.status == status.CONTENT_COMPLETE:
434
        item.status_description = "This item is in process"
103 ashish 435
    session.commit()
436
 
437
def get_item_availability_for_warehouse(warehouse_id, item_id):
438
    if not warehouse_id:
122 ashish 439
        raise InventoryServiceException(101, "bad warehouse_id")
103 ashish 440
    if not item_id:
122 ashish 441
        raise InventoryServiceException(101, "bad item_id")
103 ashish 442
 
443
    warehouse = get_Warehouse(warehouse_id)
444
    if not warehouse:
122 ashish 445
        raise InventoryServiceException(108, "warehouse does not exist")
635 rajveer 446
    item = get_item(item_id)
504 rajveer 447
 
103 ashish 448
    if not item:
766 rajveer 449
        raise InventoryServiceException(108, "item does not exist")
122 ashish 450
 
494 rajveer 451
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id)
504 rajveer 452
    query = query.filter_by(item_id = item.id)
494 rajveer 453
    try:
454
        current_inventory_snapshot = query.one()
871 chandransh 455
        return current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
494 rajveer 456
    except:
457
        return 0
458
    """
459
    current_inventory_snapshot = CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id == warehouse_id, CurrentInventorySnapshot.item_id == item_id).one()
103 ashish 460
    if not current_inventory_snapshot:
461
        return 0
462
    else:
463
        return current_inventory_snapshot.availibility
494 rajveer 464
    """
643 chandransh 465
 
2368 ankur.sing 466
def check_risky_item(item):
2251 ankur.sing 467
    if not item.risky:
468
        return
2983 chandransh 469
    availability = __get_item_availability(item)
470
    if availability <= 0:
2251 ankur.sing 471
        if item.status == status.ACTIVE:
2984 rajveer 472
            change_item_status(item.id, status.PAUSED_BY_RISK)
2251 ankur.sing 473
    else:
2984 rajveer 474
        if item.status == status.PAUSED_BY_RISK:
2251 ankur.sing 475
            change_item_status(item.id, status.ACTIVE)
2368 ankur.sing 476
    session.commit()
2251 ankur.sing 477
 
2983 chandransh 478
def __get_item_availability(item):
479
    all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
480
    availability = 0
481
    reserved = 0
482
    for currInv in all_inventory:
483
        availability = availability + currInv.availibility
484
        reserved = reserved + currInv.reserved
485
    return availability - reserved
486
 
871 chandransh 487
def reserve_item_in_warehouse(item_id, warehouse_id, quantity):    
488
    if not warehouse_id:
489
        raise InventoryServiceException(101, "bad warehouse_id")
2251 ankur.sing 490
    item = get_item(item_id)
491
    if not item:
871 chandransh 492
        raise InventoryServiceException(101, "bad item_id")
493
 
494
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
495
    try:
496
        current_inventory_snapshot = query.one()
497
        current_inventory_snapshot.reserved = current_inventory_snapshot.reserved + quantity
498
        session.commit()
2368 ankur.sing 499
        check_risky_item(item)
871 chandransh 500
        return True
501
    except:
502
        print "Unexpected error:", sys.exc_info()[0]
503
        return False
504
 
505
def reduce_reservation_count(item_id, warehouse_id, quantity):
506
    if not warehouse_id:
507
        raise InventoryServiceException(101, "bad warehouse_id")
2251 ankur.sing 508
    item = get_item(item_id)
509
    if not item:
871 chandransh 510
        raise InventoryServiceException(101, "bad item_id")
511
 
512
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
513
    try:
514
        current_inventory_snapshot = query.one()
515
        current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
516
        session.commit()
2368 ankur.sing 517
        check_risky_item(item)
871 chandransh 518
        return True
519
    except:
520
        print "Unexpected error:", sys.exc_info()[0]
521
        return False
522
 
2075 rajveer 523
def mark_item_as_content_complete(entity_id, category, brand, modelName, modelNumber):
2828 rajveer 524
    '''
525
    Get all the items for this entityID and update category, brand, modelName and modelNumber for all.
526
    Update Status for only IN_PROCESS items to CONTENT_COMPLETE
527
    '''
723 chandransh 528
    content_complete_status = status.CONTENT_COMPLETE
2828 rajveer 529
    items = Item.query.filter_by(catalog_item_id=entity_id).all()
723 chandransh 530
    current_timestamp = datetime.datetime.now()
531
    for item in items:
2828 rajveer 532
        if item.status == status.IN_PROCESS:
533
            item.status = content_complete_status
534
            item_change_log = ItemChangeLog()
535
            item_change_log.old_status = item.status
536
            item_change_log.new_status = content_complete_status
537
            item_change_log.timestamp = current_timestamp
538
            item_change_log.item = item
723 chandransh 539
 
2075 rajveer 540
        item.category = category
541
        item.brand = brand
2081 rajveer 542
        item.model_name = modelName
543
        item.model_number = modelNumber
723 chandransh 544
        item.updatedOn = current_timestamp
545
    session.commit()
546
    return True
1294 chandransh 547
 
643 chandransh 548
def get_item_availability_for_location(warehouse_loc, item_id):
3355 chandransh 549
    """
550
    Determines the warehouse that should be used to fulfil an order for the given item.
551
    It first checks all the warehouses which are in the logistics location given by the
552
    warehouse_loc parameter. If none of the warehouses there have any inventory, then the
553
    preferred warehouse for the item is used.
554
 
555
    Returns an ordered list of size 4 with following elements in the given order:
556
    1. Logistics location of the warehouse which was finally picked up to ship the order.
557
    2. Id of the warehouse which was finally picked up.
558
    3. Inventory size in the selected warehouse.
559
    4. Expected delay added by the category manager.
560
 
561
    Parameters:
562
     - warehouse_loc
563
     - item_id
564
    """
643 chandransh 565
    if warehouse_loc is None:
566
        raise InventoryServiceException(101, "Bad Warehouse Location")
567
    if not item_id:
1416 chandransh 568
        raise InventoryServiceException(101, "Bad Item id")
643 chandransh 569
 
1416 chandransh 570
    item = Item.get_by(id=item_id)
3355 chandransh 571
 
572
    #First try all warehouses in the suggested location.
643 chandransh 573
    warehouses = Warehouse.query.filter_by(logisticsLocation=warehouse_loc).all()
574
    warehouse_ids = [warehouse.id for warehouse in warehouses]
575
    warehouse_retid = -1
576
    global_availability = 0
577
    for warehouse_id in warehouse_ids:
785 rajveer 578
        try:
871 chandransh 579
            current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).one()
580
            availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
785 rajveer 581
        except:
582
            availability = 0    
643 chandransh 583
        if availability > global_availability:
584
            warehouse_retid = warehouse_id
585
            global_availability = availability
2341 chandransh 586
 
3355 chandransh 587
    #If no warehouse could be found, use the preferred warehouse for this item
643 chandransh 588
    if warehouse_retid == -1:
759 chandransh 589
        # This is the case when all warehouses have exhausted their
590
        # inventory of this item or no warehouse is available in this
591
        # location.
1416 chandransh 592
        warehouse_retid = int(item.preferredWarehouse)
2344 chandransh 593
        warehouse = Warehouse.get_by(id=warehouse_retid)
2341 chandransh 594
        try:
595
            current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_retid, item_id = item_id).one()
596
            global_availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
597
        except:
598
            global_availability = 0
643 chandransh 599
 
3355 chandransh 600
    return [warehouse.logisticsLocation, warehouse_retid, global_availability, item.expectedDelay]
2341 chandransh 601
 
122 ashish 602
def get_warehouses_for_item(item_id):
643 chandransh 603
 
122 ashish 604
    if not item_id:
605
        raise InventoryServiceException(101, "bad item_id")
635 rajveer 606
    item = get_item(item_id)
122 ashish 607
 
608
    if not item:
609
        raise InventoryServiceException(101, "bad item")
610
 
483 rajveer 611
    warehouses = item.currentInventory.warehouse
501 rajveer 612
    return warehouses
613
 
2404 chandransh 614
def get_child_categories(category):
615
    cm = CategoryManager()
2621 varun.gupt 616
    cat = cm.getCategory(category)
617
    return cat.children_category_ids if cat else None
2404 chandransh 618
 
626 chandransh 619
def get_best_sellers(start_index, stop_index, category=-1):
2404 chandransh 620
    '''
621
    Returns the Best Sellers between the start and the stop index in the given category
622
    '''
1926 rajveer 623
    query = get_best_sellers_query(category, None)
1098 chandransh 624
    best_sellers = query.all()[start_index:stop_index]
621 chandransh 625
    return get_thrift_item_list(best_sellers)
626
 
2093 chandransh 627
def get_best_sellers_count(category=-1):
2404 chandransh 628
    '''
629
    Returns the number of best sellers in the given category
630
    '''
1926 rajveer 631
    count = get_best_sellers_query(category, None).count()
1120 rajveer 632
    if count is None:
633
        count = 0
766 rajveer 634
    return count
621 chandransh 635
 
1926 rajveer 636
def get_best_sellers_catalog_ids(start_index, stop_index, brand, category=-1):
2404 chandransh 637
    '''
638
    Returns the Best sellers for the given brand and category between the start and the stop index.
639
    Ignores the category if it's passed as -1 and the brand if it's passed as None. 
640
    '''
1926 rajveer 641
    query = get_best_sellers_query(category, brand)
1098 chandransh 642
    best_sellers = query.all()[start_index:stop_index]
621 chandransh 643
    return [item.catalog_item_id for item in best_sellers]
1970 rajveer 644
 
1926 rajveer 645
def get_best_sellers_query(category, brand):
2404 chandransh 646
    '''
647
    Returns the query to be used for getting Best Sellers.
648
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
649
    '''
1098 chandransh 650
    query = Item.query.filter_by(status=status.ACTIVE).filter(Item.bestSellingRank != None)
626 chandransh 651
    if category != -1:
1970 rajveer 652
        all_categories = [category]
653
        child_categories = get_child_categories(category)
654
        if child_categories is not None:
655
            all_categories = all_categories + child_categories 
656
        query = query.filter(Item.category.in_(all_categories))
1926 rajveer 657
    if brand is not None:
658
        query = query.filter_by(brand=brand)
1098 chandransh 659
    query = query.order_by(asc(Item.bestSellingRank))
621 chandransh 660
    return query
609 chandransh 661
 
1098 chandransh 662
def get_best_deals(category=-1):
2404 chandransh 663
    '''
664
    Returns the Best deals in the given category. Ignores the category if it's passed as -1.
665
    '''
666
    query = get_best_deals_query(Item, category, None)
1098 chandransh 667
    items = query.all()
609 chandransh 668
    return get_thrift_item_list(items)
669
 
1098 chandransh 670
def get_best_deals_count(category=-1):
2404 chandransh 671
    '''
672
    Returns the count of best deals in the given category.
673
    Ignores the category if it's -1.
674
    '''
675
    count = get_best_deals_counting_query(func.count(distinct(Item.catalog_item_id)), category, None).scalar()
1120 rajveer 676
    if count is None:
677
        count = 0
766 rajveer 678
    return count
501 rajveer 679
 
1926 rajveer 680
def get_best_deals_catalog_ids(start_index, stop_index, brand, category=-1):
2404 chandransh 681
    '''
682
    Returns the catalog_item_ids of best deal items for the given brand and category.
683
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
684
    '''
685
    query = get_best_deals_query(Item, category, brand)
1098 chandransh 686
    best_deal_items = query.all()[start_index:stop_index]
687
    return [item.catalog_item_id for item in best_deal_items]
688
 
2404 chandransh 689
def get_best_deals_counting_query(obj, category, brand):
690
    '''
691
    Returns the query to be used to select the best deals in the given brand and category.
692
    Ignores the category if it's passed as -1 and the brand if it's passed as None. 
693
    '''
694
    query = session.query(obj).filter_by(status=status.ACTIVE).filter(Item.bestDealValue != None)
626 chandransh 695
    if category != -1:
1970 rajveer 696
        all_categories = [category]
697
        child_categories = get_child_categories(category)
698
        if child_categories is not None:
699
            all_categories = all_categories + child_categories 
700
        query = query.filter(Item.category.in_(all_categories))
1926 rajveer 701
    if brand is not None:
702
        query = query.filter_by(brand=brand)
2404 chandransh 703
    return query
704
 
705
def get_best_deals_query(obj, category, brand):
706
    '''
707
    Returns the query to be used to get the best deals in the given category and brand.
708
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
709
    '''
710
    query = get_best_deals_counting_query(obj, category, brand)
1098 chandransh 711
    query = query.group_by(Item.catalog_item_id).order_by(desc(Item.bestDealValue))
712
    return query
609 chandransh 713
 
1098 chandransh 714
def get_latest_arrivals(limit, category=-1):
2404 chandransh 715
    '''
716
    Returns up to limit number of Latest Arrivals in the given category.
717
    '''
2975 chandransh 718
    categories = []
719
    if category != -1:
720
        categories = [category]
721
    query = get_latest_arrivals_query(Item, categories, None)
1098 chandransh 722
    items = query.all()[0:limit]
609 chandransh 723
    return get_thrift_item_list(items)
598 chandransh 724
 
1098 chandransh 725
def get_latest_arrivals_count(limit, category=-1):
2404 chandransh 726
    '''
727
    Returns the number of latest arrivals which will be displayed on the website.
3016 chandransh 728
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 729
    '''
2975 chandransh 730
    categories = []
731
    if category != -1:
732
        categories = [category]
733
    count = get_latest_arrivals_counting_query(func.count(distinct(Item.catalog_item_id)), categories, None).scalar()
1120 rajveer 734
    if count is None:
735
        count = 0
736
    count = min(count, limit)
766 rajveer 737
    return count
602 chandransh 738
 
2975 chandransh 739
def get_latest_arrivals_catalog_ids(start_index, stop_index, brand, categories=[]):
2404 chandransh 740
    '''
741
    Returns the catalog_item_ids of the latest arrivals between the start and the stop index
3016 chandransh 742
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 743
    '''
2975 chandransh 744
    query = get_latest_arrivals_query(Item, categories, brand)
1098 chandransh 745
    latest_arrivals = query.all()[start_index:stop_index]
746
    return [item.catalog_item_id for item in latest_arrivals]
747
 
2975 chandransh 748
def get_latest_arrivals_counting_query(obj, categories, brand):
2404 chandransh 749
    '''
750
    Returns the query to be used to count Latest arrivals.
3016 chandransh 751
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 752
    '''
753
    query = session.query(obj).filter_by(status=status.ACTIVE)
2975 chandransh 754
 
755
    all_categories = []
756
    for category in categories:
757
        all_categories.append(category)
1970 rajveer 758
        child_categories = get_child_categories(category)
2975 chandransh 759
        if child_categories:
760
            all_categories = all_categories + child_categories
761
    if all_categories: 
1970 rajveer 762
        query = query.filter(Item.category.in_(all_categories))
2975 chandransh 763
 
1926 rajveer 764
    if brand is not None:
765
        query = query.filter_by(brand=brand)
2404 chandransh 766
    return query
767
 
2975 chandransh 768
def get_latest_arrivals_query(obj, categories, brand):
2404 chandransh 769
    '''
770
    Returns the query to be used to retrieve Latest Arrivals.
771
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
772
    '''
2975 chandransh 773
    query = get_latest_arrivals_counting_query(obj, categories, brand)
1098 chandransh 774
    query = query.group_by(Item.catalog_item_id).order_by(desc(Item.startDate))
775
    return query
609 chandransh 776
 
777
def get_thrift_item_list(items):
1098 chandransh 778
    return [to_t_item(item) for item in items if item != None]
635 rajveer 779
 
1155 rajveer 780
def generate_new_entity_id():
781
    generator =  EntityIDGenerator.query.one()
782
    id = generator.id + 1
783
    generator.id = id
784
    session.commit()
785
    return id
786
 
635 rajveer 787
def put_category_object(object):
788
    category = Category.get_by(id=1)
789
    if category is None:
790
        category = Category()
791
    category.object = object    
792
    session.commit()
793
    return True
794
 
795
def get_category_object():
766 rajveer 796
    object = Category.get_by(id=1).object
797
    return object
798
 
1341 chandransh 799
def get_item_pricing(item_id, warehouse_id):
800
    item = Item.query.filter_by(id=item_id).first()
801
    if item is None:
802
        raise InventoryServiceException(101, "Bad Item")
803
 
804
    warehouse = get_Warehouse(warehouse_id)
805
    if not warehouse:
806
        raise InventoryServiceException(108, "Bad Warehouse")
807
    vendor = warehouse.vendor
808
 
809
    try:
810
        item_pricing = VendorItemPricing.query.filter_by(vendor=vendor, item=item).one()
1347 chandransh 811
        return item_pricing
3244 chandransh 812
    except MultipleResultsFound:
1341 chandransh 813
        raise InventoryServiceException(110, "Multiple pricing information present for Vendor: " + vendor.name + " and Item: " + str(item_id))
3244 chandransh 814
    except NoResultFound:
1341 chandransh 815
        raise InventoryServiceException(111, "Missing pricing information for Vendor: " + vendor.name + " and Item: " + str(item_id))
816
 
1970 rajveer 817
def add_category(t_category):
818
    category = Category.get_by(id=t_category.id)
819
    if category is None:
820
        category = Category()
821
    category.id = t_category.id 
822
    category.label = t_category.label
823
    category.description = t_category.description
824
    category.parent_category_id = t_category.parent_category_id 
825
    session.commit()
826
    return True
827
 
828
def get_category(id):
829
    return Category.query.filter_by(id=id).first()
830
 
831
def get_all_categories():
832
    return Category.query.all()
833
 
1991 ankur.sing 834
 
835
def get_all_item_pricing(item_id):
836
    item = Item.query.filter_by(id=item_id).first()
837
    if item is None:
838
        raise InventoryServiceException(101, "Bad Item")
839
    item_pricing = VendorItemPricing.query.filter_by(item=item).all()
840
    return item_pricing
841
 
2116 ankur.sing 842
def get_item_mappings(item_id):
843
    item = Item.query.filter_by(id=item_id).first()
844
    if item is None:
845
        raise InventoryServiceException(101, "Bad Item")
846
    item_mappings = VendorItemMapping.query.filter_by(item=item).all()
847
    return item_mappings
848
 
849
def add_vendor_pricing(vendorItemPricing):
1991 ankur.sing 850
    if not vendorItemPricing:
851
        raise InventoryServiceException(108, "Bad vendorItemPricing in request")
852
    vendorId = vendorItemPricing.vendorId
853
    itemId = vendorItemPricing.itemId
854
 
855
    try:
856
        vendor = Vendor.query.filter_by(id=vendorId).one()
857
    except:
858
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
859
 
860
    try:
861
        item = Item.query.filter_by(id=itemId).one()
862
    except:
863
        raise InventoryServiceException(101, "Item not found for vendorId " + str(itemId))
864
 
2120 ankur.sing 865
    validate_vendor_prices(to_t_item(item), vendorItemPricing)
2065 ankur.sing 866
 
1991 ankur.sing 867
    try:
868
        ds_vendorItemPricing = VendorItemPricing.query.filter(and_(VendorItemPricing.vendor==vendor, VendorItemPricing.item==item)).one()
869
    except:
2116 ankur.sing 870
        ds_vendorItemPricing = VendorItemPricing()
871
        ds_vendorItemPricing.vendor = vendor
872
        ds_vendorItemPricing.item = item
1991 ankur.sing 873
 
874
    if vendorItemPricing.mop:
875
        ds_vendorItemPricing.mop = vendorItemPricing.mop
876
    if vendorItemPricing.dealerPrice:
877
        ds_vendorItemPricing.dealerPrice = vendorItemPricing.dealerPrice
878
    if vendorItemPricing.transferPrice:
2065 ankur.sing 879
        ds_vendorItemPricing.transfer_price = vendorItemPricing.transferPrice
1991 ankur.sing 880
 
881
    session.commit()
882
    return
883
 
2358 ankur.sing 884
def add_vendor_item_mapping(key, vendorItemMapping):
2116 ankur.sing 885
    if not vendorItemMapping:
886
        raise InventoryServiceException(108, "Bad vendorItemMapping in request")
887
    vendorId = vendorItemMapping.vendorId
888
    itemId = vendorItemMapping.itemId
889
 
890
    try:
891
        vendor = Vendor.query.filter_by(id=vendorId).one()
892
    except:
893
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
894
 
895
    try:
896
        item = Item.query.filter_by(id=itemId).one()
897
    except:
898
        raise InventoryServiceException(101, "Item not found for vendorId " + str(itemId))
899
 
900
    try:
2358 ankur.sing 901
        ds_vendorItemMapping = VendorItemMapping.query.filter(and_(VendorItemMapping.vendor==vendor, VendorItemMapping.item==item, VendorItemMapping.item_key==key)).one()
2116 ankur.sing 902
    except:
903
        ds_vendorItemMapping = VendorItemMapping()
904
        ds_vendorItemMapping.vendor = vendor
905
        ds_vendorItemMapping.item = item
2497 ankur.sing 906
    ds_vendorItemMapping.vendor_category = vendorItemMapping.vendorCategory
2116 ankur.sing 907
    ds_vendorItemMapping.item_key = vendorItemMapping.itemKey
908
 
909
    session.commit()
910
    return
911
 
2120 ankur.sing 912
def validate_item_prices(item):
2129 ankur.sing 913
    if item.mrp == None or item.sellingPrice == None or item.mrp == "" or item.sellingPrice == "":
914
        return
915
    if item.mrp < item.sellingPrice:
2120 ankur.sing 916
        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))
917
        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 918
    return
2120 ankur.sing 919
 
920
def validate_vendor_prices(item, vendorPrices):
2129 ankur.sing 921
    if item.mrp != None and item.mrp != "" and vendorPrices.mop != "" and item.mrp <  vendorPrices.mop:
2120 ankur.sing 922
        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))
923
        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)))
924
    if vendorPrices.mop != "" and vendorPrices.transferPrice != "" and vendorPrices.transferPrice > vendorPrices.mop:
925
        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))
926
        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)))
927
    return
2065 ankur.sing 928
 
929
def get_all_vendors():
930
    return Vendor.query.all()
931
 
2116 ankur.sing 932
def check_similar_item(product_group, brand, model_number, color):
2129 ankur.sing 933
    query = Item.query
2428 ankur.sing 934
    query = query.filter_by(product_group=product_group)
935
    query = query.filter_by(brand=brand)
936
    query = query.filter_by(model_number=model_number)
2129 ankur.sing 937
    if color:
938
        query = query.filter_by(color=color)
939
    item = query.first()
2116 ankur.sing 940
    if item is None:
941
        return 0
942
    else:
943
        return item.id
2286 ankur.sing 944
 
945
def change_risky_flag(item_id, risky):
946
    item = get_item(item_id)
947
    if not item:
948
        raise InventoryServiceException(101, "Item missing in our database")
949
    try:
950
        log_risky_flag(item_id, risky)
951
    except:
952
        print "Not able to log risky flag change"
953
    item.risky = risky
2368 ankur.sing 954
    if not risky and item.status == status.PAUSED:
955
        change_item_status(item.id, status.ACTIVE)
2286 ankur.sing 956
    session.commit()
957
 
2358 ankur.sing 958
def get_items_by_vendor_category(vendor_category):
959
    if not vendor_category:
960
        raise InventoryServiceException(101, "Invalid vendor category in request")
961
    query = Item.query.filter(and_(Item.hotspotCategory==vendor_category, Item.status != status.PHASED_OUT))
962
    items = query.all()
963
    return items
2116 ankur.sing 964
 
2358 ankur.sing 965
def get_risky_items():
966
    items = Item.query.filter_by(risky=True).all()
967
    return items
3008 rajveer 968
 
2809 rajveer 969
def get_similar_items_catalog_ids(start_index, stop_index, itemId):
3008 rajveer 970
    query = SimilarItems.query.filter_by(item_id=itemId).limit(stop_index-start_index)
971
    similar_items = query.all()
3289 rajveer 972
    return_list = []
973
    for similar_item in similar_items:
974
        isActive = False
975
        try:
976
            all_items = Item.query.filter_by(catalog_item_id=similar_item.catalog_item_id).all()
977
        except:
978
            continue
979
        for item in all_items:
980
            isActive = isActive or item.status == status.ACTIVE
981
        if isActive:
982
            return_list.append(similar_item.catalog_item_id)
983
    return return_list
2809 rajveer 984
 
3079 rajveer 985
def add_product_notification(itemId, email):
986
    try:
3470 rajveer 987
        try:
988
            product_notification = ProductNotification.query.filter_by(item_id=itemId, email=email).one()
989
        except:
990
            product_notification = ProductNotification()
991
            product_notification.email = email
992
            product_notification.item_id = itemId
3079 rajveer 993
        product_notification.addedOn = datetime.datetime.now()
994
        session.commit()
995
        return True
996
    except:
997
        return False
3086 rajveer 998
 
999
 
1000
def send_product_notifications():
1001
    product_notifications = ProductNotification.query.all()
1002
    for product_notification in product_notifications:
1003
        item = product_notification.item
1004
        availability = __get_item_availability(item)
3309 rajveer 1005
        if availability > 0 and item.status == status.ACTIVE:
3086 rajveer 1006
            __enque_product_notification_email(product_notification.email, __get_product_name(item) , product_notification.addedOn, __get_product_url(item), item.id)
1007
            product_notification.delete()
1008
    session.commit()
1009
    return True
1010
 
1011
def __get_product_name(item):
1012
    product_name = item.brand + " " + item.model_name + " " + item.model_number
1013
    color = item.color
1014
    if color is not None and color != 'NA':
1015
        product_name = product_name + " (" + color + ")"
3201 rajveer 1016
    product_name = product_name.replace("  "," ")
3086 rajveer 1017
    return product_name
1018
 
1019
 
1020
def __get_product_url(item):
1021
    product_url = "http://www.saholic.com/mobile-phones/" + item.brand + "-" + item.model_name + "-" + item.model_number + "-" + str(item.catalog_item_id)
1022
    product_url = product_url.replace("--","-")
1023
    product_url = product_url.replace(" ","")
1024
    return product_url
1025
 
3348 varun.gupt 1026
def get_all_brands_by_category(category_id):
1027
    catm = CategoryManager()
1028
    child_categories = catm.getCategory(category_id).children_category_ids
1029
    brands = session.query(distinct(Item.brand)).filter(Item.category.in_(child_categories)).all()
1030
 
1031
    return [brand[0] for brand in brands]
3086 rajveer 1032
 
1033
def __enque_product_notification_email(email, product, date, url, itemId):
1034
 
1035
    html = """
1036
        <html>
1037
        <body>
1038
        <div>
1039
        <p>
1040
            Hi,<br /><br />
1041
            The product requested by you on $date is now available on saholic.com.
1042
        </p>
1043
 
1044
        <p>    
1045
        <strong>Product: $product </strong>
1046
        </p>
1047
 
1048
        <p>
1049
        Click the link below to visit the product: 
1050
        <br/>
1051
        $url
1052
        </p>
1053
        <p>
1054
        Regards,<br/>
1055
        Saholic Customer Support Team<br/>
1056
        www.saholic.com<br/>
1057
        Email: help@saholic.com<br/>
1058
        </p>
1059
        </div>
1060
        </body>
1061
        </html>
1062
        """
1063
 
1064
    html = Template(html).substitute(dict(product=product,date=date,url=url))
3079 rajveer 1065
 
3086 rajveer 1066
    try:
1067
        helper_client = HelperClient().get_client()
1068
        helper_client.saveUserEmailForSending(email, "", "Product requested by you is available now.", html, str(itemId), "ProductNotification")
1069
    except Exception as e:
1070
        print e
1071
 
1072
 
766 rajveer 1073
def close_session():
1074
    if session.is_active:
1075
        print "session is active. closing it."
1399 rajveer 1076
        session.close()
3376 rajveer 1077
 
1078
def is_alive():
1079
    try:
1080
        session.query(Item.id).limit(1).one()
1081
        return True
1082
    except:
1083
        return False