Subversion Repositories SmartDukaan

Rev

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