Subversion Repositories SmartDukaan

Rev

Rev 5944 | Rev 6029 | 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 *
5393 mandeep.dh 7
from functools import partial
5944 mandeep.dh 8
from shop2020.clients.CatalogClient import CatalogClient
4748 mandeep.dh 9
from shop2020.clients.HelperClient import HelperClient
5944 mandeep.dh 10
from shop2020.clients.InventoryClient import InventoryClient
4748 mandeep.dh 11
from shop2020.config.client.ConfigClient import ConfigClient
94 ashish 12
from shop2020.model.v1.catalog.impl import DataService
4748 mandeep.dh 13
from shop2020.model.v1.catalog.impl.CategoryManager import CategoryManager
5318 rajveer 14
from shop2020.model.v1.catalog.impl.Convertors import to_t_item, to_t_source
5944 mandeep.dh 15
from shop2020.model.v1.catalog.impl.DataService import Item, ItemChangeLog, \
16
    Category, EntityIDGenerator, SimilarItems, ProductNotification, Source, \
17
    SourceItemPricing, AuthorizationLog, VoucherItemMapping
18
from shop2020.thriftpy.model.v1.catalog.ttypes import status, ItemShippingInfo, \
19
    ItemType
20
from shop2020.thriftpy.model.v1.inventory.ttypes import \
21
    InventoryServiceException
4873 mandeep.dh 22
from shop2020.utils import EmailAttachmentSender
4748 mandeep.dh 23
from shop2020.utils.EmailAttachmentSender import mail
5318 rajveer 24
from shop2020.utils.Utils import to_py_date, log_risky_flag
621 chandransh 25
from sqlalchemy import desc, asc
5944 mandeep.dh 26
from sqlalchemy.sql.expression import or_, distinct, func
3086 rajveer 27
from string import Template
4748 mandeep.dh 28
import datetime
29
import sys
5393 mandeep.dh 30
import threading
3924 rajveer 31
import urllib2
94 ashish 32
 
5978 rajveer 33
sourceId = int(ConfigClient().get_property("sourceid"))
5047 amit.gupta 34
to_addresses = ["cnc.center@shop2020.in", "ashutosh.saxena@shop2020.in"]
35
from_user = "cnc.center@shop2020.in"
36
from_pwd = "5h0p2o2o"
5885 mandeep.dh 37
skippedItems = { 175 : [27, 2160, 2175, 2163, 2158, 7128, 26, 2154],
38
                 193 : [5839] }
5047 amit.gupta 39
 
5295 rajveer 40
def initialize(dbname='catalog', db_hostname="localhost"):
41
    DataService.initialize(dbname, db_hostname)
5336 rajveer 42
 
3849 chandransh 43
def get_all_items_by_status(status, offset=0, limit=None):
44
    query = Item.query
4539 rajveer 45
    if status is not None:
3849 chandransh 46
        query = query.filter_by(status=status)
47
    query = query.order_by(Item.product_group, Item.brand, Item.model_number, Item.model_name).offset(offset)
48
    if limit:
49
        query = query.limit(limit)
50
    items = query.all()
51
    return items
52
 
53
def get_all_items(is_active, offset=0, limit=None):
103 ashish 54
    if is_active:
3849 chandransh 55
        items = get_all_items_by_status(status.ACTIVE, offset, limit)
103 ashish 56
    else:
3849 chandransh 57
        items = get_all_items_by_status(None, offset, limit)
766 rajveer 58
    return items
59
 
3849 chandransh 60
def get_item_count_by_status(use_status, status):
61
    if use_status:
62
        return Item.query.filter_by(status=status).count()
103 ashish 63
    else:
3849 chandransh 64
        return Item.query.count()
103 ashish 65
 
635 rajveer 66
def get_item(item_id):
766 rajveer 67
    item = Item.get_by(id=item_id)
68
    return item
94 ashish 69
 
635 rajveer 70
def get_items_by_catalog_id(catalog_id):
447 rajveer 71
    query = Item.query.filter_by(catalog_item_id=catalog_id)
437 rajveer 72
    try:
635 rajveer 73
        items = query.all()
4934 amit.gupta 74
        return items
1399 rajveer 75
    except Exception as ex:
76
        print ex
437 rajveer 77
        raise InventoryServiceException(109, "Item not found")
5586 phani.kuma 78
 
79
def is_valid_catalog_id(catalog_id):
80
    item = Item.query.filter_by(catalog_item_id=catalog_id).first()
81
    if item is not None:
82
        return True
83
    else:
84
        return False
85
 
576 chandransh 86
def is_active(item_id):
2983 chandransh 87
    t_item_shipping_info = ItemShippingInfo()
576 chandransh 88
    try:
635 rajveer 89
        item = get_item(item_id)
3281 chandransh 90
        t_item_shipping_info.isRisky = item.risky
5944 mandeep.dh 91
        client = InventoryClient().get_client()
5978 rajveer 92
        itemInfo = client.getItemAvailabilityAtLocation(item.id, sourceId)
5944 mandeep.dh 93
        warehouse_id = itemInfo[0]
5393 mandeep.dh 94
        if item.risky and item.status == status.ACTIVE:
5944 mandeep.dh 95
            availability = client.getItemAvailibilityAtWarehouse(warehouse_id, item_id)
96
            if availability <= 0:
5393 mandeep.dh 97
                add_status_change_log(item, status.PAUSED_BY_RISK)
98
                item.status = status.PAUSED_BY_RISK
99
                item.status_description = "This item is currently out of stock"
100
                session.commit()
101
                __send_mail_for_oos_item(item)
102
                #This will clear cache from tomcat
103
                __clear_homepage_cache()
104
        else:
5944 mandeep.dh 105
            availability = itemInfo[4]
2983 chandransh 106
        t_item_shipping_info.isActive = (item.status == status.ACTIVE)
3281 chandransh 107
        t_item_shipping_info.quantity = availability
576 chandransh 108
    except InventoryServiceException:
2983 chandransh 109
        print "[ERROR] Unexpected error:", sys.exc_info()[0]
110
    return t_item_shipping_info
111
 
2035 rajveer 112
def get_item_status_description(itemId):
113
    item = get_item(itemId)
114
    return item.status_description
94 ashish 115
 
122 ashish 116
def update_item(item):
117
    if not item:
118
        raise InventoryServiceException(108, "Bad item in request")
119
 
120
    if not item.id:
609 chandransh 121
        raise InventoryServiceException(101, "Missing id for update")
122 ashish 122
 
2120 ankur.sing 123
    validate_item_prices(item)
2065 ankur.sing 124
 
635 rajveer 125
    ds_item = get_item(item.id)
5047 amit.gupta 126
    message = ""
122 ashish 127
    if not ds_item:
609 chandransh 128
        raise InventoryServiceException(101, "Item missing in our database")
122 ashish 129
 
963 chandransh 130
    if item.productGroup:
131
        ds_item.product_group = item.productGroup 
132
    if item.brand:
133
        ds_item.brand = item.brand
511 rajveer 134
    if item.modelNumber:
135
        ds_item.model_number = item.modelNumber
2497 ankur.sing 136
    ds_item.color = item.color
137
    ds_item.model_name = item.modelName
138
    ds_item.category = item.category
139
    ds_item.comments = item.comments
