Subversion Repositories SmartDukaan

Rev

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