Subversion Repositories SmartDukaan

Rev

Rev 4873 | Rev 4881 | 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 *
4748 mandeep.dh 7
from pydoc import Helper
8
from shop2020.clients.HelperClient import HelperClient
9
from shop2020.clients.TransactionClient import TransactionClient
10
from shop2020.config.client.ConfigClient import ConfigClient
94 ashish 11
from shop2020.model.v1.catalog.impl import DataService
4748 mandeep.dh 12
from shop2020.model.v1.catalog.impl.CategoryManager import CategoryManager
13
from shop2020.model.v1.catalog.impl.Convertors import to_t_item, \
3557 rajveer 14
    to_t_vendor_item_pricing, to_t_source
4748 mandeep.dh 15
from shop2020.model.v1.catalog.impl.DataService import Item, Warehouse, \
16
    ItemInventoryHistory, CurrentInventorySnapshot, ItemInfo, ItemChangeLog, \
17
    Category, EntityIDGenerator, VendorItemPricing, VendorItemMapping, Vendor, \
18
    SimilarItems, ProductNotification, Source, SourceItemPricing, AuthorizationLog, \
4873 mandeep.dh 19
    MissedInventoryUpdate
4748 mandeep.dh 20
from shop2020.thriftpy.model.v1.catalog.ttypes import InventoryServiceException, \
21
    status, ItemShippingInfo
22
from shop2020.thriftpy.model.v1.order.ttypes import AlertType
4873 mandeep.dh 23
from shop2020.utils import EmailAttachmentSender
4748 mandeep.dh 24
from shop2020.utils.EmailAttachmentSender import mail
2286 ankur.sing 25
from shop2020.utils.Utils import log_entry, to_py_date, log_risky_flag
621 chandransh 26
from sqlalchemy import desc, asc
3244 chandransh 27
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
3872 chandransh 28
from sqlalchemy.sql.expression import and_, or_, distinct, func
3086 rajveer 29
from string import Template
4748 mandeep.dh 30
from urllib2 import HTTPBasicAuthHandler
31
import datetime
32
import sys
3924 rajveer 33
import urllib2
94 ashish 34
 
35
def initialize():
36
    DataService.initialize()
37
 
3849 chandransh 38
def get_all_items_by_status(status, offset=0, limit=None):
39
    query = Item.query
4539 rajveer 40
    if status is not None:
3849 chandransh 41
        query = query.filter_by(status=status)
42
    query = query.order_by(Item.product_group, Item.brand, Item.model_number, Item.model_name).offset(offset)
43
    if limit:
44
        query = query.limit(limit)
45
    items = query.all()
46
    return items
47
 
48
def get_all_items(is_active, offset=0, limit=None):
103 ashish 49
    if is_active:
3849 chandransh 50
        items = get_all_items_by_status(status.ACTIVE, offset, limit)
103 ashish 51
    else:
3849 chandransh 52
        items = get_all_items_by_status(None, offset, limit)
766 rajveer 53
    return items
54
 
3849 chandransh 55
def get_item_count_by_status(use_status, status):
56
    if use_status:
57
        return Item.query.filter_by(status=status).count()
103 ashish 58
    else:
3849 chandransh 59
        return Item.query.count()
103 ashish 60
 
635 rajveer 61
def get_item(item_id):
766 rajveer 62
    item = Item.get_by(id=item_id)
63
    return item
94 ashish 64
 
635 rajveer 65
def get_items_by_catalog_id(catalog_id):
447 rajveer 66
    query = Item.query.filter_by(catalog_item_id=catalog_id)
437 rajveer 67
    try:
635 rajveer 68
        items = query.all()
69
        return get_thrift_item_list(items)
1399 rajveer 70
    except Exception as ex:
71
        print ex
437 rajveer 72
        raise InventoryServiceException(109, "Item not found")
73
 
576 chandransh 74
def is_active(item_id):
2983 chandransh 75
    t_item_shipping_info = ItemShippingInfo()
576 chandransh 76
    try:
635 rajveer 77
        item = get_item(item_id)
3281 chandransh 78
        t_item_shipping_info.isRisky = item.risky
4708 anupam.sin 79
        warehouse_ids = None
80
        if item.isWarehousePreferenceSticky :
81
            warehouse_ids = [item.preferredWarehouse]
82
        availability = __get_item_availability(item, warehouse_ids)
3281 chandransh 83
        if item.risky and availability <= 0 and item.status == status.ACTIVE:
84
            add_status_change_log(item, status.PAUSED_BY_RISK)
85
            item.status = status.PAUSED_BY_RISK
86
            item.status_description = "This item is currently out of stock"
87
            session.commit()
4797 rajveer 88
            __send_mail_for_oos_item(item)
3924 rajveer 89
            #This will clear cache from tomcat
90
            __clear_homepage_cache()
2983 chandransh 91
        t_item_shipping_info.isActive = (item.status == status.ACTIVE)
3281 chandransh 92
        t_item_shipping_info.quantity = availability
576 chandransh 93
    except InventoryServiceException:
2983 chandransh 94
        print "[ERROR] Unexpected error:", sys.exc_info()[0]
95
    return t_item_shipping_info
96
 
2035 rajveer 97
def get_item_status_description(itemId):
98
    item = get_item(itemId)
99
    return item.status_description
563 chandransh 100
 
94 ashish 101
def get_Warehouse(warehouse_id):
102
    return Warehouse.get_by(id=warehouse_id)
103
 
4332 anupam.sin 104
def get_Vendor(vendorId):
105
    return Vendor.get_by(id=vendorId)
106
 
122 ashish 107
def get_all_warehouses_by_status(status):
108
    if not status:
766 rajveer 109
        warehouses = Warehouse.query.all()
122 ashish 110
    else:
851 chandransh 111
        warehouses = Warehouse.query.filter_by(status=status).all()
112
    return warehouses
122 ashish 113
 
94 ashish 114
def get_all_warehouses_for_item(item_id):
635 rajveer 115
    item = get_item(item_id)
94 ashish 116
    if not item:
122 ashish 117
        raise InventoryServiceException(108, "Some unforeseen error while obtaining item")
118
    return item.get_all_warehouses
94 ashish 119
 
122 ashish 120
def get_all_items_for_warehouse(warehouse_id):
121
    warehouse = get_Warehouse(warehouse_id)
122
    if not warehouse:
123
        raise InventoryServiceException(108, "bad warehouse")
124
    return warehouse.all_items
125
 
94 ashish 126
def add_warehouse(warehouse):
103 ashish 127
    if not warehouse:
122 ashish 128
        raise InventoryServiceException(108, "Bad warehouse")
103 ashish 129
    if get_Warehouse(warehouse.id):
130
        #warehouse is already present.
122 ashish 131
        raise InventoryServiceException(101, "Warehouse already present")
103 ashish 132
 
94 ashish 133
    ds_warehouse = Warehouse()
134
    ds_warehouse.id = warehouse.id
135
    ds_warehouse.location = warehouse.location
122 ashish 136
    ds_warehouse.status = status.ACTIVE
103 ashish 137
    ds_warehouse.addedOn = datetime.datetime.now()
483 rajveer 138
    ds_warehouse.lastCheckedOn = datetime.datetime.now()
139
    ds_warehouse.tinNumber = warehouse.tinNumber
140
    ds_warehouse.pincode = warehouse.pincode
141
    if warehouse.vendorString:
142
        ds_warehouse.vendorString = warehouse.vendorString
94 ashish 143
    session.commit()
103 ashish 144
    return ds_warehouse.id
94 ashish 145
 
122 ashish 146
def update_item(item):
147
    if not item:
148
        raise InventoryServiceException(108, "Bad item in request")
149
 
150
    if not item.id:
609 chandransh 151
        raise InventoryServiceException(101, "Missing id for update")
122 ashish 152
 
2120 ankur.sing 153
    validate_item_prices(item)
2065 ankur.sing 154
 
635 rajveer 155
    ds_item = get_item(item.id)
122 ashish 156
 
157
    if not ds_item:
609 chandransh 158
        raise InventoryServiceException(101, "Item missing in our database")
122 ashish 159
 
963 chandransh 160
    if item.productGroup:
161
        ds_item.product_group = item.productGroup 
162
    if item.brand:
163
        ds_item.brand = item.brand
511 rajveer 164
    if item.modelNumber:
165
        ds_item.model_number = item.modelNumber
2497 ankur.sing 166
    ds_item.color = item.color
167
    ds_item.model_name = item.modelName
168
    ds_item.category = item.category
169
    ds_item.comments = item.comments
511 rajveer 170
 
2497 ankur.sing 171
    ds_item.catalog_item_id = item.catalogItemId
483 rajveer 172
 
2129 ankur.sing 173
    ds_item.mrp = item.mrp
174
    ds_item.sellingPrice = item.sellingPrice
2497 ankur.sing 175
 
2174 ankur.sing 176
    ds_item.weight = item.weight
2129 ankur.sing 177
 
2358 ankur.sing 178
    if ds_item.status != item.itemStatus:
2402 rajveer 179
        add_status_change_log(ds_item, item.itemStatus)
2358 ankur.sing 180
        ds_item.status = item.itemStatus
2035 rajveer 181
    if item.status_description:
182
        ds_item.status_description = item.status_description
122 ashish 183
 
511 rajveer 184
    if item.startDate:
2116 ankur.sing 185
        ds_item.startDate = to_py_date(item.startDate)
2497 ankur.sing 186
    else:
187
        ds_item.startDate = None
511 rajveer 188
    if item.retireDate:
2116 ankur.sing 189
        ds_item.retireDate = to_py_date(item.retireDate)
2497 ankur.sing 190
    else:
191
        ds_item.retireDate = None
511 rajveer 192
 
2497 ankur.sing 193
    ds_item.feature_id = item.featureId
194
    ds_item.feature_description = item.featureDescription
122 ashish 195
 
2129 ankur.sing 196
    ds_item.bestDealText = item.bestDealText
197
    ds_item.bestDealValue = item.bestDealValue
2065 ankur.sing 198
    ds_item.bestSellingRank = item.bestSellingRank
2497 ankur.sing 199
 
2065 ankur.sing 200
    ds_item.defaultForEntity = item.defaultForEntity
2251 ankur.sing 201
    ds_item.risky = item.risky
3359 chandransh 202
 
3459 chandransh 203
    if item.expectedDelay is not None:
3359 chandransh 204
        ds_item.expectedDelay = item.expectedDelay
205
 
206
    if item.preferredWarehouse:
207
        ds_item.preferredWarehouse = item.preferredWarehouse
4413 anupam.sin 208
 
209
    if item.defaultWarehouse:
210
        ds_item.defaultWarehouse = item.defaultWarehouse
4506 phani.kuma 211
 
212
    if item.preferredVendor:
213
        ds_item.preferredVendor = item.preferredVendor
4413 anupam.sin 214
 
215
    ds_item.isWarehousePreferenceSticky = item.isWarehousePreferenceSticky
3359 chandransh 216
 
2347 ankur.sing 217
    ds_item.updatedOn = datetime.datetime.now()
2065 ankur.sing 218
 
122 ashish 219
    session.commit();
220
    return ds_item.id
94 ashish 221
 
103 ashish 222
def add_item(item):
223
    if not item:
122 ashish 224
        raise InventoryServiceException(108, "Bad item in request")
635 rajveer 225
    if get_item(item.id):
122 ashish 226
        raise InventoryServiceException(101, "Item already exists")
2120 ankur.sing 227
 
228
    validate_item_prices(item)
229
 
103 ashish 230
    ds_item = Item()
963 chandransh 231
    if item.productGroup:
232
        ds_item.product_group = item.productGroup
233
    if item.brand:
234
        ds_item.brand = item.brand
515 rajveer 235
    if item.modelName:
236
        ds_item.model_name = item.modelName
237
    if item.modelNumber:
238
        ds_item.model_number = item.modelNumber
609 chandransh 239
    if item.color:
240
        ds_item.color = item.color
483 rajveer 241
    if item.category:
242
        ds_item.category = item.category
243
    if item.comments:
244
        ds_item.comments = item.comments
245
 
103 ashish 246
    ds_item.addedOn = datetime.datetime.now()
609 chandransh 247
    ds_item.updatedOn = datetime.datetime.now()
2116 ankur.sing 248
    if item.startDate:
249
        ds_item.startDate = to_py_date(item.startDate)
250
    if item.retireDate:
251
        ds_item.retireDate = to_py_date(item.retireDate)
609 chandransh 252
 
483 rajveer 253
    if item.mrp:
254
        ds_item.mrp = item.mrp
255
    if item.sellingPrice:
256
        ds_item.sellingPrice = item.sellingPrice
122 ashish 257
    if item.weight:
258
        ds_item.weight = item.weight
259
 
260
    if item.featureId:
261
        ds_item.feature_id = item.featureId
262
    if item.featureDescription:
263
        ds_item.feature_description = item.featureDescription
264
 
103 ashish 265
    if item.otherInfo:
266
        for k,v in item.otherInfo.iteritems():
267
            info = ItemInfo()
268
            info.key = k
269
            info.value = v
270
            ds_item.iteminfo.append(info)
2116 ankur.sing 271
 
103 ashish 272
    #check if categories present. If yes, add them to system
122 ashish 273
 
609 chandransh 274
    if item.bestDealValue:
275
        ds_item.bestDealValue = item.bestDealValue
276
    if item.bestDealText:
277
        ds_item.bestDealText = item.bestDealText
2116 ankur.sing 278
    if item.bestSellingRank:
279
        ds_item.bestSellingRank = item.bestSellingRank
280
    ds_item.defaultForEntity = item.defaultForEntity
2251 ankur.sing 281
    ds_item.risky = item.risky
609 chandransh 282
 
3467 chandransh 283
    if item.expectedDelay is not None:
3359 chandransh 284
        ds_item.expectedDelay = item.expectedDelay
3467 chandransh 285
    else:
286
        ds_item.expectedDelay = 0
3359 chandransh 287
 
288
    if item.preferredWarehouse:
289
        ds_item.preferredWarehouse = item.preferredWarehouse
290
 
2116 ankur.sing 291
    # Check if a similar item already exists in our database
4725 phani.kuma 292
    similar_item = Item.query.filter_by(brand=item.brand, model_number=item.modelNumber, model_name=item.modelName).first()
293
    print "[SIMILAR ITEM FOUND:] FOR {0} {1} {2}".format(item.brand, item.modelNumber, item.modelName)
2116 ankur.sing 294
 
295
    if similar_item is None or similar_item.catalog_item_id is None:
296
        # If there is no similar item in the database from before,
297
        # use the entity_id_generator
298
        entity_id = EntityIDGenerator.query.first()
299
        ds_item.catalog_item_id = entity_id.id + 1
300
        ds_item.status = status.IN_PROCESS
301
        ds_item.status_description = "This item is in process."
302
        entity_id.id = entity_id.id  + 1
4725 phani.kuma 303
        if similar_item is not None and similar_item.catalog_item_id is None:
304
            similar_item.catalog_item_id = entity_id.id
2116 ankur.sing 305
    else:
306
        #If a similar item already exists for a product group, brand and model_number, set it as same.
307
        ds_item.catalog_item_id = similar_item.catalog_item_id
308
        ds_item.category = similar_item.category
4762 phani.kuma 309
        ds_item.product_group = similar_item.product_group
2116 ankur.sing 310
        ds_item.status = similar_item.status
311
        ds_item.status_description = similar_item.status_description
312
 
103 ashish 313
    session.commit();
3325 chandransh 314
    return ds_item.id
315
 
316
def update_inventory_history(warehouse_id, timestamp, availability):
317
    warehouse = get_Warehouse(warehouse_id)
318
    if not warehouse:
319
        raise InventoryServiceException(107, "Warehouse? Where?")
4368 rajveer 320
    vendors = get_vendors_for_warehouse(warehouse_id)
321
    if len(vendors) > 1:
322
        raise InventoryServiceException(110, "Multiple vendors found for warehouse !")
323
    vendor = vendors[0]
3325 chandransh 324
    time = datetime.datetime.now()
325
    for item_key, quantity in availability.iteritems():
326
        try:
327
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
328
            item = vendor_item_mapping.item
329
        except:
330
            continue  
331
        try:
332
            item_inventory_history = ItemInventoryHistory()
333
            item_inventory_history.warehouse = warehouse
334
            item_inventory_history.item = item
335
            item_inventory_history.timestamp = time
336
            item_inventory_history.availibility = quantity
337
        except:
338
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
339
    session.commit()
103 ashish 340
 
483 rajveer 341
def update_inventory(warehouse_id, timestamp, availability):
342
    warehouse = get_Warehouse(warehouse_id)
343
    if not warehouse:
344
        raise InventoryServiceException(107, "Warehouse? Where?")
345
 
346
    time = datetime.datetime.now()
347
    warehouse.lastCheckedOn = time
348
    warehouse.vendorString = timestamp
4368 rajveer 349
    vendors = get_vendors_for_warehouse(warehouse_id)
350
    if len(vendors) > 1:
351
        raise InventoryServiceException(110, "Multiple vendors found for warehouse !")
352
    vendor = vendors[0]
2368 ankur.sing 353
    session.commit()
1368 chandransh 354
    for item_key, quantity in availability.iteritems():
483 rajveer 355
        try:
1368 chandransh 356
            vendor_item_mapping = VendorItemMapping.query.filter_by(vendor=vendor, item_key=item_key).one();
357
            item = vendor_item_mapping.item
494 rajveer 358
        except:
4873 mandeep.dh 359
            print 'Skipping update for ' + item_key + ' quantity ' + str(quantity) + ' warehouse id: ' + str(warehouse_id)
360
            __send_mail_for_missing_key(item_key, quantity, warehouse_id)
4748 mandeep.dh 361
            continue
494 rajveer 362
        try:
483 rajveer 363
            current_inventory_snapshot = CurrentInventorySnapshot.get_by(item=item, warehouse=warehouse)
364
            if not current_inventory_snapshot:
365
                current_inventory_snapshot = CurrentInventorySnapshot()
366
                current_inventory_snapshot.item = item
367
                current_inventory_snapshot.warehouse = warehouse
368
                current_inventory_snapshot.availibility = 0
871 chandransh 369
                current_inventory_snapshot.reserved = 0
483 rajveer 370
            # added the difference in the current inventory    
371
            current_inventory_snapshot.availibility = current_inventory_snapshot.availibility + quantity
4400 rajveer 372
            try:
373
                if quantity > 0 and __get_item_reserved(item) > 0:
374
                    cl = TransactionClient().get_client()
4448 rajveer 375
                    #FIXME hardcoding for warehouse id 
376
                    cl.addAlert(AlertType.NEW_INVENTORY_ALERT, 5, "Inventory received for item " + item.brand + " " + item.model_name + " " + item.model_number + " " +  item.color)
4400 rajveer 377
            except:
378
                print "Not able to raise alert for incoming inventory" 
4822 mandeep.dh 379
            if current_inventory_snapshot.availibility < 0:
380
                __send_alert_for_negative_availability(item, current_inventory_snapshot.availibility, warehouse)
483 rajveer 381
        except:
382
            raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
2368 ankur.sing 383
        session.commit() 
384
        check_risky_item(item)
483 rajveer 385
 
4822 mandeep.dh 386
def __send_alert_for_negative_reserved(item, reserved, warehouse):
4873 mandeep.dh 387
    itemName = " ".join([str(item.id), str(item.brand), str(item.model_name), str(item.model_number), str(item.color)])
388
    EmailAttachmentSender.mail('cnc.center@shop2020.in', '5h0p2o2o', 'mandeep.dhir@shop2020.in', 'Negative reserved: ' + str(reserved) + ' for Item Id: ' + itemName + ' warehouse id: ' + str(warehouse.id), None)
4822 mandeep.dh 389
 
390
def __send_alert_for_negative_availability(item, availability, warehouse):
4873 mandeep.dh 391
    itemName = " ".join([str(item.id), str(item.brand), str(item.model_name), str(item.model_number), str(item.color)])
392
    EmailAttachmentSender.mail('cnc.center@shop2020.in', '5h0p2o2o', 'mandeep.dhir@shop2020.in', 'Negative availability ' + str(availability) + ' for Item id: ' + itemName + ' warehouse id: ' + str(warehouse.id), None)
4822 mandeep.dh 393
 
4873 mandeep.dh 394
def __send_mail_for_missing_key(item_key, quantity, warehouse_id):
395
    if not MissedInventoryUpdate.get_by(itemKey = item_key, isIgnored = 1):
396
        # One email per product key mismatch
397
        if not MissedInventoryUpdate.get_by(itemKey = item_key):
398
            EmailAttachmentSender.mail('cnc.center@shop2020.in', '5h0p2o2o', ['mandeep.dhir@shop2020.in', 'chaitnaya.vats@shop2020.in'], 'Skipped inventory update for ' + item_key + ' quantity ' + str(quantity) + ' warehouse id: ' + str(warehouse_id), None)
399
        missedInventoryUpdate = MissedInventoryUpdate()
400
        missedInventoryUpdate.itemKey = item_key
401
        missedInventoryUpdate.quantity = quantity
402
        missedInventoryUpdate.isIgnored = 0
403
        missedInventoryUpdate.timestamp = datetime.datetime.now()
404
        missedInventoryUpdate.warehouseId = warehouse_id
4748 mandeep.dh 405
        session.commit()
406
 
4320 rajveer 407
def add_inventory(itemId, warehouseId, quantity):
408
    current_inventory_snapshot = CurrentInventorySnapshot.get_by(item_id=itemId, warehouse_id=warehouseId)
409
    if not current_inventory_snapshot:
410
        current_inventory_snapshot = CurrentInventorySnapshot()
411
        current_inventory_snapshot.item_id = itemId
412
        current_inventory_snapshot.warehouse_id = warehouseId
413
        current_inventory_snapshot.availibility = 0
414
        current_inventory_snapshot.reserved = 0
415
    # added the difference in the current inventory    
416
    current_inventory_snapshot.availibility = current_inventory_snapshot.availibility + quantity
4813 rajveer 417
    session.commit()
4822 mandeep.dh 418
    if current_inventory_snapshot.availibility < 0:
419
        __send_alert_for_negative_availability(get_item(itemId), current_inventory_snapshot.availibility, get_Warehouse(warehouseId))
4813 rajveer 420
    check_risky_item(get_item(itemId)) 
4320 rajveer 421
 
4431 phani.kuma 422
'''
94 ashish 423
def get_item_inventoy(item_id):
424
 
425
    inventory = Item.get_by(id=item_id).currentInventory
426
    if not inventory:
122 ashish 427
        raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
94 ashish 428
    return inventory
4431 phani.kuma 429
'''
94 ashish 430
 
635 rajveer 431
def get_item_inventory_by_item_id(item_id):
432
    inventory = Item.get_by(id=item_id).currentInventory
379 ashish 433
    if not inventory:
434
        raise InventoryServiceException(108, "Some unforeseen error while updating inventory")
435
    return inventory
436
 
103 ashish 437
 
438
def retire_warehouse(warehouse_id):
439
    if not warehouse_id:
122 ashish 440
        raise InventoryServiceException(101, "Bad warehouse id")
103 ashish 441
    warehouse = get_Warehouse(warehouse_id)
442
    if not warehouse:
122 ashish 443
        raise InventoryServiceException(108, "warehouse id not present")
444
    warehouse.status = status.DELETED;
103 ashish 445
    session.commit()
446
 
447
def retire_item(item_id):
448
    if not item_id:
122 ashish 449
        raise InventoryServiceException(101, "bad item id")
635 rajveer 450
    item = get_item(item_id)
103 ashish 451
    if not item:
122 ashish 452
        raise InventoryServiceException(108, "item id not present")
453
    item.status = status.PHASED_OUT
454
    item.retireDate = datetime.datetime.now()
103 ashish 455
    session.commit()
122 ashish 456
 
457
#need to implement threads based solution here
103 ashish 458
def start_item_on(item_id, timestamp):
459
    if not item_id:
122 ashish 460
        raise InventoryServiceException(101, "bad item id")
635 rajveer 461
    item = get_item(item_id)
103 ashish 462
    if not item:
122 ashish 463
        raise InventoryServiceException(108, "item id not present")
103 ashish 464
 
122 ashish 465
    item.status = status.ACTIVE
466
    item.startDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))
467
    add_status_change_log(item, status.ACTIVE)
103 ashish 468
    session.commit()
469
 
122 ashish 470
#need to implement threads here
103 ashish 471
def retire_item_on(item_id, timestamp):
472
    if not item_id:
122 ashish 473
        raise InventoryServiceException(101, "bad item id")
635 rajveer 474
    item = get_item(item_id)
103 ashish 475
    if not item:
122 ashish 476
        raise InventoryServiceException(108, "item id not present")
103 ashish 477
 
122 ashish 478
    item.status = status.PHASED_OUT
479
    item.retireDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))
480
    add_status_change_log(item, status.PHASED_OUT)
103 ashish 481
    session.commit()
482
 
483
def add_status_change_log(item, new_status):
484
    item_change_log = ItemChangeLog()
485
    item_change_log.new_status = new_status
486
    item_change_log.old_status = item.status
487
    item_change_log.timestamp = datetime.datetime.now()
488
    item_change_log.item = item
489
    session.commit()
490
 
491
def change_item_status(item_id, new_status):
492
    if not item_id:
122 ashish 493
        raise InventoryServiceException(101, "bad item id")
635 rajveer 494
    item = get_item(item_id)
103 ashish 495
    if not item:
122 ashish 496
        raise InventoryServiceException(108, "item id not present")
2116 ankur.sing 497
    add_status_change_log(item, new_status)
122 ashish 498
    item.status = new_status
2251 ankur.sing 499
    if item.status == status.PHASED_OUT:
500
        item.status_description = "This item has been phased out"
501
    elif item.status == status.DELETED:
502
        item.status_description = "This item has been deleted"
3924 rajveer 503
    elif item.status == status.PAUSED:
504
        item.status_description = "This item is currently out of stock"      
505
    elif item.status == status.PAUSED_BY_RISK:
506
        item.status_description = "This item is currently out of stock"
507
        #This will clear cache from tomcat
508
        __clear_homepage_cache()  
2251 ankur.sing 509
    elif item.status == status.ACTIVE:
510
        item.status_description = "This item is active"
511
    elif item.status == status.IN_PROCESS:
512
        item.status_description = "This item is in process"
513
    elif item.status == status.CONTENT_COMPLETE:
514
        item.status_description = "This item is in process"
103 ashish 515
    session.commit()
516
 
517
def get_item_availability_for_warehouse(warehouse_id, item_id):
518
    if not warehouse_id:
122 ashish 519
        raise InventoryServiceException(101, "bad warehouse_id")
103 ashish 520
    if not item_id:
122 ashish 521
        raise InventoryServiceException(101, "bad item_id")
103 ashish 522
 
523
    warehouse = get_Warehouse(warehouse_id)
524
    if not warehouse:
122 ashish 525
        raise InventoryServiceException(108, "warehouse does not exist")
635 rajveer 526
    item = get_item(item_id)
504 rajveer 527
 
103 ashish 528
    if not item:
766 rajveer 529
        raise InventoryServiceException(108, "item does not exist")
122 ashish 530
 
494 rajveer 531
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id)
504 rajveer 532
    query = query.filter_by(item_id = item.id)
494 rajveer 533
    try:
534
        current_inventory_snapshot = query.one()
871 chandransh 535
        return current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
494 rajveer 536
    except:
537
        return 0
538
    """
539
    current_inventory_snapshot = CurrentInventorySnapshot.query.filter(CurrentInventorySnapshot.warehouse_id == warehouse_id, CurrentInventorySnapshot.item_id == item_id).one()
103 ashish 540
    if not current_inventory_snapshot:
541
        return 0
542
    else:
543
        return current_inventory_snapshot.availibility
494 rajveer 544
    """
643 chandransh 545
 
2368 ankur.sing 546
def check_risky_item(item):
2251 ankur.sing 547
    if not item.risky:
548
        return
4813 rajveer 549
    warehouse_ids = None
550
    if item.isWarehousePreferenceSticky :
551
        warehouse_ids = [item.preferredWarehouse]
552
    availability = __get_item_availability(item, warehouse_ids)
2983 chandransh 553
    if availability <= 0:
2251 ankur.sing 554
        if item.status == status.ACTIVE:
2984 rajveer 555
            change_item_status(item.id, status.PAUSED_BY_RISK)
4797 rajveer 556
            __send_mail_for_oos_item(item)
2251 ankur.sing 557
    else:
2984 rajveer 558
        if item.status == status.PAUSED_BY_RISK:
2251 ankur.sing 559
            change_item_status(item.id, status.ACTIVE)
2368 ankur.sing 560
    session.commit()
2251 ankur.sing 561
 
4406 anupam.sin 562
'''
563
This method returns quantity of a particular item across all warehouses whose ids is provided
564
if warehouse_ids is null it checks for inventory in all warehouses.
565
'''
566
def __get_item_availability(item, warehouse_ids):
567
    if warehouse_ids is None:
568
        all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
569
        availability = 0
570
        reserved = 0
571
        for currInv in all_inventory:
572
            availability = availability + currInv.availibility
573
            reserved = reserved + currInv.reserved
574
        return availability - reserved
575
    else:
576
        total_availability = 0
577
        for warehouse_id in warehouse_ids:
578
            try:
579
                current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item.id).one()
580
                availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
581
            except Exception as e:
582
                print e
583
                availability = 0    
584
            total_availability = total_availability + availability
585
        return total_availability 
4400 rajveer 586
 
587
def __get_item_reserved(item):
588
    all_inventory = CurrentInventorySnapshot.query.filter_by(item = item).all()
589
    reserved = 0
590
    for currInv in all_inventory:
591
        reserved = reserved + currInv.reserved
592
    return reserved
2983 chandransh 593
 
871 chandransh 594
def reserve_item_in_warehouse(item_id, warehouse_id, quantity):    
595
    if not warehouse_id:
596
        raise InventoryServiceException(101, "bad warehouse_id")
2251 ankur.sing 597
    item = get_item(item_id)
598
    if not item:
871 chandransh 599
        raise InventoryServiceException(101, "bad item_id")
600
 
601
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
602
    try:
603
        current_inventory_snapshot = query.one()
604
    except:
4103 chandransh 605
        current_inventory_snapshot = CurrentInventorySnapshot()
606
        current_inventory_snapshot.warehouse_id = warehouse_id
607
        current_inventory_snapshot.item_id = item_id
608
        current_inventory_snapshot.availibility = 0
609
        current_inventory_snapshot.reserved = 0
610
 
611
    current_inventory_snapshot.reserved = current_inventory_snapshot.reserved + quantity
612
    session.commit()
613
    check_risky_item(item)
614
    return True
871 chandransh 615
 
616
def reduce_reservation_count(item_id, warehouse_id, quantity):
617
    if not warehouse_id:
618
        raise InventoryServiceException(101, "bad warehouse_id")
2251 ankur.sing 619
    item = get_item(item_id)
620
    if not item:
871 chandransh 621
        raise InventoryServiceException(101, "bad item_id")
622
 
623
    query = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id)
624
    try:
625
        current_inventory_snapshot = query.one()
626
        current_inventory_snapshot.reserved = current_inventory_snapshot.reserved - quantity
4318 rajveer 627
        ##FIXME In case of our own warehouse reduce availability also
628
        if warehouse_id == 7:
4335 rajveer 629
            current_inventory_snapshot.availibility = current_inventory_snapshot.availibility - quantity
871 chandransh 630
        session.commit()
2368 ankur.sing 631
        check_risky_item(item)
4822 mandeep.dh 632
        if current_inventory_snapshot.reserved < 0:
633
            __send_alert_for_negative_reserved(get_item(item_id), current_inventory_snapshot.reserved, get_Warehouse(warehouse_id))
871 chandransh 634
        return True
635
    except:
636
        print "Unexpected error:", sys.exc_info()[0]
637
        return False
638
 
2075 rajveer 639
def mark_item_as_content_complete(entity_id, category, brand, modelName, modelNumber):
2828 rajveer 640
    '''
641
    Get all the items for this entityID and update category, brand, modelName and modelNumber for all.
642
    Update Status for only IN_PROCESS items to CONTENT_COMPLETE
643
    '''
723 chandransh 644
    content_complete_status = status.CONTENT_COMPLETE
2828 rajveer 645
    items = Item.query.filter_by(catalog_item_id=entity_id).all()
723 chandransh 646
    current_timestamp = datetime.datetime.now()
647
    for item in items:
2828 rajveer 648
        if item.status == status.IN_PROCESS:
649
            item.status = content_complete_status
650
            item_change_log = ItemChangeLog()
651
            item_change_log.old_status = item.status
652
            item_change_log.new_status = content_complete_status
653
            item_change_log.timestamp = current_timestamp
654
            item_change_log.item = item
723 chandransh 655
 
4762 phani.kuma 656
        category_object = get_category(category)
657
        if category_object is not None:
658
            item.category = category
659
            item.product_group = category_object.display_name
2075 rajveer 660
        item.brand = brand
2081 rajveer 661
        item.model_name = modelName
662
        item.model_number = modelNumber
723 chandransh 663
        item.updatedOn = current_timestamp
664
    session.commit()
665
    return True
1294 chandransh 666
 
643 chandransh 667
def get_item_availability_for_location(warehouse_loc, item_id):
3355 chandransh 668
    """
669
    Determines the warehouse that should be used to fulfil an order for the given item.
4406 anupam.sin 670
    It first checks whether the preferred warehouse for that item is set or not. If set 
671
    and preference is sticky then that warehouse is used for fulfilment.
672
    If preference is not sticky then we see if item is available in the preferred WH,
673
    in which case that warehouse is used otherwise we use that warehouse which has the max
674
    availability. And if there is no inventory for that item in any warehouses then we use
675
    default warehouse.
676
    If preference is not set in that case we just find the warehouse with max availability
677
    and in case of zero inventory we use default warehouse
3355 chandransh 678
 
679
    Returns an ordered list of size 4 with following elements in the given order:
680
    1. Logistics location of the warehouse which was finally picked up to ship the order.
681
    2. Id of the warehouse which was finally picked up.
682
    3. Inventory size in the selected warehouse.
683
    4. Expected delay added by the category manager.
684
 
685
    Parameters:
686
     - warehouse_loc
687
     - item_id
688
    """
643 chandransh 689
    if warehouse_loc is None:
690
        raise InventoryServiceException(101, "Bad Warehouse Location")
691
    if not item_id:
1416 chandransh 692
        raise InventoryServiceException(101, "Bad Item id")
643 chandransh 693
 
1416 chandransh 694
    item = Item.get_by(id=item_id)
4406 anupam.sin 695
    logisticsLocation = warehouse_loc
696
    warehouses = Warehouse.query.filter_by(logisticsLocation=logisticsLocation).all()
643 chandransh 697
    warehouse_ids = [warehouse.id for warehouse in warehouses]
698
    warehouse_retid = -1
4406 anupam.sin 699
 
3503 chandransh 700
    total_availability = 0
4406 anupam.sin 701
    '''
702
    If warehouse preference is set and it is sticky then we should fulfil this order from this warehouse only.
703
    But we still need to calculate total availability across warehouses.
704
    '''
705
    if (item.isWarehousePreferenceSticky and item.preferredWarehouse is not None) :
706
        warehouse_retid = item.preferredWarehouse
707
        warehouse = Warehouse.get_by(id=warehouse_retid)
708
        logisticsLocation = warehouse.logisticsLocation
4476 anupam.sin 709
        total_availability = __get_item_availability(item, [warehouse_retid])
4406 anupam.sin 710
 
711
    #If preference is not sticky then this order should be fulfilled from preferred WH if inventory available
712
    #otherwise we should check for its availability elsewhere and fulfil this order from there, but if it is not available anywhere
713
    #then we should fulfil this order from its default warehouse.
714
 
715
    elif (not item.isWarehousePreferenceSticky and item.preferredWarehouse is not None) :
785 rajveer 716
        try:
4406 anupam.sin 717
            current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = item.preferredWarehouse, item_id = item_id).one()
871 chandransh 718
            availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
4317 varun.gupt 719
        except Exception as e:
720
            print e
785 rajveer 721
            availability = 0    
4406 anupam.sin 722
        if availability > 0:
723
            warehouse_retid = item.preferredWarehouse
4476 anupam.sin 724
            total_availability = availability
4406 anupam.sin 725
        else :
726
            [logisticsLocation, warehouse_retid, total_availability] = \
727
                        __get_warehouse_with_max_availability(warehouse_loc = warehouse_loc, \
728
                                                            warehouse_ids = warehouse_ids, item = item)
729
 
730
    else :
731
        [logisticsLocation, warehouse_retid, total_availability] = \
732
                        __get_warehouse_with_max_availability(warehouse_loc = warehouse_loc, \
733
                                                            warehouse_ids = warehouse_ids, item = item)
2341 chandransh 734
 
4406 anupam.sin 735
    if item.expectedDelay is None:
736
        print 'expectedDelay field for this item was Null. Resetting it to 0'
737
        item.expectedDelay = 0
738
 
739
    ## FIXME Assign warehouse 5 (9D2) for all the hotspot products.
740
    #if warehouse_retid in [warehouse.id for warehouse in get_warehouses_for_vendor(1)]:
4433 anupam.sin 741
    if int(warehouse_retid) in [1,2,3,4,5]:
4406 anupam.sin 742
        warehouse_retid = 5
743
        warehouse = Warehouse.get_by(id=warehouse_retid)
744
        logisticsLocation = warehouse.logisticsLocation  
745
 
746
    return [logisticsLocation, int(warehouse_retid), total_availability, int(item.expectedDelay)]
747
 
748
def __get_warehouse_with_max_availability(warehouse_loc, warehouse_ids, item):
749
 
750
    warehouse_retid = -1
751
    max_availability = 0
752
    total_availability = 0
753
 
754
    for warehouse_id in warehouse_ids:
755
            try:
756
                current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item.id).one()
757
                availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
758
            except Exception as e:
759
                print e
760
                availability = 0    
761
            if availability > max_availability:
762
                warehouse_retid = warehouse_id
763
                max_availability = availability
764
            total_availability = total_availability + availability
765
 
766
    #If no warehouse could be found, use the default warehouse for this item
643 chandransh 767
    if warehouse_retid == -1:
759 chandransh 768
        # This is the case when all warehouses have exhausted their
769
        # inventory of this item or no warehouse is available in this
770
        # location.
4406 anupam.sin 771
        warehouse_retid = int(item.defaultWarehouse)
2344 chandransh 772
        warehouse = Warehouse.get_by(id=warehouse_retid)
4406 anupam.sin 773
        warehouse_loc = warehouse.logisticsLocation
2341 chandransh 774
        try:
4406 anupam.sin 775
            current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_retid, item_id = item.id).one()
3503 chandransh 776
            max_availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
4317 varun.gupt 777
        except Exception as e:
778
            print e
3503 chandransh 779
            max_availability = 0
780
        total_availability = max_availability
643 chandransh 781
 
4406 anupam.sin 782
    return [warehouse_loc, warehouse_retid, total_availability]
783
'''    
784
def calculate_total_availability(warehouse_ids, item_id):
785
    total_availability = 0
786
    for warehouse_id in warehouse_ids:
787
            try:
788
                current_inventory_snapshot = CurrentInventorySnapshot.query.filter_by(warehouse_id = warehouse_id, item_id = item_id).one()
789
                availability = current_inventory_snapshot.availibility - current_inventory_snapshot.reserved
790
            except Exception as e:
791
                print e
792
                availability = 0    
793
            total_availability = total_availability + availability
794
    return total_availability
795
'''
2341 chandransh 796
 
122 ashish 797
def get_warehouses_for_item(item_id):
643 chandransh 798
 
122 ashish 799
    if not item_id:
800
        raise InventoryServiceException(101, "bad item_id")
635 rajveer 801
    item = get_item(item_id)
122 ashish 802
 
803
    if not item:
804
        raise InventoryServiceException(101, "bad item")
805
 
483 rajveer 806
    warehouses = item.currentInventory.warehouse
501 rajveer 807
    return warehouses
808
 
2404 chandransh 809
def get_child_categories(category):
810
    cm = CategoryManager()
2621 varun.gupt 811
    cat = cm.getCategory(category)
812
    return cat.children_category_ids if cat else None
2404 chandransh 813
 
626 chandransh 814
def get_best_sellers(start_index, stop_index, category=-1):
2404 chandransh 815
    '''
816
    Returns the Best Sellers between the start and the stop index in the given category
817
    '''
1926 rajveer 818
    query = get_best_sellers_query(category, None)
1098 chandransh 819
    best_sellers = query.all()[start_index:stop_index]
621 chandransh 820
    return get_thrift_item_list(best_sellers)
821
 
2093 chandransh 822
def get_best_sellers_count(category=-1):
2404 chandransh 823
    '''
824
    Returns the number of best sellers in the given category
825
    '''
1926 rajveer 826
    count = get_best_sellers_query(category, None).count()
1120 rajveer 827
    if count is None:
828
        count = 0
766 rajveer 829
    return count
621 chandransh 830
 
1926 rajveer 831
def get_best_sellers_catalog_ids(start_index, stop_index, brand, category=-1):
2404 chandransh 832
    '''
833
    Returns the Best sellers for the given brand and category between the start and the stop index.
834
    Ignores the category if it's passed as -1 and the brand if it's passed as None. 
835
    '''
1926 rajveer 836
    query = get_best_sellers_query(category, brand)
1098 chandransh 837
    best_sellers = query.all()[start_index:stop_index]
621 chandransh 838
    return [item.catalog_item_id for item in best_sellers]
1970 rajveer 839
 
1926 rajveer 840
def get_best_sellers_query(category, brand):
2404 chandransh 841
    '''
842
    Returns the query to be used for getting Best Sellers.
843
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
844
    '''
1098 chandransh 845
    query = Item.query.filter_by(status=status.ACTIVE).filter(Item.bestSellingRank != None)
626 chandransh 846
    if category != -1:
1970 rajveer 847
        all_categories = [category]
848
        child_categories = get_child_categories(category)
849
        if child_categories is not None:
850
            all_categories = all_categories + child_categories 
851
        query = query.filter(Item.category.in_(all_categories))
1926 rajveer 852
    if brand is not None:
853
        query = query.filter_by(brand=brand)
1098 chandransh 854
    query = query.order_by(asc(Item.bestSellingRank))
621 chandransh 855
    return query
609 chandransh 856
 
1098 chandransh 857
def get_best_deals(category=-1):
2404 chandransh 858
    '''
859
    Returns the Best deals in the given category. Ignores the category if it's passed as -1.
860
    '''
861
    query = get_best_deals_query(Item, category, None)
1098 chandransh 862
    items = query.all()
609 chandransh 863
    return get_thrift_item_list(items)
864
 
1098 chandransh 865
def get_best_deals_count(category=-1):
2404 chandransh 866
    '''
867
    Returns the count of best deals in the given category.
868
    Ignores the category if it's -1.
869
    '''
870
    count = get_best_deals_counting_query(func.count(distinct(Item.catalog_item_id)), category, None).scalar()
1120 rajveer 871
    if count is None:
872
        count = 0
766 rajveer 873
    return count
501 rajveer 874
 
1926 rajveer 875
def get_best_deals_catalog_ids(start_index, stop_index, brand, category=-1):
2404 chandransh 876
    '''
877
    Returns the catalog_item_ids of best deal items for the given brand and category.
878
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
879
    '''
880
    query = get_best_deals_query(Item, category, brand)
1098 chandransh 881
    best_deal_items = query.all()[start_index:stop_index]
882
    return [item.catalog_item_id for item in best_deal_items]
883
 
2404 chandransh 884
def get_best_deals_counting_query(obj, category, brand):
885
    '''
886
    Returns the query to be used to select the best deals in the given brand and category.
887
    Ignores the category if it's passed as -1 and the brand if it's passed as None. 
888
    '''
889
    query = session.query(obj).filter_by(status=status.ACTIVE).filter(Item.bestDealValue != None)
626 chandransh 890
    if category != -1:
1970 rajveer 891
        all_categories = [category]
892
        child_categories = get_child_categories(category)
893
        if child_categories is not None:
894
            all_categories = all_categories + child_categories 
895
        query = query.filter(Item.category.in_(all_categories))
1926 rajveer 896
    if brand is not None:
897
        query = query.filter_by(brand=brand)
2404 chandransh 898
    return query
899
 
900
def get_best_deals_query(obj, category, brand):
901
    '''
902
    Returns the query to be used to get the best deals in the given category and brand.
903
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
904
    '''
905
    query = get_best_deals_counting_query(obj, category, brand)
1098 chandransh 906
    query = query.group_by(Item.catalog_item_id).order_by(desc(Item.bestDealValue))
907
    return query
609 chandransh 908
 
1098 chandransh 909
def get_latest_arrivals(limit, category=-1):
2404 chandransh 910
    '''
911
    Returns up to limit number of Latest Arrivals in the given category.
912
    '''
2975 chandransh 913
    categories = []
914
    if category != -1:
915
        categories = [category]
916
    query = get_latest_arrivals_query(Item, categories, None)
1098 chandransh 917
    items = query.all()[0:limit]
609 chandransh 918
    return get_thrift_item_list(items)
598 chandransh 919
 
1098 chandransh 920
def get_latest_arrivals_count(limit, category=-1):
2404 chandransh 921
    '''
922
    Returns the number of latest arrivals which will be displayed on the website.
3016 chandransh 923
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 924
    '''
2975 chandransh 925
    categories = []
926
    if category != -1:
927
        categories = [category]
928
    count = get_latest_arrivals_counting_query(func.count(distinct(Item.catalog_item_id)), categories, None).scalar()
1120 rajveer 929
    if count is None:
930
        count = 0
931
    count = min(count, limit)
766 rajveer 932
    return count
602 chandransh 933
 
2975 chandransh 934
def get_latest_arrivals_catalog_ids(start_index, stop_index, brand, categories=[]):
2404 chandransh 935
    '''
936
    Returns the catalog_item_ids of the latest arrivals between the start and the stop index
3016 chandransh 937
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 938
    '''
2975 chandransh 939
    query = get_latest_arrivals_query(Item, categories, brand)
1098 chandransh 940
    latest_arrivals = query.all()[start_index:stop_index]
941
    return [item.catalog_item_id for item in latest_arrivals]
942
 
2975 chandransh 943
def get_latest_arrivals_counting_query(obj, categories, brand):
2404 chandransh 944
    '''
945
    Returns the query to be used to count Latest arrivals.
3016 chandransh 946
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 947
    '''
948
    query = session.query(obj).filter_by(status=status.ACTIVE)
2975 chandransh 949
 
950
    all_categories = []
951
    for category in categories:
952
        all_categories.append(category)
1970 rajveer 953
        child_categories = get_child_categories(category)
2975 chandransh 954
        if child_categories:
955
            all_categories = all_categories + child_categories
956
    if all_categories: 
1970 rajveer 957
        query = query.filter(Item.category.in_(all_categories))
2975 chandransh 958
 
1926 rajveer 959
    if brand is not None:
960
        query = query.filter_by(brand=brand)
2404 chandransh 961
    return query
962
 
2975 chandransh 963
def get_latest_arrivals_query(obj, categories, brand):
2404 chandransh 964
    '''
965
    Returns the query to be used to retrieve Latest Arrivals.
966
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
967
    '''
