Subversion Repositories SmartDukaan

Rev

Rev 2358 | Rev 2402 | 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,\
1991 ankur.sing 11
    VendorItemMapping, Vendor
122 ashish 12
from shop2020.thriftpy.model.v1.catalog.ttypes import \
13
    InventoryServiceException, status
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
1970 rajveer 20
from shop2020.model.v1.catalog.impl.CategoryManager import CategoryManager
1991 ankur.sing 21
from sqlalchemy.sql.expression import and_
94 ashish 22
 
23
def initialize():
24
    DataService.initialize()
25
 
26
 
103 ashish 27
def get_all_items(is_active):
28
    if is_active:
766 rajveer 29
        items = Item.query.filter_by(status= status.ACTIVE).all()
103 ashish 30
    else:
766 rajveer 31
        items = Item.query.all()
32
    return items
33
 
103 ashish 34
def get_all_items_by_status(status):
2174 ankur.sing 35
    if status == None:
103 ashish 36
        #return all items
766 rajveer 37
        items = get_all_items(False)
103 ashish 38
    else:
766 rajveer 39
        items = Item.query.filter_by(status=status).all()
40
    return items
103 ashish 41
 
635 rajveer 42
def get_item(item_id):
766 rajveer 43
    item = Item.get_by(id=item_id)
44
    return item
94 ashish 45
 
635 rajveer 46
def get_items_by_catalog_id(catalog_id):
447 rajveer 47
    query = Item.query.filter_by(catalog_item_id=catalog_id)
437 rajveer 48
    try:
635 rajveer 49
        items = query.all()
50
        return get_thrift_item_list(items)
1399 rajveer 51
    except Exception as ex:
52
        print ex
437 rajveer 53
        raise InventoryServiceException(109, "Item not found")
54
 
576 chandransh 55
def is_active(item_id):
56
    try:
635 rajveer 57
        item = get_item(item_id)
576 chandransh 58
        return item.status == status.ACTIVE
59
    except InventoryServiceException:
60
        return False
2035 rajveer 61
 
62
def get_item_status_description(itemId):
63
    item = get_item(itemId)
64
    return item.status_description
563 chandransh 65
 
94 ashish 66
def get_Warehouse(warehouse_id):
67
    return Warehouse.get_by(id=warehouse_id)
68
 
122 ashish 69
def get_all_warehouses_by_status(status):
70
    if not status:
766 rajveer 71
        warehouses = Warehouse.query.all()
122 ashish 72
    else:
851 chandransh 73
        warehouses = Warehouse.query.filter_by(status=status).all()
74
    return warehouses
122 ashish 75
 
94 ashish 76
def get_all_warehouses_for_item(item_id):
635 rajveer 77
    item = get_item(item_id)
94 ashish 78
    if not item:
122 ashish 79
        raise InventoryServiceException(108, "Some unforeseen error while obtaining item")
80
    return item.get_all_warehouses
94 ashish 81
 
122 ashish 82
def get_all_items_for_warehouse(warehouse_id):
83
    warehouse = get_Warehouse(warehouse_id)
84
    if not warehouse:
85
        raise InventoryServiceException(108, "bad warehouse")
86
    return warehouse.all_items
87
 
94 ashish 88
def add_warehouse(warehouse):
103 ashish 89
    if not warehouse:
122 ashish 90
        raise InventoryServiceException(108, "Bad warehouse")
103 ashish 91
    if get_Warehouse(warehouse.id):
92
        #warehouse is already present.
122 ashish 93
        raise InventoryServiceException(101, "Warehouse already present")
103 ashish 94
 
94 ashish 95
    ds_warehouse = Warehouse()
96
    ds_warehouse.id = warehouse.id
97
    ds_warehouse.location = warehouse.location
122 ashish 98
    ds_warehouse.status = status.ACTIVE
103 ashish 99
    ds_warehouse.addedOn = datetime.datetime.now()
483 rajveer 100
    ds_warehouse.lastCheckedOn = datetime.datetime.now()
101
    ds_warehouse.tinNumber = warehouse.tinNumber
102
    ds_warehouse.pincode = warehouse.pincode
103
    if warehouse.vendorString:
104
        ds_warehouse.vendorString = warehouse.vendorString
94 ashish 105
    session.commit()
103 ashish 106
    return ds_warehouse.id
94 ashish 107
 
122 ashish 108
def update_item(item):
109
    if not item:
110
        raise InventoryServiceException(108, "Bad item in request")
111
 
112
    if not item.id:
609 chandransh 113
        raise InventoryServiceException(101, "Missing id for update")
122 ashish 114
 
2120 ankur.sing 115
    validate_item_prices(item)
2065 ankur.sing 116
 
635 rajveer 117
    ds_item = get_item(item.id)
122 ashish 118
 
119
    if not ds_item:
609 chandransh 120
        raise InventoryServiceException(101, "Item missing in our database")
122 ashish 121
 
963 chandransh 122
    if item.productGroup:
123
        ds_item.product_group = item.productGroup 
124
    if item.brand:
125
        ds_item.brand = item.brand
511 rajveer 126
    if item.modelName:
127
        ds_item.model_name = item.modelName
128
    if item.modelNumber:
129
        ds_item.model_number = item.modelNumber
609 chandransh 130
    if item.color:
131
        ds_item.color = item.color
483 rajveer 132
    if item.category:
133
        ds_item.category = item.category
134
    if item.comments:
135
        ds_item.comments = item.comments
511 rajveer 136
 
122 ashish 137
    if item.catalogItemId:
138
        ds_item.catalog_item_id = item.catalogItemId
483 rajveer 139
 
2129 ankur.sing 140
    ds_item.mrp = item.mrp
141
    ds_item.sellingPrice = item.sellingPrice
142
 
483 rajveer 143
    if item.mop:
144
        ds_item.mop = item.mop
609 chandransh 145
    if item.dealerPrice:
146
        ds_item.dealerPrice = item.dealerPrice
2065 ankur.sing 147
    if item.transferPrice:
148
        ds_item.transfer_price = item.transferPrice
2174 ankur.sing 149
    ds_item.weight = item.weight
2129 ankur.sing 150
 
2358 ankur.sing 151
    if ds_item.status != item.itemStatus:
152
        ds_item.status = item.itemStatus
153
        add_status_change_log(ds_item.id, item.itemStatus)
2035 rajveer 154
    if item.status_description:
155
        ds_item.status_description = item.status_description
122 ashish 156
 
511 rajveer 157
    if item.startDate:
2116 ankur.sing 158
        ds_item.startDate = to_py_date(item.startDate)
511 rajveer 159
    if item.retireDate:
2116 ankur.sing 160
        ds_item.retireDate = to_py_date(item.retireDate)
511 rajveer 161
 
122 ashish 162
    if item.featureId:
163
        ds_item.feature_id = item.featureId
164
    if item.featureDescription:
165
        ds_item.feature_description = item.featureDescription
166
 
2129 ankur.sing 167
    ds_item.bestDealText = item.bestDealText
168
    ds_item.bestDealValue = item.bestDealValue
2065 ankur.sing 169
    ds_item.bestSellingRank = item.bestSellingRank
170
    ds_item.defaultForEntity = item.defaultForEntity
2251 ankur.sing 171
    ds_item.risky = item.risky
2347 ankur.sing 172
    ds_item.updatedOn = datetime.datetime.now()
2065 ankur.sing 173
 
122 ashish 174
    session.commit();
175
    return ds_item.id
94 ashish 176
 
2116 ankur.sing 177
def check_vendor_item_mapping(product_group, brand, model_number, color, vendor_id, vendor_category):
178
    key = product_group.strip().lower() + '|' + brand.strip().lower() + '|' + model_number.strip().lower() + '|' + color.strip().lower()
179
    try:
180
        vim = VendorItemMapping.query.filter_by(vendor_id=vendor_id, item_key=key, vendor_category=vendor_category).one()
181
        return True
182
    except:
183
        return False
184
 
103 ashish 185
def add_item(item):
186
    if not item:
122 ashish 187
        raise InventoryServiceException(108, "Bad item in request")
635 rajveer 188
    if get_item(item.id):
122 ashish 189
        raise InventoryServiceException(101, "Item already exists")
2120 ankur.sing 190
 
191
    validate_item_prices(item)
192
 
103 ashish 193
    ds_item = Item()
963 chandransh 194
    if item.productGroup:
195
        ds_item.product_group = item.productGroup
196
    if item.brand:
197
        ds_item.brand = item.brand
515 rajveer 198
    if item.modelName:
199
        ds_item.model_name = item.modelName
200
    if item.modelNumber:
201
        ds_item.model_number = item.modelNumber
609 chandransh 202
    if item.color:
203
        ds_item.color = item.color
2116 ankur.sing 204
    if item.hotspotCategory:
205
        ds_item.hotspotCategory = item.hotspotCategory
206
        if item.hotspotCategory == 'Handsets':
207
            item.preferredWarehouse = 1
208
        else:
209
            item.preferredWarehouse = 2
210
 
483 rajveer 211
    if item.category:
212
        ds_item.category = item.category
213
    if item.comments:
214
        ds_item.comments = item.comments
215
 
103 ashish 216
    ds_item.addedOn = datetime.datetime.now()
609 chandransh 217
    ds_item.updatedOn = datetime.datetime.now()
2116 ankur.sing 218
    if item.startDate:
219
        ds_item.startDate = to_py_date(item.startDate)
220
    if item.retireDate:
221
        ds_item.retireDate = to_py_date(item.retireDate)
