Subversion Repositories SmartDukaan

Rev

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