511 rajveer 140
 
2497 ankur.sing 141
    ds_item.catalog_item_id = item.catalogItemId
483 rajveer 142
 
2129 ankur.sing 143
    ds_item.mrp = item.mrp
5047 amit.gupta 144
    if ds_item.sellingPrice or item.sellingPrice:
145
        if ds_item.sellingPrice != item.sellingPrice:
146
            message += "Selling Price is changed from {0} to {1}.\n".format(ds_item.sellingPrice, item.sellingPrice)
147
 
2129 ankur.sing 148
    ds_item.sellingPrice = item.sellingPrice
2497 ankur.sing 149
 
2174 ankur.sing 150
    ds_item.weight = item.weight
2129 ankur.sing 151
 
2358 ankur.sing 152
    if ds_item.status != item.itemStatus:
2402 rajveer 153
        add_status_change_log(ds_item, item.itemStatus)
5047 amit.gupta 154
        if item.itemStatus == status.PHASED_OUT:
155
            message += "Item is phased out."
2358 ankur.sing 156
        ds_item.status = item.itemStatus
2035 rajveer 157
    if item.status_description:
158
        ds_item.status_description = item.status_description
122 ashish 159
 
511 rajveer 160
    if item.startDate:
2116 ankur.sing 161
        ds_item.startDate = to_py_date(item.startDate)
2497 ankur.sing 162
    else:
163
        ds_item.startDate = None
511 rajveer 164
    if item.retireDate:
2116 ankur.sing 165
        ds_item.retireDate = to_py_date(item.retireDate)
2497 ankur.sing 166
    else:
167
        ds_item.retireDate = None
5217 amit.gupta 168
 
169
    if item.expectedArrivalDate:
170
        ds_item.expectedArrivalDate = to_py_date(item.expectedArrivalDate)
171
    else:
172
        ds_item.expectedArrivalDate = None
511 rajveer 173
 
5217 amit.gupta 174
    if item.comingSoonStartDate:
175
        ds_item.comingSoonStartDate = to_py_date(item.comingSoonStartDate)
176
    else:
177
        ds_item.comingSoonStartDate = None
178
 
179
 
2497 ankur.sing 180
    ds_item.feature_id = item.featureId
181
    ds_item.feature_description = item.featureDescription
122 ashish 182
 
5047 amit.gupta 183
    if ds_item.bestDealText or item.bestDealText:
184
        if item.bestDealText != ds_item.bestDealText:
5080 amit.gupta 185
            message += "Promotion text is changed from '{0}' to '{1}'.\n".format(ds_item.bestDealText, item.bestDealText)
2129 ankur.sing 186
    ds_item.bestDealText = item.bestDealText
187
    ds_item.bestDealValue = item.bestDealValue
2065 ankur.sing 188
    ds_item.bestSellingRank = item.bestSellingRank
2497 ankur.sing 189
 
2065 ankur.sing 190
    ds_item.defaultForEntity = item.defaultForEntity
5047 amit.gupta 191
 
192
    if ds_item.risky or item.risky:
193
        if ds_item.risky != item.risky:
5080 amit.gupta 194
            message += "Risky flag is changed to '{0}'.\n".format(set)
5047 amit.gupta 195
 
2251 ankur.sing 196
    ds_item.risky = item.risky
3359 chandransh 197
 
5385 phani.kuma 198
    ds_item.type = ItemType._VALUES_TO_NAMES[item.type]
199
    ds_item.hasItemNo = item.hasItemNo
5460 phani.kuma 200
    ds_item.clearance = item.clearance
5385 phani.kuma 201
 
3459 chandransh 202
    if item.expectedDelay is not None:
3359 chandransh 203
        ds_item.expectedDelay = item.expectedDelay
4506 phani.kuma 204
 
205
    if item.preferredVendor:
5080 amit.gupta 206
        if item.preferredVendor != ds_item.preferredVendor:
5944 mandeep.dh 207
            inventoryClient = InventoryClient().get_client()
208
            newPreferredVendorName = inventoryClient.getVendor(item.preferredVendor).name
5080 amit.gupta 209
            oldPreferredVendorName = 'None'
210
            if ds_item.preferredVendor:
5944 mandeep.dh 211
                oldPreferredVendorName = inventoryClient.getVendor(ds_item.preferredVendor).name
5408 amit.gupta 212
            message += "Preferred vendor is changed from '{0}' to '{1}'.\n".format(oldPreferredVendorName, newPreferredVendorName)        
4506 phani.kuma 213
        ds_item.preferredVendor = item.preferredVendor
5080 amit.gupta 214
 
215
    if item.isWarehousePreferenceSticky != ds_item.isWarehousePreferenceSticky:
216
        flag = "ON" if item.isWarehousePreferenceSticky else "OFF"
217
        message += "Warehouse preference sticky is {0}.\n".format(flag)
218
 
4413 anupam.sin 219
    ds_item.isWarehousePreferenceSticky = item.isWarehousePreferenceSticky
3359 chandransh 220
 
2347 ankur.sing 221
    ds_item.updatedOn = datetime.datetime.now()
2065 ankur.sing 222
 
122 ashish 223
    session.commit();
5047 amit.gupta 224
    subject = "Item '{0}' is updated in Catalog. Id is {1}".format(__get_product_name(ds_item),ds_item.id)
225
    if message:
226
        __send_mail(subject, message)
122 ashish 227
    return ds_item.id
94 ashish 228
 
103 ashish 229
def add_item(item):
230
    if not item:
122 ashish 231
        raise InventoryServiceException(108, "Bad item in request")
635 rajveer 232
    if get_item(item.id):
122 ashish 233
        raise InventoryServiceException(101, "Item already exists")
2120 ankur.sing 234
 
235
    validate_item_prices(item)
236
 
103 ashish 237
    ds_item = Item()
963 chandransh 238
    if item.productGroup:
239
        ds_item.product_group = item.productGroup
240
    if item.brand:
241
        ds_item.brand = item.brand
515 rajveer 242
    if item.modelName:
243
        ds_item.model_name = item.modelName
244
    if item.modelNumber:
245
        ds_item.model_number = item.modelNumber
609 chandransh 246
    if item.color:
247
        ds_item.color = item.color
483 rajveer 248
    if item.category:
249
        ds_item.category = item.category
250
    if item.comments:
251
        ds_item.comments = item.comments
252
 
103 ashish 253
    ds_item.addedOn = datetime.datetime.now()
609 chandransh 254
    ds_item.updatedOn = datetime.datetime.now()
2116 ankur.sing 255
    if item.startDate:
256
        ds_item.startDate = to_py_date(item.startDate)
257
    if item.retireDate:
258
        ds_item.retireDate = to_py_date(item.retireDate)
5217 amit.gupta 259
    if item.comingSoonStartDate:
260
        ds_item.comingSoonStartDate = to_py_date(item.comingSoonStartDate)
261
    if item.expectedArrivalDate:
262
        ds_item.expectedArrivalDate = to_py_date(item.expectedArrivalDate)    
483 rajveer 263
    if item.mrp:
264
        ds_item.mrp = item.mrp
265
    if item.sellingPrice:
266
        ds_item.sellingPrice = item.sellingPrice
122 ashish 267
    if item.weight:
268
        ds_item.weight = item.weight