609 chandransh 222
 
483 rajveer 223
    if item.mrp:
224
        ds_item.mrp = item.mrp
225
    if item.mop:
226
        ds_item.mop = item.mop
227
    if item.sellingPrice:
228
        ds_item.sellingPrice = item.sellingPrice
609 chandransh 229
    if item.dealerPrice:
230
        ds_item.dealerPrice = item.dealerPrice
2116 ankur.sing 231
    if item.transferPrice:
232
        ds_item.transfer_price = item.transferPrice
122 ashish 233
    if item.weight:
234
        ds_item.weight = item.weight
235
 
236
    if item.featureId:
237
        ds_item.feature_id = item.featureId
238
    if item.featureDescription:
239
        ds_item.feature_description = item.featureDescription
240
 
103 ashish 241
    if item.otherInfo:
242
        for k,v in item.otherInfo.iteritems():
243
            info = ItemInfo()
244
            info.key = k
245
            info.value = v
246
            ds_item.iteminfo.append(info)
2116 ankur.sing 247
 
103 ashish 248
    #check if categories present. If yes, add them to system
122 ashish 249
 
609 chandransh 250
    if item.bestDealValue:
251
        ds_item.bestDealValue = item.bestDealValue
252
    if item.bestDealText:
253
        ds_item.bestDealText = item.bestDealText
2116 ankur.sing 254
    if item.bestSellingRank:
255
        ds_item.bestSellingRank = item.bestSellingRank
256
    ds_item.defaultForEntity = item.defaultForEntity
2251 ankur.sing 257
    ds_item.risky = item.risky
609 chandransh 258
 
2116 ankur.sing 259
    # Check if a similar item already exists in our database
260
    similar_item = Item.query.filter_by(product_group=item.productGroup, brand = item.brand, model_number=item.modelNumber, hotspotCategory=item.hotspotCategory).first()
261
    print "[SIMILAR ITEM FOUND:] FOR {0} {1} {2} {3} {4}".format(item.productGroup, item.brand, item.modelNumber, item.hotspotCategory, item.color)
262
 
263
    if similar_item is None or similar_item.catalog_item_id is None:
264
        # If there is no similar item in the database from before,
265
        # use the entity_id_generator
266
        entity_id = EntityIDGenerator.query.first()
267
        ds_item.catalog_item_id = entity_id.id + 1
268
        ds_item.status = status.IN_PROCESS
269
        ds_item.status_description = "This item is in process."
270
        entity_id.id = entity_id.id  + 1
271
    else:
272
        #If a similar item already exists for a product group, brand and model_number, set it as same.
273
        ds_item.catalog_item_id = similar_item.catalog_item_id
274
        ds_item.category = similar_item.category
275
        ds_item.status = similar_item.status
276
        ds_item.status_description = similar_item.status_description
277
 
103 ashish 278
    session.commit();
609 chandransh 279
    return ds_item.id       
103 ashish 280
 
483 rajveer 281
def update_inventory(warehouse_id, timestamp, availability):
282
    warehouse = get_Warehouse(warehouse_id)
283
    if not warehouse:
284
        raise InventoryServiceException(107, "Warehouse? Where?")
285
 
286
    time = datetime.datetime.now()
287
    warehouse.lastCheckedOn = time
288
    warehouse.vendorString = timestamp
1368 chandransh 289
    vendor = warehouse.vendor
2368 ankur.sing 290
    session.commit()
1368 chandransh 291
    for item_key, quantity in availability.iteritems():
483 rajveer 292
        try:
1368 chandransh 293
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
294
            item = vendor_item_mapping.item
494 rajveer 295
        except:
296
            continue  
297
        try:
483 rajveer 298
            item_inventory_history = ItemInventoryHistory()
299
            item_inventory_history.warehouse = warehouse
300
            item_inventory_history.item = item
301
            item_inventory_history.timestamp = time
302
            item_inventory_history.availibility = quantity
303
 
304
            current_inventory_snapshot = CurrentInventorySnapshot.get_by(item=item, warehouse=warehouse)
305
            if not current_inventory_snapshot:
306
                current_inventory_snapshot = CurrentInventorySnapshot()
307
                current_inventory_snapshot.item = item
308
                current_inventory_snapshot.warehouse = warehouse
309
                current_inventory_snapshot.availibility = 0
871 chandransh 310
                current_inventory_snapshot.reserved = 0
483 rajveer 311
            # added the difference in the current inventory    
312
            current_inventory_snapshot.availibility = current_inventory_snapshot.availibility + quantity
313
        except:
314
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
2368 ankur.sing 315
        session.commit() 
316
        check_risky_item(item)
483 rajveer 317
 
94 ashish 318
def get_item_inventoy(item_id):
319
 
320
    inventory = Item.get_by(id=item_id).currentInventory