2975 chandransh 968
    query = get_latest_arrivals_counting_query(obj, categories, brand)
1098 chandransh 969
    query = query.group_by(Item.catalog_item_id).order_by(desc(Item.startDate))
970
    return query
609 chandransh 971
 
972
def get_thrift_item_list(items):
1098 chandransh 973
    return [to_t_item(item) for item in items if item != None]
635 rajveer 974
 
1155 rajveer 975
def generate_new_entity_id():
976
    generator =  EntityIDGenerator.query.one()
977
    id = generator.id + 1
978
    generator.id = id
979
    session.commit()
980
    return id
981
 
635 rajveer 982
def put_category_object(object):
983
    category = Category.get_by(id=1)
984
    if category is None:
985
        category = Category()
986
    category.object = object    
987
    session.commit()
988
    return True
989
 
990
def get_category_object():
766 rajveer 991
    object = Category.get_by(id=1).object
992
    return object
993
 
4283 anupam.sin 994
def get_item_pricing(item_id, vendorId):
1341 chandransh 995
    item = Item.query.filter_by(id=item_id).first()
996
    if item is None:
997
        raise InventoryServiceException(101, "Bad Item")
4307 anupam.sin 998
    '''
999
    if vendor id is -1 then we calculate an average transfer price to be populated
1000
    at the time of order creation. This will be later updated with actual transfer price
1001
    at the time of billing.
1002
    '''
1003
    if(vendorId == -1):
4543 anupam.sin 1004
        total = 0
4307 anupam.sin 1005
        try:
4858 anupam.sin 1006
            if item.preferredWarehouse is not None:
1007
                warehouse = Warehouse.query.filter_by(id=item.preferredWarehouse).first()
1008
                vendors = warehouse.vendors
1009
                item_pricings = []
1010
                for vendor in vendors :
1011
                    item_pricing = VendorItemPricing.query.filter_by(item=item, vendor=vendor).first()
1012
                    if item_pricing :
1013
                        item_pricings.append(item_pricing)
1014
            else :
1015
                item_pricings = VendorItemPricing.query.filter_by(item=item).all()
4315 anupam.sin 1016
            if item_pricings:
4307 anupam.sin 1017
                for item_pricing in item_pricings:
4543 anupam.sin 1018
                    total += item_pricing.transfer_price
4315 anupam.sin 1019
                avg = total / len(item_pricings)
1020
                item_pricing.transfer_price = avg
4543 anupam.sin 1021
            else:
1022
                item_pricing = VendorItemPricing()
1023
                item_pricing.transfer_price = item.sellingPrice
1024
                vendor = Vendor()
1025
                vendor.id = vendorId
1026
                item_pricing.vendor = vendor
1027
                item_pricing.item = item
1028
 
1029
            return item_pricing
4307 anupam.sin 1030
        except:
1031
            raise InventoryServiceException(101, "Item pricing not found ")
4283 anupam.sin 1032
    vendor = Vendor.get_by(id=vendorId)    
1341 chandransh 1033
    try:
1034
        item_pricing = VendorItemPricing.query.filter_by(vendor=vendor, item=item).one()
1347 chandransh 1035
        return item_pricing
3244 chandransh 1036
    except MultipleResultsFound:
1341 chandransh 1037
        raise InventoryServiceException(110, "Multiple pricing information present for Vendor: " + vendor.name + " and Item: " + str(item_id))
3244 chandransh 1038
    except NoResultFound:
1341 chandransh 1039
        raise InventoryServiceException(111, "Missing pricing information for Vendor: " + vendor.name + " and Item: " + str(item_id))
1040
 
1970 rajveer 1041
def add_category(t_category):
1042
    category = Category.get_by(id=t_category.id)
1043
    if category is None:
1044
        category = Category()
1045
    category.id = t_category.id 
1046
    category.label = t_category.label
1047
    category.description = t_category.description
4762 phani.kuma 1048
    category.display_name = t_category.display_name
1970 rajveer 1049
    category.parent_category_id = t_category.parent_category_id 
1050
    session.commit()
1051
    return True
1052
 
1053
def get_category(id):
1054
    return Category.query.filter_by(id=id).first()
1055
 
1056
def get_all_categories():
1057
    return Category.query.all()
1058
 
1991 ankur.sing 1059
 
1060
def get_all_item_pricing(item_id):
1061
    item = Item.query.filter_by(id=item_id).first()
1062
    if item is None:
1063
        raise InventoryServiceException(101, "Bad Item")
1064
    item_pricing = VendorItemPricing.query.filter_by(item=item).all()
1065
    return item_pricing
1066
 
2116 ankur.sing 1067
def get_item_mappings(item_id):
1068
    item = Item.query.filter_by(id=item_id).first()
1069
    if item is None:
1070
        raise InventoryServiceException(101, "Bad Item")
1071
    item_mappings = VendorItemMapping.query.filter_by(item=item).all()
1072
    return item_mappings
1073
 
1074
def add_vendor_pricing(vendorItemPricing):
1991 ankur.sing 1075
    if not vendorItemPricing:
1076
        raise InventoryServiceException(108, "Bad vendorItemPricing in request")
1077
    vendorId = vendorItemPricing.vendorId
1078
    itemId = vendorItemPricing.itemId
1079
 
1080
    try:
1081
        vendor = Vendor.query.filter_by(id=vendorId).one()
1082
    except:
1083
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
1084
 
1085
    try:
1086
        item = Item.query.filter_by(id=itemId).one()
1087
    except:
1088
        raise InventoryServiceException(101, "Item not found for vendorId " + str(itemId))
1089
 
2120 ankur.sing 1090
    validate_vendor_prices(to_t_item(item), vendorItemPricing)
2065 ankur.sing 1091
 
1991 ankur.sing 1092
    try:
1093
        ds_vendorItemPricing = VendorItemPricing.query.filter(and_(VendorItemPricing.vendor==vendor, VendorItemPricing.item==item)).one()
1094
    except:
2116 ankur.sing 1095
        ds_vendorItemPricing = VendorItemPricing()
1096
        ds_vendorItemPricing.vendor = vendor
1097
        ds_vendorItemPricing.item = item
1991 ankur.sing 1098
 
1099
    if vendorItemPricing.mop:
1100
        ds_vendorItemPricing.mop = vendorItemPricing.mop
1101
    if vendorItemPricing.dealerPrice:
1102
        ds_vendorItemPricing.dealerPrice = vendorItemPricing.dealerPrice
1103
    if vendorItemPricing.transferPrice:
2065 ankur.sing 1104
        ds_vendorItemPricing.transfer_price = vendorItemPricing.transferPrice
1991 ankur.sing 1105
 
1106
    session.commit()
1107
    return
1108
 
2358 ankur.sing 1109
def add_vendor_item_mapping(key, vendorItemMapping):
2116 ankur.sing 1110
    if not vendorItemMapping:
1111
        raise InventoryServiceException(108, "Bad vendorItemMapping in request")
1112
    vendorId = vendorItemMapping.vendorId
1113
    itemId = vendorItemMapping.itemId
1114
 
1115
    try:
1116
        vendor = Vendor.query.filter_by(id=vendorId).one()
1117
    except:
1118
        raise InventoryServiceException(101, "Vendor not found for vendorId " + str(vendorId))
1119
 
1120
    try:
1121
        item = Item.query.filter_by(id=itemId).one()
1122
    except:
1123
        raise InventoryServiceException(101, "Item not found for vendorId " + str(itemId))
1124
 
1125
    try:
2358 ankur.sing 1126
        ds_vendorItemMapping = VendorItemMapping.query.filter(and_(VendorItemMapping.vendor==vendor, VendorItemMapping.item==item, VendorItemMapping.item_key==key)).one()
2116 ankur.sing 1127
    except:
1128
        ds_vendorItemMapping = VendorItemMapping()
1129
        ds_vendorItemMapping.vendor = vendor
1130
        ds_vendorItemMapping.item = item
1131
    ds_vendorItemMapping.item_key = vendorItemMapping.itemKey
1132
 
1133
    session.commit()
1134
    return
1135
 
2120 ankur.sing 1136
def validate_item_prices(item):
2129 ankur.sing 1137
    if item.mrp == None or item.sellingPrice == None or item.mrp == "" or item.sellingPrice == "":
1138
        return
1139
    if item.mrp < item.sellingPrice:
2120 ankur.sing 1140
        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))
1141
        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 1142
    return
2120 ankur.sing 1143
 
1144
def validate_vendor_prices(item, vendorPrices):
2129 ankur.sing 1145
    if item.mrp != None and item.mrp != "" and vendorPrices.mop != "" and item.mrp <  vendorPrices.mop:
2120 ankur.sing 1146
        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))
1147
        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)))
1148
    if vendorPrices.mop != "" and vendorPrices.transferPrice != "" and vendorPrices.transferPrice > vendorPrices.mop:
1149
        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))
1150
        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)))
1151
    return
2065 ankur.sing 1152
 
1153
def get_all_vendors():
1154
    return Vendor.query.all()
1155
 
4725 phani.kuma 1156
def check_color_valid(color):
1157
    if color is not None:
1158
        color = color.strip().lower()
1159
        if color != '' and color != 'na' and color != 'blank' and color != '(blank)':
1160
            return True
1161
    return False
1162
 
1163
def check_similar_item(brand, model_number, model_name, color):
2129 ankur.sing 1164
    query = Item.query
2428 ankur.sing 1165
    query = query.filter_by(brand=brand)
1166
    query = query.filter_by(model_number=model_number)
4725 phani.kuma 1167
    query = query.filter_by(model_name=model_name)
1168
    similar_items = query.all()
1169
    item = None
