Subversion Repositories SmartDukaan

Rev

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