269
 
270
    if item.featureId:
271
        ds_item.feature_id = item.featureId
272
    if item.featureDescription:
273
        ds_item.feature_description = item.featureDescription
274
 
2116 ankur.sing 275
 
103 ashish 276
    #check if categories present. If yes, add them to system
122 ashish 277
 
609 chandransh 278
    if item.bestDealValue:
279
        ds_item.bestDealValue = item.bestDealValue
280
    if item.bestDealText:
281
        ds_item.bestDealText = item.bestDealText
2116 ankur.sing 282
    if item.bestSellingRank:
283
        ds_item.bestSellingRank = item.bestSellingRank
284
    ds_item.defaultForEntity = item.defaultForEntity
2251 ankur.sing 285
    ds_item.risky = item.risky
609 chandransh 286
 
5385 phani.kuma 287
    ds_item.type = ItemType._VALUES_TO_NAMES[item.type]
288
    ds_item.hasItemNo = item.hasItemNo
5460 phani.kuma 289
    ds_item.clearance = item.clearance
5385 phani.kuma 290
 
3467 chandransh 291
    if item.expectedDelay is not None:
3359 chandransh 292
        ds_item.expectedDelay = item.expectedDelay
3467 chandransh 293
    else:
294
        ds_item.expectedDelay = 0
3359 chandransh 295
 
5408 amit.gupta 296
    preferredVendorName = "None"
4881 phani.kuma 297
    if item.preferredVendor:
298
        ds_item.preferredVendor = item.preferredVendor
5944 mandeep.dh 299
        inventoryClient = InventoryClient().get_client()
300
        preferredVendorName = inventoryClient.getVendor(item.preferredVendor).name        
4881 phani.kuma 301
 
5586 phani.kuma 302
    if item.catalogItemId:
303
        catalog_client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
304
        master_items = catalog_client.getItemsByCatalogId(item.catalogItemId)
305
        itemStatus = status.IN_PROCESS
306
        for masterItem in master_items:
307
            if masterItem.itemStatus in [status.CONTENT_COMPLETE, status.COMING_SOON, status.ACTIVE, status.PAUSED]:
308
                itemStatus = status.CONTENT_COMPLETE
309
                ds_item.category = masterItem.category
310
                break
311
        ds_item.catalog_item_id = item.catalogItemId
312
        ds_item.status = itemStatus
2116 ankur.sing 313
        ds_item.status_description = "This item is in process."
314
    else:
5586 phani.kuma 315
        # Check if a similar item already exists in our database
316
        similar_item = Item.query.filter_by(brand=item.brand, model_number=item.modelNumber, model_name=item.modelName).first()
317
        print "[SIMILAR ITEM FOUND:] FOR {0} {1} {2}".format(item.brand, item.modelNumber, item.modelName)
318
 
319
        if similar_item is None or similar_item.catalog_item_id is None:
320
            # If there is no similar item in the database from before,
321
            # use the entity_id_generator
322
            entity_id = EntityIDGenerator.query.first()
323
            ds_item.catalog_item_id = entity_id.id + 1
324
            ds_item.status = status.IN_PROCESS
325
            ds_item.status_description = "This item is in process."
326
            entity_id.id = entity_id.id  + 1
327
            if similar_item is not None and similar_item.catalog_item_id is None:
328
                similar_item.catalog_item_id = entity_id.id
329
        else:
330
            #If a similar item already exists for a product group, brand and model_number, set it as same.
331
            ds_item.catalog_item_id = similar_item.catalog_item_id
332
            ds_item.category = similar_item.category
333
            ds_item.product_group = similar_item.product_group
334
            ds_item.status = similar_item.status
335
            ds_item.status_description = similar_item.status_description
2116 ankur.sing 336
 
103 ashish 337
    session.commit();
5052 amit.gupta 338
    subject = "New item is added. Id is {0}".format(str(ds_item.id))
5408 amit.gupta 339
    message = "Category : {6}, Brand : {0}, Model : {1}, Model Number : {2}\nColor : {3}, Selling Price : {4}, Mrp : {5}, \nPromotion Text : {7}, Preferred Vendor: {8}".format(item.brand, item.modelNumber, item.modelName, item.color, item.sellingPrice, item.mrp, item.category, item.bestDealText, preferredVendorName)
5047 amit.gupta 340
    __send_mail(subject, message)
3325 chandransh 341
    return ds_item.id
342
 
103 ashish 343
def retire_item(item_id):
344
    if not item_id:
122 ashish 345
        raise InventoryServiceException(101, "bad item id")
635 rajveer 346
    item = get_item(item_id)
103 ashish 347
    if not item:
122 ashish 348
        raise InventoryServiceException(108, "item id not present")
349
    item.status = status.PHASED_OUT
350
    item.retireDate = datetime.datetime.now()
103 ashish 351
    session.commit()
122 ashish 352
 
353
#need to implement threads based solution here
103 ashish 354
def start_item_on(item_id, timestamp):
355
    if not item_id:
122 ashish 356
        raise InventoryServiceException(101, "bad item id")
635 rajveer 357
    item = get_item(item_id)
103 ashish 358
    if not item:
122 ashish 359
        raise InventoryServiceException(108, "item id not present")
103 ashish 360
 
122 ashish 361
    item.status = status.ACTIVE
362
    item.startDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))
363
    add_status_change_log(item, status.ACTIVE)
103 ashish 364
    session.commit()
365
 
122 ashish 366
#need to implement threads here
103 ashish 367
def retire_item_on(item_id, timestamp):
368
    if not item_id:
122 ashish 369
        raise InventoryServiceException(101, "bad item id")
635 rajveer 370
    item = get_item(item_id)
103 ashish 371
    if not item:
122 ashish 372
        raise InventoryServiceException(108, "item id not present")
103 ashish 373
 
122 ashish 374
    item.status = status.PHASED_OUT
375
    item.retireDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))
376
    add_status_change_log(item, status.PHASED_OUT)
103 ashish 377
    session.commit()
378
 
379
def add_status_change_log(item, new_status):
380
    item_change_log = ItemChangeLog()
381
    item_change_log.new_status = new_status
382
    item_change_log.old_status = item.status
383
    item_change_log.timestamp = datetime.datetime.now()
384
    item_change_log.item = item
385
    session.commit()
386
 
387
def change_item_status(item_id, new_status):
388
    if not item_id:
122 ashish 389
        raise InventoryServiceException(101, "bad item id")
635 rajveer 390
    item = get_item(item_id)
103 ashish 391
    if not item:
122 ashish 392
        raise InventoryServiceException(108, "item id not present")
2116 ankur.sing 393
    add_status_change_log(item, new_status)
122 ashish 394
    item.status = new_status
2251 ankur.sing 395
    if item.status == status.PHASED_OUT:
396
        item.status_description = "This item has been phased out"
5047 amit.gupta 397
        __send_mail("Item '{0}' is Phased-Out. Item id is {1}".format(__get_product_name(item), item_id), "")
2251 ankur.sing 398
    elif item.status == status.DELETED:
399
        item.status_description = "This item has been deleted"
3924 rajveer 400
    elif item.status == status.PAUSED:
401
        item.status_description = "This item is currently out of stock"      
402
    elif item.status == status.PAUSED_BY_RISK:
403
        item.status_description = "This item is currently out of stock"
404
        #This will clear cache from tomcat
405
        __clear_homepage_cache()  
2251 ankur.sing 406
    elif item.status == status.ACTIVE:
407
        item.status_description = "This item is active"
5047 amit.gupta 408
        __send_mail("Item '{0}' is Active. Item id is {1}".format(__get_product_name(item), item_id), "")
2251 ankur.sing 409
    elif item.status == status.IN_PROCESS:
410
        item.status_description = "This item is in process"
411
    elif item.status == status.CONTENT_COMPLETE:
412
        item.status_description = "This item is in process"
103 ashish 413
    session.commit()
414
 
5944 mandeep.dh 415
def check_risky_item(item_id):
635 rajveer 416
    item = get_item(item_id)
2251 ankur.sing 417
    if not item.risky:
418
        return
5944 mandeep.dh 419
    client = InventoryClient().get_client()
5978 rajveer 420
    itemInfo = client.getItemAvailabilityAtLocation(item.id, sourceId)    
5944 mandeep.dh 421
    warehouse_id = itemInfo[0]
422
    availability = client.getItemAvailibilityAtWarehouse(warehouse_id, item.id)
423
    if availability <= 0:
2251 ankur.sing 424
        if item.status == status.ACTIVE:
2984 rajveer 425
            change_item_status(item.id, status.PAUSED_BY_RISK)
4797 rajveer 426
            __send_mail_for_oos_item(item)
2251 ankur.sing 427
    else:
2984 rajveer 428
        if item.status == status.PAUSED_BY_RISK:
2251 ankur.sing 429
            change_item_status(item.id, status.ACTIVE)
2368 ankur.sing 430
    session.commit()
2983 chandransh 431
 
2075 rajveer 432
def mark_item_as_content_complete(entity_id, category, brand, modelName, modelNumber):
2828 rajveer 433
    '''
434
    Get all the items for this entityID and update category, brand, modelName and modelNumber for all.
435
    Update Status for only IN_PROCESS items to CONTENT_COMPLETE
436
    '''
723 chandransh 437
    content_complete_status = status.CONTENT_COMPLETE
2828 rajveer 438
    items = Item.query.filter_by(catalog_item_id=entity_id).all()
723 chandransh 439
    current_timestamp = datetime.datetime.now()
440
    for item in items:
2828 rajveer 441
        if item.status == status.IN_PROCESS:
442
            item.status = content_complete_status
443
            item_change_log = ItemChangeLog()
444
            item_change_log.old_status = item.status
445
            item_change_log.new_status = content_complete_status
446
            item_change_log.timestamp = current_timestamp
447
            item_change_log.item = item
723 chandransh 448
 
4762 phani.kuma 449
        category_object = get_category(category)
450
        if category_object is not None:
451
            item.category = category
452
            item.product_group = category_object.display_name
2075 rajveer 453
        item.brand = brand
2081 rajveer 454
        item.model_name = modelName
455
        item.model_number = modelNumber
723 chandransh 456
        item.updatedOn = current_timestamp
457
    session.commit()
458
    return True
1294 chandransh 459
 
2404 chandransh 460
def get_child_categories(category):
461
    cm = CategoryManager()
2621 varun.gupt 462
    cat = cm.getCategory(category)
463
    return cat.children_category_ids if cat else None
2404 chandransh 464
 
626 chandransh 465
def get_best_sellers(start_index, stop_index, category=-1):
2404 chandransh 466
    '''
467
    Returns the Best Sellers between the start and the stop index in the given category
468
    '''
1926 rajveer 469
    query = get_best_sellers_query(category, None)
1098 chandransh 470
    best_sellers = query.all()[start_index:stop_index]
621 chandransh 471
    return get_thrift_item_list(best_sellers)
472
 
2093 chandransh 473
def get_best_sellers_count(category=-1):
2404 chandransh 474
    '''
475
    Returns the number of best sellers in the given category
476
    '''
1926 rajveer 477
    count = get_best_sellers_query(category, None).count()
1120 rajveer 478
    if count is None:
479
        count = 0
766 rajveer 480
    return count
621 chandransh 481
 
1926 rajveer 482
def get_best_sellers_catalog_ids(start_index, stop_index, brand, category=-1):
2404 chandransh 483
    '''
484
    Returns the Best sellers for the given brand and category between the start and the stop index.
485
    Ignores the category if it's passed as -1 and the brand if it's passed as None. 
486
    '''
1926 rajveer 487
    query = get_best_sellers_query(category, brand)
1098 chandransh 488
    best_sellers = query.all()[start_index:stop_index]
621 chandransh 489
    return [item.catalog_item_id for item in best_sellers]
1970 rajveer 490
 
1926 rajveer 491
def get_best_sellers_query(category, brand):
2404 chandransh 492
    '''
493
    Returns the query to be used for getting Best Sellers.
494
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
495
    '''
1098 chandransh 496
    query = Item.query.filter_by(status=status.ACTIVE).filter(Item.bestSellingRank != None)
626 chandransh 497
    if category != -1:
1970 rajveer 498
        all_categories = [category]
499
        child_categories = get_child_categories(category)
500
        if child_categories is not None:
501
            all_categories = all_categories + child_categories 
502
        query = query.filter(Item.category.in_(all_categories))
1926 rajveer 503
    if brand is not None:
504
        query = query.filter_by(brand=brand)
1098 chandransh 505
    query = query.order_by(asc(Item.bestSellingRank))
621 chandransh 506
    return query
609 chandransh 507
 
1098 chandransh 508
def get_best_deals(category=-1):
2404 chandransh 509
    '''
510
    Returns the Best deals in the given category. Ignores the category if it's passed as -1.
511
    '''
512
    query = get_best_deals_query(Item, category, None)
1098 chandransh 513
    items = query.all()
609 chandransh 514
    return get_thrift_item_list(items)
515
 
1098 chandransh 516
def get_best_deals_count(category=-1):
2404 chandransh 517
    '''
518
    Returns the count of best deals in the given category.
519
    Ignores the category if it's -1.
520
    '''
521
    count = get_best_deals_counting_query(func.count(distinct(Item.catalog_item_id)), category, None).scalar()
1120 rajveer 522
    if count is None:
523
        count = 0
766 rajveer 524
    return count
501 rajveer 525
 
1926 rajveer 526
def get_best_deals_catalog_ids(start_index, stop_index, brand, category=-1):
2404 chandransh 527
    '''
528
    Returns the catalog_item_ids of best deal items for the given brand and category.
529
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
530
    '''
531
    query = get_best_deals_query(Item, category, brand)
1098 chandransh 532
    best_deal_items = query.all()[start_index:stop_index]
533
    return [item.catalog_item_id for item in best_deal_items]
534
 
2404 chandransh 535
def get_best_deals_counting_query(obj, category, brand):
536
    '''
537
    Returns the query to be used to select the best deals in the given brand and category.
538
    Ignores the category if it's passed as -1 and the brand if it's passed as None. 
539
    '''
540
    query = session.query(obj).filter_by(status=status.ACTIVE).filter(Item.bestDealValue != None)
626 chandransh 541
    if category != -1:
1970 rajveer 542
        all_categories = [category]
543
        child_categories = get_child_categories(category)