1170
    # Check if a similar item already exists in our database
1171
    for old_item in similar_items:
1172
        if old_item.color != None and old_item.color.strip().lower() == color.strip().lower():
1173
            item = old_item
1174
            break
1175
 
1176
    # Check if a similar item already exists in our database with out valid color if similar item with same color is not found
2116 ankur.sing 1177
    if item is None:
4725 phani.kuma 1178
        for old_item in similar_items:
1179
            if not check_color_valid(old_item.color):
1180
                item = old_item
1181
                break
1182
    i = 0
1183
    color_of_similar_item = None
1184
    # Check if a similar item already exists in our database to be used to get catalog_item_id
1185
    for old_item in similar_items:
1186
        # get a similar item already existing in our database with valid color
1187
        if check_color_valid(old_item.color):
1188
            similar_item = old_item
1189
            color_of_similar_item = similar_item.color
1190
            break
1191
        i = i + 1
1192
        # get a similar item already existing in our database if similar item with valid color is not found
1193
        if i == len(similar_items):
1194
            similar_item = old_item
1195
            color_of_similar_item = similar_item.color
1196
 
1197
    # Check if a similar item that is obtained above is having a valid color
1198
    if check_color_valid(color_of_similar_item):
1199
        # if a similar item that is obtained above is having a valid color and new item is about to be created with out valid color it is not done.
1200
        # since for example if their is a item with red color in our database and we are creating a new item with no color for the same product which is wrong.
1201
        if item is None and not check_color_valid(color):
1202
            return similar_item.id
1203
 
1204
    if item is None:
2116 ankur.sing 1205
        return 0
1206
    else:
1207
        return item.id
2286 ankur.sing 1208
 
1209
def change_risky_flag(item_id, risky):
1210
    item = get_item(item_id)
1211
    if not item:
1212
        raise InventoryServiceException(101, "Item missing in our database")
1213
    try:
1214
        log_risky_flag(item_id, risky)
1215
    except:
1216
        print "Not able to log risky flag change"
1217
    item.risky = risky
4295 varun.gupt 1218
    if not risky and item.status == status.PAUSED_BY_RISK:
2368 ankur.sing 1219
        change_item_status(item.id, status.ACTIVE)
2286 ankur.sing 1220
    session.commit()
1221
 
4762 phani.kuma 1222
def get_items_by_category(categoryName):
1223
    if not categoryName:
1224
        raise InventoryServiceException(101, "Invalid category in request")
1225
    categories = ["Handsets", "Tablets", "Laptops"]
1226
    if categoryName == "Accessories":
4843 phani.kuma 1227
        query = Item.query.filter(Item.status != status.PHASED_OUT).filter(~Item.product_group.in_(categories))
4762 phani.kuma 1228
    elif categoryName == "Handsets":
4843 phani.kuma 1229
        query = Item.query.filter(Item.status != status.PHASED_OUT).filter(Item.product_group.in_(categories))
2358 ankur.sing 1230
    items = query.all()
1231
    return items
2116 ankur.sing 1232
 
2358 ankur.sing 1233
def get_risky_items():
1234
    items = Item.query.filter_by(risky=True).all()
1235
    return items
3008 rajveer 1236
 
2809 rajveer 1237
def get_similar_items_catalog_ids(start_index, stop_index, itemId):
3008 rajveer 1238
    query = SimilarItems.query.filter_by(item_id=itemId).limit(stop_index-start_index)
1239
    similar_items = query.all()
3289 rajveer 1240
    return_list = []
1241
    for similar_item in similar_items:
1242
        isActive = False
1243
        try:
1244
            all_items = Item.query.filter_by(catalog_item_id=similar_item.catalog_item_id).all()
1245
        except:
1246
            continue
1247
        for item in all_items:
1248
            isActive = isActive or item.status == status.ACTIVE
1249
        if isActive:
1250
            return_list.append(similar_item.catalog_item_id)
1251
    return return_list
4423 phani.kuma 1252
 
1253
def get_all_similar_items_catalog_ids(itemId):
1254
    query = SimilarItems.query.filter_by(item_id=itemId)
1255
    similar_items = query.all()
1256
    return_list = []
1257
    for similar_item in similar_items:
1258
        item_query = Item.query.filter_by(catalog_item_id=similar_item.catalog_item_id).limit(1)
1259
        item = item_query.one()
1260
        return_list.append(item)
2809 rajveer 1261
 
4423 phani.kuma 1262
    return get_thrift_item_list(return_list)
1263
 
1264
def add_similar_item_catalog_id(itemId, catalog_item_id):
1265
    if not itemId or not catalog_item_id:
1266
        raise InventoryServiceException(101, "Bad itemId or catalogItemId in request")
1267
    items_for_entity = get_items_by_catalog_id(catalog_item_id)
1268
    if not len(items_for_entity):
1269
        raise InventoryServiceException(101, "catalogItemId does not exists in database")
1270
 
1271
    s_items = SimilarItems.query.filter_by(item_id=itemId, catalog_item_id=catalog_item_id).all()
1272
    if not len(s_items):
1273
        s_item = SimilarItems()
1274
        s_item.item_id=itemId
1275
        s_item.catalog_item_id=catalog_item_id
1276
        session.commit()
1277
        return items_for_entity[0]
1278
    else:
1279
        raise InventoryServiceException(101, "Already exists")
1280
 
1281
def delete_similar_item_catalog_id(itemId, catalog_item_id):
1282
    if not itemId or not catalog_item_id:
1283
        raise InventoryServiceException(101, "Bad itemId or catalogItemId in request")
1284
 
1285
    similar_item = SimilarItems.query.filter_by(item_id=itemId, catalog_item_id=catalog_item_id).all()
1286
    if len(similar_item):
1287
        similar_item[0].delete()
1288
    session.commit()
1289
    return True
1290
 
3079 rajveer 1291
def add_product_notification(itemId, email):
1292
    try:
3470 rajveer 1293
        try:
1294
            product_notification = ProductNotification.query.filter_by(item_id=itemId, email=email).one()
1295
        except:
1296
            product_notification = ProductNotification()
1297
            product_notification.email = email
1298
            product_notification.item_id = itemId
3079 rajveer 1299
        product_notification.addedOn = datetime.datetime.now()
1300
        session.commit()
1301
        return True
1302
    except:
1303
        return False
3086 rajveer 1304
 
1305
 
1306
def send_product_notifications():
1307
    product_notifications = ProductNotification.query.all()
1308
    for product_notification in product_notifications:
1309
        item = product_notification.item
4406 anupam.sin 1310
        availability = __get_item_availability(item, None)
3309 rajveer 1311
        if availability > 0 and item.status == status.ACTIVE:
3086 rajveer 1312
            __enque_product_notification_email(product_notification.email, __get_product_name(item) , product_notification.addedOn, __get_product_url(item), item.id)
1313
            product_notification.delete()
1314
    session.commit()
1315
    return True
1316
 
1317
def __get_product_name(item):
1318
    product_name = item.brand + " " + item.model_name + " " + item.model_number
1319
    color = item.color
1320
    if color is not None and color != 'NA':
1321
        product_name = product_name + " (" + color + ")"
3201 rajveer 1322
    product_name = product_name.replace("  "," ")
3086 rajveer 1323
    return product_name
1324
 
1325
 
1326
def __get_product_url(item):
1327
    product_url = "http://www.saholic.com/mobile-phones/" + item.brand + "-" + item.model_name + "-" + item.model_number + "-" + str(item.catalog_item_id)
1328
    product_url = product_url.replace("--","-")
1329
    product_url = product_url.replace(" ","")
1330
    return product_url
1331
 
3348 varun.gupt 1332
def get_all_brands_by_category(category_id):
1333
    catm = CategoryManager()
1334
    child_categories = catm.getCategory(category_id).children_category_ids
1335
    brands = session.query(distinct(Item.brand)).filter(Item.category.in_(child_categories)).all()
1336
 
1337
    return [brand[0] for brand in brands]
3086 rajveer 1338
 
1339
def __enque_product_notification_email(email, product, date, url, itemId):
1340
 
1341
    html = """
1342
        <html>
1343
        <body>
1344
        <div>
1345
        <p>
1346
            Hi,<br /><br />
1347
            The product requested by you on $date is now available on saholic.com.
1348
        </p>
1349
 
1350
        <p>    
1351
        <strong>Product: $product </strong>
1352
        </p>
1353
 
1354
        <p>
1355
        Click the link below to visit the product: 
1356
        <br/>
1357
        $url
1358
        </p>
1359
        <p>
1360
        Regards,<br/>
1361
        Saholic Customer Support Team<br/>
1362
        www.saholic.com<br/>
1363
        Email: help@saholic.com<br/>
1364
        </p>
1365
        </div>
1366
        </body>
1367
        </html>
1368
        """
1369
 
1370
    html = Template(html).substitute(dict(product=product,date=date,url=url))
3079 rajveer 1371
 
3086 rajveer 1372
    try:
1373
        helper_client = HelperClient().get_client()
1374
        helper_client.saveUserEmailForSending(email, "", "Product requested by you is available now.", html, str(itemId), "ProductNotification")
1375
    except Exception as e:
1376
        print e
1377
 
3557 rajveer 1378
def get_all_sources():
1379
    sources = Source.query.all()
1380
    return [to_t_source(source) for source in sources]
3086 rajveer 1381
 
3557 rajveer 1382
def get_item_pricing_by_source(itemId, sourceId):
1383
    item = Item.query.filter_by(id=itemId).first()
1384
    if item is None:
1385
        raise InventoryServiceException(101, "Bad Item")
1386
 
1387
    source = Source.query.filter_by(id=sourceId).first()