321
    if not inventory:
122 ashish 322
        raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
94 ashish 323
    return inventory
324
 
635 rajveer 325
def get_item_inventory_by_item_id(item_id):
326
    inventory = Item.get_by(id=item_id).currentInventory
379 ashish 327
    if not inventory:
328
        raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
329
    return inventory
330
 
103 ashish 331
 
332
def retire_warehouse(warehouse_id):
333
    if not warehouse_id:
122 ashish 334
        raise InventoryServiceException(101, "Bad warehouse id")
103 ashish 335
    warehouse = get_Warehouse(warehouse_id)
336
    if not warehouse:
122 ashish 337
        raise InventoryServiceException(108, "warehouse id not present")
338
    warehouse.status = status.DELETED;
103 ashish 339
    session.commit()
340
 
341
def retire_item(item_id):
342
    if not item_id:
122 ashish 343
        raise InventoryServiceException(101, "bad item id")
635 rajveer 344
    item = get_item(item_id)
103 ashish 345
    if not item:
122 ashish 346
        raise InventoryServiceException(108, "item id not present")
347
    item.status = status.PHASED_OUT
348
    item.retireDate = datetime.datetime.now()
103 ashish 349
    session.commit()
122 ashish 350
 
351
#need to implement threads based solution here
103 ashish 352
def start_item_on(item_id, timestamp):
353
    if not item_id:
122 ashish 354
        raise InventoryServiceException(101, "bad item id")
635 rajveer 355
    item = get_item(item_id)
103 ashish 356
    if not item:
122 ashish 357
        raise InventoryServiceException(108, "item id not present")
103 ashish 358
 
122 ashish 359
    item.status = status.ACTIVE
360
    item.startDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))
361
    add_status_change_log(item, status.ACTIVE)
103 ashish 362
    session.commit()
363
 
122 ashish 364
#need to implement threads here
103 ashish 365
def retire_item_on(item_id, timestamp):
366
    if not item_id:
122 ashish 367
        raise InventoryServiceException(101, "bad item id")
635 rajveer 368
    item = get_item(item_id)
103 ashish 369
    if not item:
122 ashish 370
        raise InventoryServiceException(108, "item id not present")
103 ashish 371
 
122 ashish 372
    item.status = status.PHASED_OUT
373
    item.retireDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))
374
    add_status_change_log(item, status.PHASED_OUT)
103 ashish 375
    session.commit()
376
 
377
def add_status_change_log(item, new_status):
378
    item_change_log = ItemChangeLog()
379
    item_change_log.new_status = new_status
380
    item_change_log.old_status = item.status
381
    item_change_log.timestamp = datetime.datetime.now()
382
    item_change_log.item = item
383
    session.commit()
384
 
385
def change_item_status(item_id, new_status):
386
    if not item_id:
122 ashish 387
        raise InventoryServiceException(101, "bad item id")
635 rajveer 388
    item = get_item(item_id)
103 ashish 389
    if not item:
122 ashish 390
        raise InventoryServiceException(108, "item id not present")
2116 ankur.sing 391
    add_status_change_log(item, new_status)
122 ashish 392
    item.status = new_status
2251 ankur.sing 393
    if item.status == status.PHASED_OUT:
394
        item.status_description = "This item has been phased out"
395
    elif item.status == status.DELETED:
396
        item.status_description = "This item has been deleted"
397
    elif item.status == status.PAUSED:
398
        item.status_description = "This item is currently out of stock"        
399
    elif item.status == status.ACTIVE:
400
        item.status_description = "This item is active"
401
    elif item.status == status.IN_PROCESS:
402
        item.status_description = "This item is in process"
403
    elif item.status == status.CONTENT_COMPLETE:
404
        item.status_description = "This item is in process"
103 ashish 405
    session.commit()
406
 
407
def get_item_availability_for_warehouse(warehouse_id, item_id):
408
    if not warehouse_id:
122 ashish 409
        raise InventoryServiceException(101, "bad warehouse_id")
103 ashish 410
    if not item_id:
122 ashish 411
        raise InventoryServiceException(101, "bad item_id")
103 ashish 412
 
413
    warehouse = get_Warehouse(warehouse_id)
414
    if not warehouse:
122 ashish 415
        raise InventoryServiceException(108, "warehouse does not exist")
635 rajveer 416
    item = get_item(item_id)
504 rajveer 417
 
103 ashish 418
    if not item:
766 rajveer 419
        raise InventoryServiceException(108, "item does not exist")
122 ashish 420
 
494 rajveer 421
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id)
504 rajveer 422
    query = query.filter_by(item_id = item.id)
494 rajveer 423
    try:
424
        current_inventory_snapshot = query.one()
871 chandransh 425
        return current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
494 rajveer 426
    except:
427
        return 0
