Subversion Repositories SmartDukaan

Rev

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