1388
    if source is None:
1389
        raise InventoryServiceException(101, "Source not found for sourceId " + str(sourceId))
1390
 
1391
    item_pricing = SourceItemPricing.query.filter_by(source=source, item=item).first()
1392
    if item_pricing is None:
1393
        raise InventoryServiceException(101, "Pricing information not found for sourceId " + str(sourceId))
1394
    return item_pricing
1395
 
1396
def add_source_item_pricing(sourceItemPricing):
1397
    if not sourceItemPricing:
1398
        raise InventoryServiceException(108, "Bad sourceItemPricing in request")
1399
 
1400
    if not sourceItemPricing.sellingPrice:
4326 mandeep.dh 1401
        raise InventoryServiceException(101, "Selling Price is not defined for sourceId " + str(sourceItemPricing.sourceId))
3557 rajveer 1402
 
1403
    sourceId = sourceItemPricing.sourceId
1404
    itemId = sourceItemPricing.itemId
1405
 
1406
    item = Item.query.filter_by(id=itemId).first()
1407
    if item is None:
1408
        raise InventoryServiceException(101, "Bad Item")
1409
 
1410
    source = Source.query.filter_by(id=sourceId).first()
1411
    if source is None:
1412
        raise InventoryServiceException(101, "Source not found for sourceId " + str(sourceId))
1413
 
3564 rajveer 1414
    ds_sourceItemPricing = SourceItemPricing.get_by(source=source, item=item)
3557 rajveer 1415
    if ds_sourceItemPricing is None:
1416
        ds_sourceItemPricing = SourceItemPricing()
1417
        ds_sourceItemPricing.source = source
1418
        ds_sourceItemPricing.item = item
1419
 
1420
    if sourceItemPricing.mrp:
1421
        ds_sourceItemPricing.mrp = sourceItemPricing.mrp
1422
    ds_sourceItemPricing.sellingPrice = sourceItemPricing.sellingPrice
1423
 
1424
    session.commit()
1425
    return
1426
 
1427
def get_all_source_pricing(itemId):
1428
    item = Item.query.filter_by(id=itemId).first()
1429
    if item is None:
1430
        raise InventoryServiceException(101, "Bad Item")
1431
    source_pricing = SourceItemPricing.query.filter_by(item=item).all()
1432
    return source_pricing
1433
 
1434
 
1435
def get_item_for_source(item_id, sourceId):
1436
    item = get_item(item_id)
1437
    if sourceId == -1:
1438
        return item
1439
    try:
1440
        sip = get_item_pricing_by_source(item_id, sourceId)
1441
        item.sellingPrice = sip.sellingPrice
1442
        if sip.mrp:
1443
            item.mrp = sip.mrp
1444
    except:
1445
        print "No source pricing"
1446
    return item
1447
 
3872 chandransh 1448
def search_items(search_terms, offset, limit):
1449
    query = Item.query
1450
 
1451
    query_clause = []
1452
 
1453
    search_terms = ['%' + search_term + '%' for search_term in search_terms]
1454
 
1455
    for search_term in search_terms:
1456
        query_clause.append(Item.brand.like(search_term))
1457
        query_clause.append(Item.model_number.like(search_term))
1458
        query_clause.append(Item.model_name.like(search_term))
1459
 
1460
    query = query.filter(or_(*query_clause))
1461
 
1462
    query = query.order_by(Item.product_group, Item.brand, Item.model_number, Item.model_name).offset(offset)
1463
    if limit:
1464
        query = query.limit(limit)
1465
    items = query.all()
1466
    return items
1467
 
1468
def get_search_result_count(search_terms):
1469
    query = Item.query
1470
 
1471
    query_clause = []
1472
 
1473
    search_terms = ['%' + search_term + '%' for search_term in search_terms]
1474
 
1475
    for search_term in search_terms:
1476
        query_clause.append(Item.brand.like(search_term))
1477
        query_clause.append(Item.model_number.like(search_term))
1478
        query_clause.append(Item.model_name.like(search_term))
1479
 
1480
    query = query.filter(or_(*query_clause))
1481
 
1482
    return query.count()
1483
 
3924 rajveer 1484
def __clear_homepage_cache():
1485
    try:
1486
        # create a password manager
1487
        password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
1488
        # Add the username and password.
1489
        configclient = ConfigClient()
4310 rajveer 1490
        ips = configclient.get_property("production_servers_private_ips");
3924 rajveer 1491
        ips = ips.split(" ")
1492
 
1493
        for ip in ips:
4310 rajveer 1494
            try:
1495
                top_level_url = "http://" + ip + ":8080/"
1496
                password_mgr.add_password(None, top_level_url, "saholic", "shop2020")
1497
                handler = urllib2.HTTPBasicAuthHandler(password_mgr)
3924 rajveer 1498
 
4310 rajveer 1499
                opener = urllib2.build_opener(handler)
3924 rajveer 1500
 
4310 rajveer 1501
                # use the opener to fetch a URL
1502
                res = opener.open(top_level_url + "cache-admin/HomePageSnippets?_method=delete")
1503
                print "Successfully cleared home page cache" + res.read()
1504
            except:
1505
                print "Unable to clear home page cache" + res.read()
3924 rajveer 1506
    except:
1507
        print "Unable to clear cache, still should continue with other operations"
4024 chandransh 1508
 
4062 chandransh 1509
def get_pending_orders_inventory(vendor_id=1):
4024 chandransh 1510
    """
1511
    Returns a list of inventory stock for items for which there are pending orders.
1512
    """
4341 rajveer 1513
 
4368 rajveer 1514
    warehouse_ids = [warehouse.id for warehouse in get_warehouses_for_vendor(vendor_id)]
4064 chandransh 1515
    pending_items_inventory = []
1516
    if warehouse_ids:
1517
        pending_items_inventory = session.query(CurrentInventorySnapshot.item_id, func.sum(CurrentInventorySnapshot.availibility), func.sum(CurrentInventorySnapshot.reserved)).filter(CurrentInventorySnapshot.warehouse_id.in_(warehouse_ids)).group_by(CurrentInventorySnapshot.item_id).having(func.sum(CurrentInventorySnapshot.reserved) > 0).all()
4024 chandransh 1518
    return pending_items_inventory
4295 varun.gupt 1519
 
1520
def get_product_notifications(start_datetime):
1521
    '''
1522
    Returns a list of Product Notification objects each representing user requests for notification
1523
    '''
1524
    query = ProductNotification.query
3924 rajveer 1525
 
4295 varun.gupt 1526
    if start_datetime:
1527
        query = query.filter(ProductNotification.addedOn > start_datetime)
1528
 
1529
    notifications = query.order_by(desc('addedOn')).all()
1530
    return notifications
1531
 
1532
def get_product_notification_request_count(start_datetime):
1533
    '''
1534
    Returns list of items and the counts of product notification requests
1535
    '''
1536
    print start_datetime
1537
    query = session.query(ProductNotification, func.count(ProductNotification.email).label('count'))
1538
 
1539
    if start_datetime:
1540
        query = query.filter(ProductNotification.addedOn > start_datetime)
1541
 
1542
    counts = query.group_by(ProductNotification.item_id).order_by(desc('count')).all()
1543
    return counts
1544
 
766 rajveer 1545
def close_session():
1546
    if session.is_active:
1547
        print "session is active. closing it."
1399 rajveer 1548
        session.close()
3376 rajveer 1549
 
1550
def is_alive():
1551
    try:
1552
        session.query(Item.id).limit(1).one()
1553
        return True
1554
    except:
1555
        return False
4332 anupam.sin 1556
 
1557
def add_vendor(vendor):
1558
    if not vendor:
1559
        raise InventoryServiceException(108, "Bad vendor")
1560
    if get_Vendor(vendor.id):
1561
        #vendor is already present.
1562
        raise InventoryServiceException(101, "Vendor already present")
1563
 
1564
    ds_vendor = Vendor()
1565
    ds_vendor.id = vendor.id
1566
    ds_vendor.name = vendor.name
1567
    session.commit()
1568
    return ds_vendor.id
1569
 
1570
def add_warehouse_vendor_mapping(warehouse_id, VendorId):
1571
    return True
1572
 
1573
def get_vendors_for_warehouse(warehouse_id):
1574
    try:
1575
        warehouse = Warehouse.get_by(id=warehouse_id)
1576
        return warehouse.vendors
1577
    except:
1578
        raise InventoryServiceException(108, "Bad Warehouse Id")
1579
 
1580
def get_warehouses_for_vendor(vendorId):
1581
    try:
1582
        vendor = get_Vendor(vendorId)
1583
        return vendor.warehouses
1584
    except:
4649 phani.kuma 1585
        raise InventoryServiceException(108, "Bad Vendor Id")
1586
 
1587
def add_authorization_log_for_item(itemId, username, reason):
1588
    if not itemId or not username:
1589
        raise InventoryServiceException(101, "Bad itemId or Invalid username in request")
1590
    authorize_log = AuthorizationLog()
1591
    authorize_log.item_id = itemId
1592
    authorize_log.username = username
1593
    authorize_log.reason = reason
1594
    session.commit()
4797 rajveer 1595
    return True
1596
 
1597
def __send_mail_for_oos_item(item): 
1598
    try:
4876 mandeep.dh 1599
        EmailAttachmentSender.mail('cnc.center@shop2020.in', '5h0p2o2o', ['abhishek.mathur@shop2020.in', 'chaitnaya.vats@shop2020.in'], "Item is out of stock. ID: " + str(item.id)  + " " + str(item.brand) +  " " + str(item.model_name) + " " + str(item.model_number), None)
4797 rajveer 1600
    except Exception as e:
1601
        print e