544
        if child_categories is not None:
545
            all_categories = all_categories + child_categories 
546
        query = query.filter(Item.category.in_(all_categories))
1926 rajveer 547
    if brand is not None:
548
        query = query.filter_by(brand=brand)
2404 chandransh 549
    return query
550
 
551
def get_best_deals_query(obj, category, brand):
552
    '''
553
    Returns the query to be used to get the best deals in the given category and brand.
554
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
555
    '''
556
    query = get_best_deals_counting_query(obj, category, brand)
1098 chandransh 557
    query = query.group_by(Item.catalog_item_id).order_by(desc(Item.bestDealValue))
558
    return query
609 chandransh 559
 
5217 amit.gupta 560
def get_coming_soon(category=-1):
561
    '''
562
    Returns the Coming Soon items in the given category. Ignores the category if it's passed as -1.
563
    '''
564
    query = get_coming_soon_query(Item, category, None)
565
    items = query.all()
566
    return get_thrift_item_list(items)
567
 
568
def get_coming_soon_count(category=-1):
569
    '''
570
    Returns the count of coming in the given category.
571
    Ignores the category if it's -1.
572
    '''
573
    count = get_coming_soon_counting_query(func.count(distinct(Item.catalog_item_id)), category, None).scalar()
574
    if count is None:
575
        count = 0
576
    return count
577
 
578
def get_coming_soon_catalog_ids(start_index, stop_index, brand, category=-1):
579
    '''
580
    Returns the catalog_item_ids of coming soon items for the given brand and category.
581
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
582
    '''
583
    query = get_coming_soon_query(Item, category, brand)
584
    coming_soon_items = query.all()[start_index:stop_index]
585
    return [item.catalog_item_id for item in coming_soon_items]
586
 
587
def get_coming_soon_counting_query(obj, category, brand):
588
    '''
589
    Returns the query to be used to select the coming soon product in the given brand and category.
590
    Ignores the category if it's passed as -1 and the brand if it's passed as None. 
591
    '''
592
    query = session.query(obj).filter_by(status=status.COMING_SOON)
593
    if category != -1:
594
        all_categories = [category]
595
        child_categories = get_child_categories(category)
596
        if child_categories is not None:
597
            all_categories = all_categories + child_categories 
598
        query = query.filter(Item.category.in_(all_categories))
599
    if brand is not None:
600
        query = query.filter_by(brand=brand)
601
    return query
602
 
603
def get_coming_soon_query(obj, category, brand):
604
    '''
605
    Returns the query to be used to get the coming soon products in the given category and brand.
606
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
607
    '''
608
    query = get_coming_soon_counting_query(obj, category, brand)
609
    query = query.group_by(Item.catalog_item_id).order_by(asc(Item.comingSoonStartDate))
610
    return query
611
 
1098 chandransh 612
def get_latest_arrivals(limit, category=-1):
2404 chandransh 613
    '''
614
    Returns up to limit number of Latest Arrivals in the given category.
615
    '''
2975 chandransh 616
    categories = []
617
    if category != -1:
618
        categories = [category]
619
    query = get_latest_arrivals_query(Item, categories, 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):
2404 chandransh 624
    '''
625
    Returns the number of latest arrivals which will be displayed on the website.
3016 chandransh 626
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 627
    '''
2975 chandransh 628
    categories = []
629
    if category != -1:
630
        categories = [category]
631
    count = get_latest_arrivals_counting_query(func.count(distinct(Item.catalog_item_id)), categories, None).scalar()
1120 rajveer 632
    if count is None:
633
        count = 0
634
    count = min(count, limit)
766 rajveer 635
    return count
602 chandransh 636
 
2975 chandransh 637
def get_latest_arrivals_catalog_ids(start_index, stop_index, brand, categories=[]):
2404 chandransh 638
    '''
639
    Returns the catalog_item_ids of the latest arrivals between the start and the stop index
3016 chandransh 640
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 641
    '''
2975 chandransh 642
    query = get_latest_arrivals_query(Item, categories, brand)
1098 chandransh 643
    latest_arrivals = query.all()[start_index:stop_index]
644
    return [item.catalog_item_id for item in latest_arrivals]
645
 
2975 chandransh 646
def get_latest_arrivals_counting_query(obj, categories, brand):
2404 chandransh 647
    '''
648
    Returns the query to be used to count Latest arrivals.
3016 chandransh 649
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 650
    '''
651
    query = session.query(obj).filter_by(status=status.ACTIVE)
2975 chandransh 652
 
653
    all_categories = []
654
    for category in categories:
655
        all_categories.append(category)
1970 rajveer 656
        child_categories = get_child_categories(category)
2975 chandransh 657
        if child_categories:
658
            all_categories = all_categories + child_categories
659
    if all_categories: 
1970 rajveer 660
        query = query.filter(Item.category.in_(all_categories))
2975 chandransh 661
 
1926 rajveer 662
    if brand is not None:
663
        query = query.filter_by(brand=brand)
2404 chandransh 664
    return query
665
 
2975 chandransh 666
def get_latest_arrivals_query(obj, categories, brand):
2404 chandransh 667
    '''
668
    Returns the query to be used to retrieve Latest Arrivals.
669
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
670
    '''
2975 chandransh 671
    query = get_latest_arrivals_counting_query(obj, categories, brand)
5167 rajveer 672
    query = query.group_by(Item.catalog_item_id).order_by(desc(Item.startDate)).order_by(Item.catalog_item_id)
1098 chandransh 673
    return query
609 chandransh 674
 
675
def get_thrift_item_list(items):
1098 chandransh 676
    return [to_t_item(item) for item in items if item != None]
635 rajveer 677
 
1155 rajveer 678
def generate_new_entity_id():
679
    generator =  EntityIDGenerator.query.one()
680
    id = generator.id + 1
681
    generator.id = id
682
    session.commit()
683
    return id
684
 
635 rajveer 685
def put_category_object(object):
686
    category = Category.get_by(id=1)
687
    if category is None:
688
        category = Category()
689
    category.object = object    
690
    session.commit()
691
    return True
692
 
693
def get_category_object():
766 rajveer 694
    object = Category.get_by(id=1).object
695
    return object
696
 
1970 rajveer 697
def add_category(t_category):
698
    category = Category.get_by(id=t_category.id)
699
    if category is None:
700
        category = Category()
701
    category.id = t_category.id 
702
    category.label = t_category.label
703
    category.description = t_category.description
4762 phani.kuma 704
    category.display_name = t_category.display_name
1970 rajveer 705
    category.parent_category_id = t_category.parent_category_id 
706
    session.commit()
707
    return True
708
 
709
def get_category(id):
710
    return Category.query.filter_by(id=id).first()
711
 
712
def get_all_categories():
713
    return Category.query.all()
714
 
2120 ankur.sing 715
def validate_item_prices(item):
2129 ankur.sing 716
    if item.mrp == None or item.sellingPrice == None or item.mrp == "" or item.sellingPrice == "":
717
        return
718
    if item.mrp < item.sellingPrice:
2120 ankur.sing 719
        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))
720
        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 721
    return
2120 ankur.sing 722
 
723
def validate_vendor_prices(item, vendorPrices):
2129 ankur.sing 724
    if item.mrp != None and item.mrp != "" and vendorPrices.mop != "" and item.mrp <  vendorPrices.mop:
2120 ankur.sing 725
        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))
726
        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)))
727
    if vendorPrices.mop != "" and vendorPrices.transferPrice != "" and vendorPrices.transferPrice > vendorPrices.mop:
728
        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))
729
        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)))
730
    return
2065 ankur.sing 731
 
4725 phani.kuma 732
def check_color_valid(color):
733
    if color is not None:
734
        color = color.strip().lower()
735
        if color != '' and color != 'na' and color != 'blank' and color != '(blank)':
736
            return True
737
    return False
738
 
739
def check_similar_item(brand, model_number, model_name, color):
2129 ankur.sing 740
    query = Item.query
2428 ankur.sing 741
    query = query.filter_by(brand=brand)
742
    query = query.filter_by(model_number=model_number)
4725 phani.kuma 743
    query = query.filter_by(model_name=model_name)
744
    similar_items = query.all()
745
    item = None
746
    # Check if a similar item already exists in our database
747
    for old_item in similar_items:
748
        if old_item.color != None and old_item.color.strip().lower() == color.strip().lower():
749
            item = old_item
750
            break
751
 
752
    # 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 753
    if item is None:
4725 phani.kuma 754
        for old_item in similar_items:
755
            if not check_color_valid(old_item.color):
756
                item = old_item
757
                break
758
    i = 0
759
    color_of_similar_item = None
760
    # Check if a similar item already exists in our database to be used to get catalog_item_id
761
    for old_item in similar_items:
762
        # get a similar item already existing in our database with valid color
763
        if check_color_valid(old_item.color):
764
            similar_item = old_item
765
            color_of_similar_item = similar_item.color
766
            break
767
        i = i + 1
768
        # get a similar item already existing in our database if similar item with valid color is not found
769
        if i == len(similar_items):
770
            similar_item = old_item
771
            color_of_similar_item = similar_item.color
772
 
773
    # Check if a similar item that is obtained above is having a valid color
774
    if check_color_valid(color_of_similar_item):
775
        # 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.
776
        # 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.
777
        if item is None and not check_color_valid(color):
778
            return similar_item.id
779
 
780
    if item is None:
2116 ankur.sing 781
        return 0
782
    else:
783
        return item.id
2286 ankur.sing 784
 
785
def change_risky_flag(item_id, risky):
786
    item = get_item(item_id)
787
    if not item:
788
        raise InventoryServiceException(101, "Item missing in our database")
789
    try:
790
        log_risky_flag(item_id, risky)
791
    except:
792
        print "Not able to log risky flag change"
793
    item.risky = risky
4295 varun.gupt 794
    if not risky and item.status == status.PAUSED_BY_RISK:
2368 ankur.sing 795
        change_item_status(item.id, status.ACTIVE)
2286 ankur.sing 796
    session.commit()
5047 amit.gupta 797
    flag = "ON" if risky else "OFF"
798
    subject = "Risky flag is {0} for Item {1}.".format(flag, __get_product_name(item))
799
    __send_mail(subject,"")
2286 ankur.sing 800
 
4957 phani.kuma 801
def get_items_for_mastersheet(categoryName, brand):
802
    if not categoryName or not brand:
803
        raise InventoryServiceException(101, "Invalid category or brand in request")
804
 
4762 phani.kuma 805
    categories = ["Handsets", "Tablets", "Laptops"]
4957 phani.kuma 806
    query = Item.query.filter(Item.status != status.PHASED_OUT)
807
    if categoryName == "ALL":
808
        pass
809
    elif categoryName == "ALL Accessories":
810
        query = query.filter(~Item.product_group.in_(categories))
811
    elif categoryName == "ALL Handsets":
812
        query = query.filter(Item.product_group.in_(categories))
813
    elif categoryName == "Mobile Accessories":
814
        child_categories = get_child_categories(10011)
815
        if child_categories is not None:
816
            child_categories.append(0)
817
            query = query.filter(Item.category.in_(child_categories))
818
    elif categoryName == "Laptop Accessories":
819
        child_categories = get_child_categories(10070)
820
        if child_categories is not None:
821
            child_categories.append(0)
822
            query = query.filter(Item.category.in_(child_categories))
823
    else:
824
        query = query.filter(Item.product_group == categoryName)
825
 
826
    if brand == "ALL":
827
        pass
828
    else:
829
        query = query.filter(Item.brand == brand)
2358 ankur.sing 830
    items = query.all()
831
    return items
2116 ankur.sing 832
 
2358 ankur.sing 833
def get_risky_items():
834
    items = Item.query.filter_by(risky=True).all()
835
    return items
3008 rajveer 836
 
2809 rajveer 837
def get_similar_items_catalog_ids(start_index, stop_index, itemId):
3008 rajveer 838
    query = SimilarItems.query.filter_by(item_id=itemId).limit(stop_index-start_index)
839
    similar_items = query.all()
3289 rajveer 840
    return_list = []
841
    for similar_item in similar_items:
842
        isActive = False
843
        try:
844
            all_items = Item.query.filter_by(catalog_item_id=similar_item.catalog_item_id).all()
845
        except:
846
            continue
847
        for item in all_items:
848
            isActive = isActive or item.status == status.ACTIVE
849
        if isActive:
850
            return_list.append(similar_item.catalog_item_id)
851
    return return_list
4423 phani.kuma 852
 
853
def get_all_similar_items_catalog_ids(itemId):
854
    query = SimilarItems.query.filter_by(item_id=itemId)
855
    similar_items = query.all()
856
    return_list = []
857
    for similar_item in similar_items:
858
        item_query = Item.query.filter_by(catalog_item_id=similar_item.catalog_item_id).limit(1)
859
        item = item_query.one()
860
        return_list.append(item)
2809 rajveer 861
 
4423 phani.kuma 862
    return get_thrift_item_list(return_list)
863
 
864
def add_similar_item_catalog_id(itemId, catalog_item_id):
865
    if not itemId or not catalog_item_id:
866
        raise InventoryServiceException(101, "Bad itemId or catalogItemId in request")
867
    items_for_entity = get_items_by_catalog_id(catalog_item_id)
868
    if not len(items_for_entity):
869
        raise InventoryServiceException(101, "catalogItemId does not exists in database")
870
 
871
    s_items = SimilarItems.query.filter_by(item_id=itemId, catalog_item_id=catalog_item_id).all()
872
    if not len(s_items):
873
        s_item = SimilarItems()
874
        s_item.item_id=itemId
875
        s_item.catalog_item_id=catalog_item_id
876
        session.commit()
877
        return items_for_entity[0]
878
    else:
879
        raise InventoryServiceException(101, "Already exists")
880
 
881
def delete_similar_item_catalog_id(itemId, catalog_item_id):
882
    if not itemId or not catalog_item_id:
883
        raise InventoryServiceException(101, "Bad itemId or catalogItemId in request")
884
 
885
    similar_item = SimilarItems.query.filter_by(item_id=itemId, catalog_item_id=catalog_item_id).all()
886
    if len(similar_item):
887
        similar_item[0].delete()
888
    session.commit()
889
    return True
5504 phani.kuma 890
 
891
def get_all_vouchers_for_item(itemId):
892
    vouchers = VoucherItemMapping.query.filter_by(item_id=itemId).all()