428
    """
429
    current_inventory_snapshot = CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id == warehouse_id, CurrentInventorySnapshot.item_id == item_id).one()
103 ashish 430
    if not current_inventory_snapshot:
431
        return 0
432
    else:
433
        return current_inventory_snapshot.availibility
494 rajveer 434
    """
643 chandransh 435
 
2368 ankur.sing 436
def check_risky_item(item):
2251 ankur.sing 437
    if not item.risky:
438
        return
2368 ankur.sing 439
    all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
440
    availibility = 0
441
    reserved = 0
442
    for currInv in all_inventory:
443
        availibility = availibility + currInv.availibility
444
        reserved = reserved + currInv.reserved 
445
    if availibility - reserved <= 0:
2251 ankur.sing 446
        if item.status == status.ACTIVE:
447
            change_item_status(item.id, status.PAUSED)
448
    else:
449
        if item.status == status.PAUSED:
450
            change_item_status(item.id, status.ACTIVE)
2368 ankur.sing 451
    session.commit()
2251 ankur.sing 452
 
871 chandransh 453
def reserve_item_in_warehouse(item_id, warehouse_id, quantity):    
454
    if not warehouse_id:
455
        raise InventoryServiceException(101, "bad warehouse_id")
2251 ankur.sing 456
    item = get_item(item_id)
457
    if not item:
871 chandransh 458
        raise InventoryServiceException(101, "bad item_id")
459
 
460
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
461
    try:
462
        current_inventory_snapshot = query.one()
463
        current_inventory_snapshot.reserved = current_inventory_snapshot.reserved + quantity
464
        session.commit()
2368 ankur.sing 465
        check_risky_item(item)
871 chandransh 466
        return True
467
    except:
468
        print "Unexpected error:", sys.exc_info()[0]
469
        return False
470
 
471
def reduce_reservation_count(item_id, warehouse_id, quantity):
472
    if not warehouse_id:
473
        raise InventoryServiceException(101, "bad warehouse_id")
2251 ankur.sing 474
    item = get_item(item_id)
475
    if not item:
871 chandransh 476
        raise InventoryServiceException(101, "bad item_id")
477
 
478
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
479
    try:
480
        current_inventory_snapshot = query.one()
481
        current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
482
        session.commit()
2368 ankur.sing 483
        check_risky_item(item)
871 chandransh 484
        return True
485
    except:
486
        print "Unexpected error:", sys.exc_info()[0]
487
        return False
488
 
2075 rajveer 489
def mark_item_as_content_complete(entity_id, category, brand, modelName, modelNumber):
723 chandransh 490
    content_complete_status = status.CONTENT_COMPLETE
1294 chandransh 491
    items = Item.query.filter_by(catalog_item_id=entity_id, status=status.IN_PROCESS).all()
723 chandransh 492
    current_timestamp = datetime.datetime.now()
493
    for item in items:
494
        item_change_log = ItemChangeLog()
495
        item_change_log.old_status = item.status
496
        item_change_log.new_status = content_complete_status
497
        item_change_log.timestamp = current_timestamp
498
        item_change_log.item = item
499
 
500
        item.status = content_complete_status
2075 rajveer 501
        item.category = category
502
        item.brand = brand
2081 rajveer 503
        item.model_name = modelName
504
        item.model_number = modelNumber
723 chandransh 505
        item.updatedOn = current_timestamp
506
    session.commit()
507
    return True
1294 chandransh 508
 
643 chandransh 509
def get_item_availability_for_location(warehouse_loc, item_id):
510
    if warehouse_loc is None:
511
        raise InventoryServiceException(101, "Bad Warehouse Location")
512
    if not item_id:
1416 chandransh 513
        raise InventoryServiceException(101, "Bad Item id")
643 chandransh 514
 
1416 chandransh 515
    item = Item.get_by(id=item_id)
643 chandransh 516
    warehouses = Warehouse.query.filter_by(logisticsLocation=warehouse_loc).all()
517
    warehouse_ids = [warehouse.id for warehouse in warehouses]
518
    warehouse_retid = -1
519
    global_availability = 0
520
    for warehouse_id in warehouse_ids:
785 rajveer 521
        try:
871 chandransh 522
            current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).one()
523
            availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
785 rajveer 524
        except:
525
            availability = 0    
643 chandransh 526
        if availability > global_availability:
527
            warehouse_retid = warehouse_id
528
            global_availability = availability
2341 chandransh 529
 
643 chandransh 530
    if warehouse_retid == -1:
759 chandransh 531
        # This is the case when all warehouses have exhausted their
532
        # inventory of this item or no warehouse is available in this
533
        # location.
1416 chandransh 534
        warehouse_retid = int(item.preferredWarehouse)
2344 chandransh 535
        warehouse = Warehouse.get_by(id=warehouse_retid)
2341 chandransh 536
        try:
537
            current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_retid, item_id = item_id).one()
538
            global_availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
539
        except:
540
            global_availability = 0
643 chandransh 541
 
2341 chandransh 542
    return [warehouse.logisticsLocation, warehouse_retid, global_availability]
543
 
122 ashish 544
def get_warehouses_for_item(item_id):
643 chandransh 545
 
122 ashish 546
    if not item_id:
547
        raise InventoryServiceException(101, "bad item_id")
635 rajveer 548
    item = get_item(item_id)
122 ashish 549
 
550
    if not item:
551
        raise InventoryServiceException(101, "bad item")
552
 
483 rajveer 553
    warehouses = item.currentInventory.warehouse
501 rajveer 554
    return warehouses
555
 
626 chandransh 556
def get_best_sellers(start_index, stop_index, category=-1):
1926 rajveer 557
    query = get_best_sellers_query(category, None)
1098 chandransh 558
    best_sellers = query.all()[start_index:stop_index]
621 chandransh 559
    return get_thrift_item_list(best_sellers)
560
 
2093 chandransh 561
def get_best_sellers_count(category=-1):
1926 rajveer 562
    count = get_best_sellers_query(category, None).count()
1120 rajveer 563
    if count is None:
564
        count = 0
766 rajveer 565
    return count
621 chandransh 566
 
1926 rajveer 567
def get_best_sellers_catalog_ids(start_index, stop_index, brand, category=-1):
568
    query = get_best_sellers_query(category, brand)
1098 chandransh 569
    best_sellers = query.all()[start_index:stop_index]
621 chandransh 570
    return [item.catalog_item_id for item in best_sellers]
1926 rajveer 571
 
1970 rajveer 572
def get_child_categories(category):
573
    cm = CategoryManager()
574
    return cm.getCategory(category).children_category_ids
575
 
1926 rajveer 576
def get_best_sellers_query(category, brand):
1098 chandransh 577
    query = Item.query.filter_by(status=status.ACTIVE).filter(Item.bestSellingRank != None)
626 chandransh 578
    if category != -1:
1970 rajveer 579
        all_categories = [category]
580
        child_categories = get_child_categories(category)
581
        if child_categories is not None:
582
            all_categories = all_categories + child_categories 
583
        query = query.filter(Item.category.in_(all_categories))
1926 rajveer 584
    if brand is not None:
585
        query = query.filter_by(brand=brand)
1098 chandransh 586
    query = query.order_by(asc(Item.bestSellingRank))
621 chandransh 587
    return query
609 chandransh 588
 
1098 chandransh 589
def get_best_deals(category=-1):
1926 rajveer 590
    query = get_best_deals_query(category, None)
1098 chandransh 591
    items = query.all()
609 chandransh 592
    return get_thrift_item_list(items)
593
 
1098 chandransh 594
def get_best_deals_count(category=-1):
1926 rajveer 595
    count = get_best_deals_query(category, None).count()
1120 rajveer 596
    if count is None:
597
        count = 0
766 rajveer 598
    return count
501 rajveer 599
 
1926 rajveer 600
def get_best_deals_catalog_ids(start_index, stop_index, brand, category=-1):
601
    query = get_best_deals_query(category, brand)
1098 chandransh 602
    best_deal_items = query.all()[start_index:stop_index]
603
    return [item.catalog_item_id for item in best_deal_items]
604
 
1926 rajveer 605
def get_best_deals_query(category, brand):
1098 chandransh 606
    query = Item.query.filter_by(status=status.ACTIVE).filter(Item.bestDealValue != None)
626 chandransh 607
    if category != -1:
1970 rajveer 608
        all_categories = [category]
609
        child_categories = get_child_categories(category)
610
        if child_categories is not None:
611
            all_categories = all_categories + child_categories 
612
        query = query.filter(Item.category.in_(all_categories))
1926 rajveer 613
    if brand is not None:
614
        query = query.filter_by(brand=brand)
1098 chandransh 615
    query = query.group_by(Item.catalog_item_id).order_by(desc(Item.bestDealValue))
616
    return query
609 chandransh 617
 
1098 chandransh 618
def get_latest_arrivals(limit, category=-1):
1926 rajveer 619
    query = get_latest_arrivals_query(category, None)
1098 chandransh 620
    items = query.all()[0:limit]
609 chandransh 621
    return get_thrift_item_list(items)
598 chandransh 622
 
1098 chandransh 623
def get_latest_arrivals_count(limit, category=-1):
1926 rajveer 624
    count = get_latest_arrivals_query(category, None).count()
1120 rajveer 625
    if count is None:
626
        count = 0
627
    count = min(count, limit)
766 rajveer 628
    return count
602 chandransh 629
 
1926 rajveer 630
def get_latest_arrivals_catalog_ids(start_index, stop_index, brand, category=-1):
631
    query = get_latest_arrivals_query(category, brand)
