Subversion Repositories SmartDukaan

Rev

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