893
    return vouchers
894
 
895
def get_voucher_amount(itemId, voucher_type):
896
    voucher = VoucherItemMapping.query.filter_by(item_id=itemId, voucherType=voucher_type).all()
897
    if len(voucher):
898
        return voucher[0].amount
899
    else:
5518 rajveer 900
        return 0
5504 phani.kuma 901
 
902
def add_update_voucher_for_item(catalog_item_id, voucher_type, voucher_amount):
903
    if not catalog_item_id or not voucher_type or not voucher_amount:
904
        raise InventoryServiceException(101, "Bad catalogItemId or voucherType or voucherAmount in request")
905
 
906
    items_for_entity = get_items_by_catalog_id(catalog_item_id)
907
    if not len(items_for_entity):
908
        raise InventoryServiceException(101, "catalogItemId does not exists in database")
909
 
910
    for item in items_for_entity:
911
        itemId = item.id
912
        voucher = VoucherItemMapping.query.filter_by(item_id=itemId, voucherType=voucher_type).all()
913
        if not len(voucher):
914
            voucher = VoucherItemMapping()
915
            voucher.item_id=itemId
916
            voucher.voucherType=voucher_type
917
            voucher.amount=voucher_amount
918
        else:
919
            voucher[0].amount=voucher_amount
920
    session.commit()
921
    return True
4423 phani.kuma 922
 
5504 phani.kuma 923
def delete_voucher_for_item(catalog_item_id, voucher_type):
924
    if not catalog_item_id or not voucher_type:
925
        raise InventoryServiceException(101, "Bad catalogItemId or voucherType in request")
926
 
927
    items_for_entity = get_items_by_catalog_id(catalog_item_id)
928
    if not len(items_for_entity):
929
        raise InventoryServiceException(101, "catalogItemId does not exists in database")
930
 
931
    for item in items_for_entity:
932
        itemId = item.id
933
        voucher = VoucherItemMapping.query.filter_by(item_id=itemId, voucherType=voucher_type).all()
934
        if len(voucher):
935
            voucher[0].delete()
936
    session.commit()
937
    return True
938
 
3079 rajveer 939
def add_product_notification(itemId, email):
940
    try:
3470 rajveer 941
        try:
942
            product_notification = ProductNotification.query.filter_by(item_id=itemId, email=email).one()
943
        except:
944
            product_notification = ProductNotification()
945
            product_notification.email = email
946
            product_notification.item_id = itemId
3079 rajveer 947
        product_notification.addedOn = datetime.datetime.now()
948
        session.commit()
949
        return True
950
    except:
951
        return False
3086 rajveer 952
 
953
 
954
def send_product_notifications():
955
    product_notifications = ProductNotification.query.all()
956
    for product_notification in product_notifications:
957
        item = product_notification.item
5944 mandeep.dh 958
        client = InventoryClient().get_client()
5978 rajveer 959
        availability = client.getItemAvailabilityAtLocation(item.id, sourceId)[4]
5125 mandeep.dh 960
        if item.status == status.ACTIVE and (not item.risky or availability > 0):
3086 rajveer 961
            __enque_product_notification_email(product_notification.email, __get_product_name(item) , product_notification.addedOn, __get_product_url(item), item.id)
962
            product_notification.delete()
963
    session.commit()
964
    return True
965
 
966
def __get_product_name(item):
967
    product_name = item.brand + " " + item.model_name + " " + item.model_number
968
    color = item.color
969
    if color is not None and color != 'NA':
970
        product_name = product_name + " (" + color + ")"
3201 rajveer 971
    product_name = product_name.replace("  "," ")
3086 rajveer 972
    return product_name
973
 
974
 
975
def __get_product_url(item):
976
    product_url = "http://www.saholic.com/mobile-phones/" + item.brand + "-" + item.model_name + "-" + item.model_number + "-" + str(item.catalog_item_id)
977
    product_url = product_url.replace("--","-")
978
    product_url = product_url.replace(" ","")
979
    return product_url
980
 
3348 varun.gupt 981
def get_all_brands_by_category(category_id):
982
    catm = CategoryManager()
983
    child_categories = catm.getCategory(category_id).children_category_ids
984
    brands = session.query(distinct(Item.brand)).filter(Item.category.in_(child_categories)).all()
985
 
986
    return [brand[0] for brand in brands]
3086 rajveer 987
 
4957 phani.kuma 988
def get_all_brands():
989
    brands = session.query(distinct(Item.brand)).order_by(Item.brand).all()
990
 
991
    return [brand[0] for brand in brands]
992
 
3086 rajveer 993
def __enque_product_notification_email(email, product, date, url, itemId):
994
 
995
    html = """
996
        <html>
997
        <body>
998
        <div>
999
        <p>
1000
            Hi,<br /><br />
1001
            The product requested by you on $date is now available on saholic.com.
1002
        </p>
1003
 
1004
        <p>    
1005
        <strong>Product: $product </strong>
1006
        </p>
1007
 
1008
        <p>
1009
        Click the link below to visit the product: 
1010
        <br/>
1011
        $url
1012
        </p>
1013
        <p>
1014
        Regards,<br/>
1015
        Saholic Customer Support Team<br/>
1016
        www.saholic.com<br/>
1017
        Email: help@saholic.com<br/>
1018
        </p>
1019
        </div>
1020
        </body>
1021
        </html>
1022
        """
1023
 
1024
    html = Template(html).substitute(dict(product=product,date=date,url=url))
3079 rajveer 1025
 
3086 rajveer 1026
    try:
1027
        helper_client = HelperClient().get_client()
5866 rajveer 1028
        helper_client.saveUserEmailForSending([email], "", "Product requested by you is available now.", html, str(itemId), "ProductNotification", [], [])
3086 rajveer 1029
    except Exception as e:
1030
        print e
1031
 
3557 rajveer 1032
def get_all_sources():
1033
    sources = Source.query.all()
1034
    return [to_t_source(source) for source in sources]
3086 rajveer 1035
 
3557 rajveer 1036
def get_item_pricing_by_source(itemId, sourceId):
1037
    item = Item.query.filter_by(id=itemId).first()
1038
    if item is None:
1039
        raise InventoryServiceException(101, "Bad Item")
1040
 
1041
    source = Source.query.filter_by(id=sourceId).first()
1042
    if source is None:
1043
        raise InventoryServiceException(101, "Source not found for sourceId " + str(sourceId))
1044
 
1045
    item_pricing = SourceItemPricing.query.filter_by(source=source, item=item).first()
1046
    if item_pricing is None:
1047
        raise InventoryServiceException(101, "Pricing information not found for sourceId " + str(sourceId))
1048
    return item_pricing
1049
 
1050
def add_source_item_pricing(sourceItemPricing):
1051
    if not sourceItemPricing:
1052
        raise InventoryServiceException(108, "Bad sourceItemPricing in request")
1053
 
1054
    if not sourceItemPricing.sellingPrice:
4326 mandeep.dh 1055
        raise InventoryServiceException(101, "Selling Price is not defined for sourceId " + str(sourceItemPricing.sourceId))
3557 rajveer 1056
 
1057
    sourceId = sourceItemPricing.sourceId
1058
    itemId = sourceItemPricing.itemId
1059
 
