Subversion Repositories SmartDukaan

Rev

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