1098 chandransh 632
    latest_arrivals = query.all()[start_index:stop_index]
633
    return [item.catalog_item_id for item in latest_arrivals]
634
 
1926 rajveer 635
def get_latest_arrivals_query(category, brand):
1098 chandransh 636
    query = Item.query.filter_by(status=status.ACTIVE)
626 chandransh 637
    if category != -1:
1970 rajveer 638
        all_categories = [category]
639
        child_categories = get_child_categories(category)
640
        if child_categories is not None:
641
            all_categories = all_categories + child_categories 
642
        query = query.filter(Item.category.in_(all_categories))
1926 rajveer 643
    if brand is not None:
644
        query = query.filter_by(brand=brand)
1098 chandransh 645
    query = query.group_by(Item.catalog_item_id).order_by(desc(Item.startDate))
646
    return query
609 chandransh 647
 
648
def get_thrift_item_list(items):
1098 chandransh 649
    return [to_t_item(item) for item in items if item != None]
635 rajveer 650
 
1155 rajveer 651
def generate_new_entity_id():
652
    generator =  EntityIDGenerator.query.one()
653
    id = generator.id + 1
654
    generator.id = id
655
    session.commit()
656
    return id
657
 
635 rajveer 658
def put_category_object(object):
659
    category = Category.get_by(id=1)
660
    if category is None:
661
        category = Category()
662
    category.object = object    
663
    session.commit()
664
    return True
665
 
666
def get_category_object():
766 rajveer 667
    object = Category.get_by(id=1).object
668
    return object
669
 
1341 chandransh 670
def get_item_pricing(item_id, warehouse_id):
671
    item = Item.query.filter_by(id=item_id).first()
672
    if item is None:
673
        raise InventoryServiceException(101, "Bad Item")
674
 
675
    warehouse = get_Warehouse(warehouse_id)
676
    if not warehouse:
677
        raise InventoryServiceException(108, "Bad Warehouse")
678
    vendor = warehouse.vendor
679
 
680
    try:
681
        item_pricing = VendorItemPricing.query.filter_by(vendor=vendor, item=item).one()
1347 chandransh 682
        return item_pricing
1341 chandransh 683
    except sqlalchemy.orm.exc.MultipleResultsFound:
684
        raise InventoryServiceException(110, "Multiple pricing information present for Vendor: " + vendor.name + " and Item: " + str(item_id))
685
    except sqlalchemy.orm.exc.NoResultFound:
686
        raise InventoryServiceException(111, "Missing pricing information for Vendor: " + vendor.name + " and Item: " + str(item_id))
687
 
1970 rajveer 688
def add_category(t_category):
689
    category = Category.get_by(id=t_category.id)
690
    if category is None:
691
        category = Category()
692
    category.id = t_category.id 
693
    category.label = t_category.label
694
    category.description = t_category.description
695
    category.parent_category_id = t_category.parent_category_id 
696
    session.commit()
697
    return True
698
 
699
def get_category(id):
700
    return Category.query.filter_by(id=id).first()
701
 
702
def get_all_categories():
703
    return Category.query.all()
704
 
1991 ankur.sing 705
 
706
def get_all_item_pricing(item_id):
707
    item = Item.query.filter_by(id=item_id).first()
708
    if item is None:
709
        raise InventoryServiceException(101, "Bad Item")
710
    item_pricing = VendorItemPricing.query.filter_by(item=item).all()
711
    return item_pricing
712
 
2116 ankur.sing 713
def get_item_mappings(item_id):
714
    item = Item.query.filter_by(id=item_id).first()
715
    if item is None:
716
        raise InventoryServiceException(101, "Bad Item")
717
    item_mappings = VendorItemMapping.query.filter_by(item=item).all()
718
    return item_mappings
719
 
720
def add_vendor_pricing(vendorItemPricing):
1991 ankur.sing 721
    if not vendorItemPricing:
722
        raise InventoryServiceException(108, "Bad vendorItemPricing in request")
723
    vendorId = vendorItemPricing.vendorId
724
    itemId = vendorItemPricing.itemId
725
 
726
    try:
727
        vendor = Vendor.query.filter_by(id=vendorId).one()
728
    except:
729
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
730
 
731
    try:
732
        item = Item.query.filter_by(id=itemId).one()
733
    except:
734
        raise InventoryServiceException(101, "Item not found for vendorId " + str(itemId))
735
 
2120 ankur.sing 736
    validate_vendor_prices(to_t_item(item), vendorItemPricing)
2065 ankur.sing 737
 
1991 ankur.sing 738
    try:
739
        ds_vendorItemPricing = VendorItemPricing.query.filter(and_(VendorItemPricing.vendor==vendor, VendorItemPricing.item==item)).one()
740
    except:
2116 ankur.sing 741
        ds_vendorItemPricing = VendorItemPricing()
742
        ds_vendorItemPricing.vendor = vendor
743
        ds_vendorItemPricing.item = item
1991 ankur.sing 744
 
745
    if vendorItemPricing.mop:
746
        ds_vendorItemPricing.mop = vendorItemPricing.mop
747
    if vendorItemPricing.dealerPrice:
748
        ds_vendorItemPricing.dealerPrice = vendorItemPricing.dealerPrice
749
    if vendorItemPricing.transferPrice:
2065 ankur.sing 750
        ds_vendorItemPricing.transfer_price = vendorItemPricing.transferPrice
1991 ankur.sing 751
 
752
    session.commit()
753
    return
754
 
2358 ankur.sing 755
def add_vendor_item_mapping(key, vendorItemMapping):
2116 ankur.sing 756
    if not vendorItemMapping:
757
        raise InventoryServiceException(108, "Bad vendorItemMapping in request")
758
    vendorId = vendorItemMapping.vendorId
759
    itemId = vendorItemMapping.itemId
760
 
761
    try:
762
        vendor = Vendor.query.filter_by(id=vendorId).one()
763
    except:
764
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
765
 
766
    try:
767
        item = Item.query.filter_by(id=itemId).one()
768
    except:
769
        raise InventoryServiceException(101, "Item not found for vendorId " + str(itemId))
770
 
771
    try:
2358 ankur.sing 772
        ds_vendorItemMapping = VendorItemMapping.query.filter(and_(VendorItemMapping.vendor==vendor, VendorItemMapping.item==item, VendorItemMapping.item_key==key)).one()
2116 ankur.sing 773
    except:
774
        ds_vendorItemMapping = VendorItemMapping()
775
        ds_vendorItemMapping.vendor = vendor
776
        ds_vendorItemMapping.item = item
777
        ds_vendorItemMapping.vendor_category = vendorItemMapping.vendorCategory
778
    ds_vendorItemMapping.item_key = vendorItemMapping.itemKey
779
 
780
    session.commit()
781
    return
782
 
2120 ankur.sing 783
def validate_item_prices(item):
2129 ankur.sing 784
    if item.mrp == None or item.sellingPrice == None or item.mrp == "" or item.sellingPrice == "":
785
        return
786
    if item.mrp < item.sellingPrice:
2120 ankur.sing 787
        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))
788
        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 789
    return
2120 ankur.sing 790
 
791
def validate_vendor_prices(item, vendorPrices):
2129 ankur.sing 792
    if item.mrp != None and item.mrp != "" and vendorPrices.mop != "" and item.mrp <  vendorPrices.mop:
2120 ankur.sing 793
        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))
794
        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)))
795
    if vendorPrices.mop != "" and vendorPrices.transferPrice != "" and vendorPrices.transferPrice > vendorPrices.mop:
796
        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))
797
        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)))
798
    return
2065 ankur.sing 799
 
800
def get_all_vendors():
801
    return Vendor.query.all()
802
 
2116 ankur.sing 803
def check_similar_item(product_group, brand, model_number, color):
2129 ankur.sing 804
    query = Item.query
805
    if product_group:
806
        query = query.filter_by(product_group=product_group)
807
    if brand:
808
        query = query.filter_by(brand=brand)
809
    if model_number:
810
        query = query.filter_by(model_number=model_number)
811
    if color:
812
        query = query.filter_by(color=color)
813
    item = query.first()
2116 ankur.sing 814
    if item is None:
815
        return 0
816
    else:
817
        return item.id
2286 ankur.sing 818
 
819
def change_risky_flag(item_id, risky):
820
    item = get_item(item_id)
821
    if not item:
822
        raise InventoryServiceException(101, "Item missing in our database")
823
    try:
824
        log_risky_flag(item_id, risky)
825
    except:
826
        print "Not able to log risky flag change"
827
    item.risky = risky
2368 ankur.sing 828
    if not risky and item.status == status.PAUSED:
829
        change_item_status(item.id, status.ACTIVE)
2286 ankur.sing 830
    session.commit()
2368 ankur.sing 831
    check_risky_item(item)
2286 ankur.sing 832
 
2358 ankur.sing 833
def get_items_by_vendor_category(vendor_category):
834
    if not vendor_category:
835
        raise InventoryServiceException(101, "Invalid vendor category in request")
836
    query = Item.query.filter(and_(Item.hotspotCategory==vendor_category, Item.status != status.PHASED_OUT))
837
    items = query.all()
838
    return items
2116 ankur.sing 839
 
2358 ankur.sing 840
def get_risky_items():
841
    items = Item.query.filter_by(risky=True).all()
842
    return items
843
 
766 rajveer 844
def close_session():
845
    if session.is_active:
846
        print "session is active. closing it."
1399 rajveer 847
        session.close()