1060
    item = Item.query.filter_by(id=itemId).first()
1061
    if item is None:
1062
        raise InventoryServiceException(101, "Bad Item")
1063
 
1064
    source = Source.query.filter_by(id=sourceId).first()
1065
    if source is None:
1066
        raise InventoryServiceException(101, "Source not found for sourceId " + str(sourceId))
1067
 
3564 rajveer 1068
    ds_sourceItemPricing = SourceItemPricing.get_by(source=source, item=item)
3557 rajveer 1069
    if ds_sourceItemPricing is None:
1070
        ds_sourceItemPricing = SourceItemPricing()
1071
        ds_sourceItemPricing.source = source
1072
        ds_sourceItemPricing.item = item
1073
 
1074
    if sourceItemPricing.mrp:
1075
        ds_sourceItemPricing.mrp = sourceItemPricing.mrp
1076
    ds_sourceItemPricing.sellingPrice = sourceItemPricing.sellingPrice
1077
 
1078
    session.commit()
1079
    return
1080
 
1081
def get_all_source_pricing(itemId):
1082
    item = Item.query.filter_by(id=itemId).first()
1083
    if item is None:
1084
        raise InventoryServiceException(101, "Bad Item")
1085
    source_pricing = SourceItemPricing.query.filter_by(item=item).all()
1086
    return source_pricing
1087
 
1088
 
1089
def get_item_for_source(item_id, sourceId):
1090
    item = get_item(item_id)
1091
    if sourceId == -1:
1092
        return item
1093
    try:
1094
        sip = get_item_pricing_by_source(item_id, sourceId)
1095
        item.sellingPrice = sip.sellingPrice
1096
        if sip.mrp:
1097
            item.mrp = sip.mrp
1098
    except:
1099
        print "No source pricing"
1100
    return item
1101
 
3872 chandransh 1102
def search_items(search_terms, offset, limit):
1103
    query = Item.query
1104
 
1105
    query_clause = []
1106
 
1107
    search_terms = ['%' + search_term + '%' for search_term in search_terms]
1108
 
1109
    for search_term in search_terms:
1110
        query_clause.append(Item.brand.like(search_term))
1111
        query_clause.append(Item.model_number.like(search_term))
1112
        query_clause.append(Item.model_name.like(search_term))
1113
 
1114
    query = query.filter(or_(*query_clause))
1115
 
1116
    query = query.order_by(Item.product_group, Item.brand, Item.model_number, Item.model_name).offset(offset)
1117
    if limit:
1118
        query = query.limit(limit)
1119
    items = query.all()
1120
    return items
1121
 
1122
def get_search_result_count(search_terms):
1123
    query = Item.query
1124
 
1125
    query_clause = []
1126
 
1127
    search_terms = ['%' + search_term + '%' for search_term in search_terms]
1128
 
1129
    for search_term in search_terms:
1130
        query_clause.append(Item.brand.like(search_term))
1131
        query_clause.append(Item.model_number.like(search_term))
1132
        query_clause.append(Item.model_name.like(search_term))
1133
 
1134
    query = query.filter(or_(*query_clause))
1135
 
1136
    return query.count()
1137
 
3924 rajveer 1138
def __clear_homepage_cache():
1139
    try:
1140
        # create a password manager
1141
        password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
1142
        # Add the username and password.
1143
        configclient = ConfigClient()
4310 rajveer 1144
        ips = configclient.get_property("production_servers_private_ips");
3924 rajveer 1145
        ips = ips.split(" ")
1146
 
1147
        for ip in ips:
4310 rajveer 1148
            try:
1149
                top_level_url = "http://" + ip + ":8080/"
1150
                password_mgr.add_password(None, top_level_url, "saholic", "shop2020")
1151
                handler = urllib2.HTTPBasicAuthHandler(password_mgr)
3924 rajveer 1152
 
4310 rajveer 1153
                opener = urllib2.build_opener(handler)
3924 rajveer 1154
 
4310 rajveer 1155
                # use the opener to fetch a URL
1156
                res = opener.open(top_level_url + "cache-admin/HomePageSnippets?_method=delete")
1157
                print "Successfully cleared home page cache" + res.read()
1158
            except:
1159
                print "Unable to clear home page cache" + res.read()
3924 rajveer 1160
    except:
1161
        print "Unable to clear cache, still should continue with other operations"
4024 chandransh 1162
 
4295 varun.gupt 1163
def get_product_notifications(start_datetime):
1164
    '''
1165
    Returns a list of Product Notification objects each representing user requests for notification
1166
    '''
1167
    query = ProductNotification.query
3924 rajveer 1168
 
4295 varun.gupt 1169
    if start_datetime:
1170
        query = query.filter(ProductNotification.addedOn > start_datetime)
1171
 
1172
    notifications = query.order_by(desc('addedOn')).all()
1173
    return notifications
1174
 
1175
def get_product_notification_request_count(start_datetime):
1176
    '''
1177
    Returns list of items and the counts of product notification requests
1178
    '''
1179
    print start_datetime
1180
    query = session.query(ProductNotification, func.count(ProductNotification.email).label('count'))
1181
 
1182
    if start_datetime:
1183
        query = query.filter(ProductNotification.addedOn > start_datetime)
1184
 
1185
    counts = query.group_by(ProductNotification.item_id).order_by(desc('count')).all()
1186
    return counts
1187
 
766 rajveer 1188
def close_session():
1189
    if session.is_active:
1190
        print "session is active. closing it."
1399 rajveer 1191
        session.close()
3376 rajveer 1192
 
1193
def is_alive():
1194
    try:
1195
        session.query(Item.id).limit(1).one()
1196
        return True
1197
    except:
1198
        return False
4332 anupam.sin 1199
 
4649 phani.kuma 1200
def add_authorization_log_for_item(itemId, username, reason):
1201
    if not itemId or not username:
1202
        raise InventoryServiceException(101, "Bad itemId or Invalid username in request")
1203
    authorize_log = AuthorizationLog()
1204
    authorize_log.item_id = itemId
1205
    authorize_log.username = username
1206
    authorize_log.reason = reason
1207
    session.commit()
4797 rajveer 1208
    return True
1209
 
1210
def __send_mail_for_oos_item(item): 
1211
    try:
4930 rajveer 1212
        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)+ " " + str(item.color), None)
4797 rajveer 1213
    except Exception as e:
1214
        print e
4985 mandeep.dh 1215
 
5047 amit.gupta 1216
def __send_mail(subject, message):
5080 amit.gupta 1217
    try:
1218
        thread = threading.Thread(target=partial(mail, from_user, from_pwd, to_addresses, subject, message))
1219
        thread.start()
1220
    except Exception as ex:
1221
        print ex    
5185 mandeep.dh 1222
 
5460 phani.kuma 1223
def get_clearance_sale_catalog_ids():
1224
    all_status = [status.ACTIVE, status.PAUSED, status.PAUSED_BY_RISK]
1225
    query = Item.query.filter_by(clearance=True)
1226
    query = query.filter(Item.status.in_(all_status))
1227
    query = query.group_by(Item.catalog_item_id).order_by(desc(Item.startDate)).order_by(Item.catalog_item_id)
1228
    clearance_sales = query.all()
1229
    return [item.catalog_item_id for item in clearance_sales]