Subversion Repositories SmartDukaan

Rev

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