Subversion Repositories SmartDukaan

Rev

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