Subversion Repositories SmartDukaan

Rev

Rev 7419 | Rev 7431 | 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
7291 vikram.rag 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, \
7340 amit.gupta 18
    OOSTracker, EntityTag, ItemInsurerMapping, Insurer, Banner, BannerMap, \
19
    FreebieItem, BrandInfo, Amazonlisted, StorePricing, ItemVatMaster
5944 mandeep.dh 20
from shop2020.thriftpy.model.v1.catalog.ttypes import status, ItemShippingInfo, \
7340 amit.gupta 21
    ItemType, PremiumType, FreebieItem as t_FreebieItem, \
22
    StorePricing as tStorePricing, CatalogServiceException
5944 mandeep.dh 23
from shop2020.thriftpy.model.v1.inventory.ttypes import \
6531 vikram.rag 24
    InventoryServiceException, IgnoredInventoryUpdateItems
4873 mandeep.dh 25
from shop2020.utils import EmailAttachmentSender
4748 mandeep.dh 26
from shop2020.utils.EmailAttachmentSender import mail
5318 rajveer 27
from shop2020.utils.Utils import to_py_date, log_risky_flag
621 chandransh 28
from sqlalchemy import desc, asc
6039 amit.gupta 29
from sqlalchemy.sql.expression import or_, distinct, func, and_
3086 rajveer 30
from string import Template
4748 mandeep.dh 31
import datetime
32
import sys
5393 mandeep.dh 33
import threading
3924 rajveer 34
import urllib2
7426 anupam.sin 35
import math
94 ashish 36
 
5978 rajveer 37
sourceId = int(ConfigClient().get_property("sourceid"))
6550 rajveer 38
to_addresses = ["khushal.bhatia@shop2020.in", "chandan.kumar@shop2020.in",  "chaitnaya.vats@shop2020.in"]
7384 rajveer 39
to_store_addresses = ["rajveer.singh@shop2020.in"]
6029 rajveer 40
mail_user = "cnc.center@shop2020.in"
41
mail_password = "5h0p2o2o"
42
source_name = "Saholic"
43
source_url = "www.saholic.com"
5885 mandeep.dh 44
skippedItems = { 175 : [27, 2160, 2175, 2163, 2158, 7128, 26, 2154],
45
                 193 : [5839] }
5047 amit.gupta 46
 
5295 rajveer 47
def initialize(dbname='catalog', db_hostname="localhost"):
48
    DataService.initialize(dbname, db_hostname)
5336 rajveer 49
 
3849 chandransh 50
def get_all_items_by_status(status, offset=0, limit=None):
51
    query = Item.query
4539 rajveer 52
    if status is not None:
3849 chandransh 53
        query = query.filter_by(status=status)
54
    query = query.order_by(Item.product_group, Item.brand, Item.model_number, Item.model_name).offset(offset)
55
    if limit:
56
        query = query.limit(limit)
57
    items = query.all()
58
    return items
59
 
6821 amar.kumar 60
def get_all_alive_items():
61
    query = Item.query
7095 amar.kumar 62
    query = query.filter(or_(Item.status==status.ACTIVE, Item.status==status.PAUSED, Item.status==status.PAUSED_BY_RISK))
6821 amar.kumar 63
    items = query.all()
64
    return items
65
 
66
 
3849 chandransh 67
def get_all_items(is_active, offset=0, limit=None):
103 ashish 68
    if is_active:
3849 chandransh 69
        items = get_all_items_by_status(status.ACTIVE, offset, limit)
103 ashish 70
    else:
3849 chandransh 71
        items = get_all_items_by_status(None, offset, limit)
766 rajveer 72
    return items
73
 
3849 chandransh 74
def get_item_count_by_status(use_status, status):
75
    if use_status:
76
        return Item.query.filter_by(status=status).count()
103 ashish 77
    else:
3849 chandransh 78
        return Item.query.count()
103 ashish 79
 
635 rajveer 80
def get_item(item_id):
766 rajveer 81
    item = Item.get_by(id=item_id)
82
    return item
94 ashish 83
 
635 rajveer 84
def get_items_by_catalog_id(catalog_id):
447 rajveer 85
    query = Item.query.filter_by(catalog_item_id=catalog_id)
437 rajveer 86
    try:
635 rajveer 87
        items = query.all()
4934 amit.gupta 88
        return items
1399 rajveer 89
    except Exception as ex:
90
        print ex
437 rajveer 91
        raise InventoryServiceException(109, "Item not found")
5586 phani.kuma 92
 
93
def is_valid_catalog_id(catalog_id):
94
    item = Item.query.filter_by(catalog_item_id=catalog_id).first()
95
    if item is not None:
96
        return True
97
    else:
98
        return False
99
 
576 chandransh 100
def is_active(item_id):
2983 chandransh 101
    t_item_shipping_info = ItemShippingInfo()
576 chandransh 102
    try:
635 rajveer 103
        item = get_item(item_id)
3281 chandransh 104
        t_item_shipping_info.isRisky = item.risky
5944 mandeep.dh 105
        client = InventoryClient().get_client()
5978 rajveer 106
        itemInfo = client.getItemAvailabilityAtLocation(item.id, sourceId)
5944 mandeep.dh 107
        warehouse_id = itemInfo[0]
5393 mandeep.dh 108
        if item.risky and item.status == status.ACTIVE:
5944 mandeep.dh 109
            availability = client.getItemAvailibilityAtWarehouse(warehouse_id, item_id)
110
            if availability <= 0:
5393 mandeep.dh 111
                add_status_change_log(item, status.PAUSED_BY_RISK)
112
                item.status = status.PAUSED_BY_RISK
113
                item.status_description = "This item is currently out of stock"
114
                session.commit()
115
                __send_mail_for_oos_item(item)
116
                #This will clear cache from tomcat
117
                __clear_homepage_cache()
118
        else:
5944 mandeep.dh 119
            availability = itemInfo[4]
2983 chandransh 120
        t_item_shipping_info.isActive = (item.status == status.ACTIVE)
3281 chandransh 121
        t_item_shipping_info.quantity = availability
576 chandransh 122
    except InventoryServiceException:
2983 chandransh 123
        print "[ERROR] Unexpected error:", sys.exc_info()[0]
124
    return t_item_shipping_info
125
 
2035 rajveer 126
def get_item_status_description(itemId):
127
    item = get_item(itemId)
128
    return item.status_description
94 ashish 129
 
122 ashish 130
def update_item(item):
131
    if not item:
132
        raise InventoryServiceException(108, "Bad item in request")
133
 
134
    if not item.id:
609 chandransh 135
        raise InventoryServiceException(101, "Missing id for update")
122 ashish 136
 
2120 ankur.sing 137
    validate_item_prices(item)
2065 ankur.sing 138
 
635 rajveer 139
    ds_item = get_item(item.id)
5047 amit.gupta 140
    message = ""
7384 rajveer 141
    store_message = ""
122 ashish 142
    if not ds_item:
609 chandransh 143
        raise InventoryServiceException(101, "Item missing in our database")
122 ashish 144
 
963 chandransh 145
    if item.productGroup:
146
        ds_item.product_group = item.productGroup 
147
    if item.brand:
148
        ds_item.brand = item.brand
511 rajveer 149
    if item.modelNumber:
150
        ds_item.model_number = item.modelNumber
2497 ankur.sing 151
    ds_item.color = item.color
152
    ds_item.model_name = item.modelName
153
    ds_item.category = item.category
6903 anupam.sin 154
    if item.category in [10001, 10002, 10003, 10004, 10005]:
155
        ds_item.preferredInsurer = 1
156
 
2497 ankur.sing 157
    ds_item.comments = item.comments
511 rajveer 158
 
2497 ankur.sing 159
    ds_item.catalog_item_id = item.catalogItemId
483 rajveer 160
 
7384 rajveer 161
    if ds_item.activeOnStore and ds_item.mrp and item.mrp and ds_item.mrp != item.mrp:
162
        sp = get_store_pricing(item.id)
163
        if sp.maxPrice > item.mrp:
164
            sp.maxPrice = item.mrp
165
            store_message += "MRP is changed from {0} to {1}.\n".format(sp.maxPrice, item.mrp)
166
 
167
 
168
    if ds_item.activeOnStore and ds_item.sellingPrice and item.sellingPrice and ds_item.sellingPrice != item.sellingPrice:
169
        sp = get_store_pricing(item.id)
170
        if sp.minPrice < item.sellingPrice:
171
            store_message += "Saholic MOP Changed. DP {0} is less than Saholic MOP.\n".format(sp.minPrice)
172
 
2129 ankur.sing 173
    ds_item.mrp = item.mrp
5047 amit.gupta 174
    if ds_item.sellingPrice or item.sellingPrice:
175
        if ds_item.sellingPrice != item.sellingPrice:
176
            message += "Selling Price is changed from {0} to {1}.\n".format(ds_item.sellingPrice, item.sellingPrice)
177
 
2129 ankur.sing 178
    ds_item.sellingPrice = item.sellingPrice
2497 ankur.sing 179
 
2174 ankur.sing 180
    ds_item.weight = item.weight
6241 amit.gupta 181
    ds_item.showSellingPrice = item.showSellingPrice
2129 ankur.sing 182
 
7291 vikram.rag 183
    if item.asin:
184
        ds_item.asin = item.asin
185
    ds_item.holdInventory = item.holdInventory
186
    ds_item.defaultInventory = item.defaultInventory
187
 
6826 amit.gupta 188
    if item.startDate:
189
        ds_item.startDate = to_py_date(item.startDate)
190
        ds_item.startDate = ds_item.startDate.replace(hour=0,second=0,minute=0)
191
        if item.itemStatus == status.COMING_SOON and ds_item.startDate < datetime.datetime.now()  :
192
            item.itemStatus = status.ACTIVE
193
            item.status_description = "This item is active"
194
    else:
195
        ds_item.startDate = None
196
 
2358 ankur.sing 197
    if ds_item.status != item.itemStatus:
2402 rajveer 198
        add_status_change_log(ds_item, item.itemStatus)
5047 amit.gupta 199
        if item.itemStatus == status.PHASED_OUT:
200
            message += "Item is phased out."
2358 ankur.sing 201
        ds_item.status = item.itemStatus
2035 rajveer 202
    if item.status_description:
203
        ds_item.status_description = item.status_description
122 ashish 204
 
511 rajveer 205
    if item.retireDate:
2116 ankur.sing 206
        ds_item.retireDate = to_py_date(item.retireDate)
2497 ankur.sing 207
    else:
208
        ds_item.retireDate = None
5217 amit.gupta 209
 
210
    if item.expectedArrivalDate:
211
        ds_item.expectedArrivalDate = to_py_date(item.expectedArrivalDate)
212
    else:
213
        ds_item.expectedArrivalDate = None
511 rajveer 214
 
5217 amit.gupta 215
    if item.comingSoonStartDate:
216
        ds_item.comingSoonStartDate = to_py_date(item.comingSoonStartDate)
6696 rajveer 217
        ds_item.comingSoonStartDate = ds_item.comingSoonStartDate.replace(hour=0,second=0,minute=0)
5217 amit.gupta 218
    else:
219
        ds_item.comingSoonStartDate = None
220
 
221
 
2497 ankur.sing 222
    ds_item.feature_id = item.featureId
223
    ds_item.feature_description = item.featureDescription
122 ashish 224
 
5047 amit.gupta 225
    if ds_item.bestDealText or item.bestDealText:
226
        if item.bestDealText != ds_item.bestDealText:
5080 amit.gupta 227
            message += "Promotion text is changed from '{0}' to '{1}'.\n".format(ds_item.bestDealText, item.bestDealText)
2129 ankur.sing 228
    ds_item.bestDealText = item.bestDealText
229
    ds_item.bestDealValue = item.bestDealValue
2065 ankur.sing 230
    ds_item.bestSellingRank = item.bestSellingRank
2497 ankur.sing 231
 
6777 vikram.rag 232
    if ds_item.bestDealsDetailsText or item.bestDealsDetailsText:
233
        if item.bestDealsDetailsText != ds_item.bestDealsDetailsText:
234
            message += "Best deals details text is changed from '{0}' to '{1}'.\n".format(ds_item.bestDealsDetailsText, item.bestDealsDetailsText)
235
    ds_item.bestDealsDetailsText = item.bestDealsDetailsText
236
 
237
    if ds_item.bestDealsDetailsLink or item.bestDealsDetailsLink:
238
        if item.bestDealsDetailsLink != ds_item.bestDealsDetailsLink:
239
            message += "Best deals details link is changed from '{0}' to '{1}'.\n".format(ds_item.bestDealsDetailsLink, item.bestDealsDetailsLink)
240
    ds_item.bestDealsDetailsLink = item.bestDealsDetailsLink
241
 
242
 
2065 ankur.sing 243
    ds_item.defaultForEntity = item.defaultForEntity
5047 amit.gupta 244
 
245
    if ds_item.risky or item.risky:
246
        if ds_item.risky != item.risky:
5080 amit.gupta 247
            message += "Risky flag is changed to '{0}'.\n".format(set)
5047 amit.gupta 248
 
2251 ankur.sing 249
    ds_item.risky = item.risky
3359 chandransh 250
 
5385 phani.kuma 251
    ds_item.type = ItemType._VALUES_TO_NAMES[item.type]
252
    ds_item.hasItemNo = item.hasItemNo
253
 
3459 chandransh 254
    if item.expectedDelay is not None:
3359 chandransh 255
        ds_item.expectedDelay = item.expectedDelay
4506 phani.kuma 256
 
257
    if item.preferredVendor:
5080 amit.gupta 258
        if item.preferredVendor != ds_item.preferredVendor:
5944 mandeep.dh 259
            inventoryClient = InventoryClient().get_client()
260
            newPreferredVendorName = inventoryClient.getVendor(item.preferredVendor).name
5080 amit.gupta 261
            oldPreferredVendorName = 'None'
262
            if ds_item.preferredVendor:
5944 mandeep.dh 263
                oldPreferredVendorName = inventoryClient.getVendor(ds_item.preferredVendor).name
5408 amit.gupta 264
            message += "Preferred vendor is changed from '{0}' to '{1}'.\n".format(oldPreferredVendorName, newPreferredVendorName)        
4506 phani.kuma 265
        ds_item.preferredVendor = item.preferredVendor
6838 vikram.rag 266
 
5080 amit.gupta 267
    if item.isWarehousePreferenceSticky != ds_item.isWarehousePreferenceSticky:
268
        flag = "ON" if item.isWarehousePreferenceSticky else "OFF"
269
        message += "Warehouse preference sticky is {0}.\n".format(flag)
270
 
4413 anupam.sin 271
    ds_item.isWarehousePreferenceSticky = item.isWarehousePreferenceSticky
3359 chandransh 272
 
7296 amit.gupta 273
    ds_item.updatedOn = datetime.datetime.now()
2065 ankur.sing 274
 
7382 rajveer 275
 
276
    if item.category not in [10001, 10002, 10003, 10004, 10005, 10009, 10010]:
7384 rajveer 277
        try:
278
            update_store_pricing(get_store_pricing(item.id), False)
279
            ds_item.activeOnStore = True
280
        except:
281
            print "Unable to update store pricing"
7382 rajveer 282
    else:
283
        ds_item.activeOnStore = item.activeOnStore
7265 rajveer 284
 
122 ashish 285
    session.commit();
5047 amit.gupta 286
    subject = "Item '{0}' is updated in Catalog. Id is {1}".format(__get_product_name(ds_item),ds_item.id)
287
    if message:
288
        __send_mail(subject, message)
7384 rajveer 289
    if store_message:
290
        __send_mail(subject, store_message, to_store_addresses)
122 ashish 291
    return ds_item.id
94 ashish 292
 
103 ashish 293
def add_item(item):
294
    if not item:
122 ashish 295
        raise InventoryServiceException(108, "Bad item in request")
635 rajveer 296
    if get_item(item.id):
122 ashish 297
        raise InventoryServiceException(101, "Item already exists")
2120 ankur.sing 298
 
299
    validate_item_prices(item)
300
 
103 ashish 301
    ds_item = Item()
963 chandransh 302
    if item.productGroup:
303
        ds_item.product_group = item.productGroup
304
    if item.brand:
305
        ds_item.brand = item.brand
515 rajveer 306
    if item.modelName:
307
        ds_item.model_name = item.modelName
308
    if item.modelNumber:
309
        ds_item.model_number = item.modelNumber
609 chandransh 310
    if item.color:
311
        ds_item.color = item.color
483 rajveer 312
    if item.category:
313
        ds_item.category = item.category
314
    if item.comments:
315
        ds_item.comments = item.comments
7291 vikram.rag 316
    if item.asin:
317
        ds_item.asin = item.asin
318
    ds_item.holdInventory = item.holdInventory
319
    ds_item.defaultInventory = item.defaultInventory    
7296 amit.gupta 320
    ds_item.addedOn = datetime.datetime.now()
321
    ds_item.updatedOn = datetime.datetime.now()
2116 ankur.sing 322
    if item.startDate:
323
        ds_item.startDate = to_py_date(item.startDate)
6696 rajveer 324
        ds_item.startDate = ds_item.startDate.replace(hour=0,second=0,minute=0)
2116 ankur.sing 325
    if item.retireDate:
326
        ds_item.retireDate = to_py_date(item.retireDate)
5217 amit.gupta 327
    if item.comingSoonStartDate:
328
        ds_item.comingSoonStartDate = to_py_date(item.comingSoonStartDate)
329
    if item.expectedArrivalDate:
330
        ds_item.expectedArrivalDate = to_py_date(item.expectedArrivalDate)    
483 rajveer 331
    if item.mrp:
332
        ds_item.mrp = item.mrp
333
    if item.sellingPrice:
334
        ds_item.sellingPrice = item.sellingPrice
122 ashish 335
    if item.weight:
336
        ds_item.weight = item.weight
337
 
338
    if item.featureId:
339
        ds_item.feature_id = item.featureId
340
    if item.featureDescription:
341
        ds_item.feature_description = item.featureDescription
342
 
2116 ankur.sing 343
 
103 ashish 344
    #check if categories present. If yes, add them to system
122 ashish 345
 
609 chandransh 346
    if item.bestDealValue:
347
        ds_item.bestDealValue = item.bestDealValue
348
    if item.bestDealText:
349
        ds_item.bestDealText = item.bestDealText
6777 vikram.rag 350
    if item.bestDealsDetailsText:
351
        ds_item.bestDealsDetailsText = item.bestDealsDetailsText
352
    if item.bestDealsDetailsLink:
353
        ds_item.bestDealsDetailsLink = item.bestDealsDetailsLink    
2116 ankur.sing 354
    if item.bestSellingRank:
355
        ds_item.bestSellingRank = item.bestSellingRank
356
    ds_item.defaultForEntity = item.defaultForEntity
2251 ankur.sing 357
    ds_item.risky = item.risky
609 chandransh 358
 
5385 phani.kuma 359
    ds_item.type = ItemType._VALUES_TO_NAMES[item.type]
360
    ds_item.hasItemNo = item.hasItemNo
7256 rajveer 361
    ds_item.activeOnStore = item.activeOnStore
5385 phani.kuma 362
 
3467 chandransh 363
    if item.expectedDelay is not None:
3359 chandransh 364
        ds_item.expectedDelay = item.expectedDelay
3467 chandransh 365
    else:
366
        ds_item.expectedDelay = 0
3359 chandransh 367
 
5408 amit.gupta 368
    preferredVendorName = "None"
4881 phani.kuma 369
    if item.preferredVendor:
370
        ds_item.preferredVendor = item.preferredVendor
5944 mandeep.dh 371
        inventoryClient = InventoryClient().get_client()
6838 vikram.rag 372
        preferredVendorName = inventoryClient.getVendor(item.preferredVendor).name
373
 
374
    if item.preferredInsurer is not None:
375
        ds_item.preferredInsurer = item.preferredInsurer             
4881 phani.kuma 376
 
5586 phani.kuma 377
    if item.catalogItemId:
378
        catalog_client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
379
        master_items = catalog_client.getItemsByCatalogId(item.catalogItemId)
380
        itemStatus = status.IN_PROCESS
381
        for masterItem in master_items:
382
            if masterItem.itemStatus in [status.CONTENT_COMPLETE, status.COMING_SOON, status.ACTIVE, status.PAUSED]:
383
                itemStatus = status.CONTENT_COMPLETE
384
                ds_item.category = masterItem.category
385
                break
386
        ds_item.catalog_item_id = item.catalogItemId
387
        ds_item.status = itemStatus
2116 ankur.sing 388
        ds_item.status_description = "This item is in process."
389
    else:
5586 phani.kuma 390
        # Check if a similar item already exists in our database
391
        similar_item = Item.query.filter_by(brand=item.brand, model_number=item.modelNumber, model_name=item.modelName).first()
392
        print "[SIMILAR ITEM FOUND:] FOR {0} {1} {2}".format(item.brand, item.modelNumber, item.modelName)
393
 
394
        if similar_item is None or similar_item.catalog_item_id is None:
395
            # If there is no similar item in the database from before,
396
            # use the entity_id_generator
397
            entity_id = EntityIDGenerator.query.first()
398
            ds_item.catalog_item_id = entity_id.id + 1
399
            ds_item.status = status.IN_PROCESS
400
            ds_item.status_description = "This item is in process."
401
            entity_id.id = entity_id.id  + 1
402
            if similar_item is not None and similar_item.catalog_item_id is None:
403
                similar_item.catalog_item_id = entity_id.id
404
        else:
405
            #If a similar item already exists for a product group, brand and model_number, set it as same.
406
            ds_item.catalog_item_id = similar_item.catalog_item_id
407
            ds_item.category = similar_item.category
408
            ds_item.product_group = similar_item.product_group
409
            ds_item.status = similar_item.status
410
            ds_item.status_description = similar_item.status_description
2116 ankur.sing 411
 
103 ashish 412
    session.commit();
5052 amit.gupta 413
    subject = "New item is added. Id is {0}".format(str(ds_item.id))
6777 vikram.rag 414
    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 415
    __send_mail(subject, message)
3325 chandransh 416
    return ds_item.id
417
 
103 ashish 418
def retire_item(item_id):
419
    if not item_id:
122 ashish 420
        raise InventoryServiceException(101, "bad item id")
635 rajveer 421
    item = get_item(item_id)
103 ashish 422
    if not item:
122 ashish 423
        raise InventoryServiceException(108, "item id not present")
424
    item.status = status.PHASED_OUT
425
    item.retireDate = datetime.datetime.now()
103 ashish 426
    session.commit()
122 ashish 427
 
428
#need to implement threads based solution here
103 ashish 429
def start_item_on(item_id, timestamp):
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")
103 ashish 435
 
122 ashish 436
    item.status = status.ACTIVE
437
    item.startDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))
438
    add_status_change_log(item, status.ACTIVE)
103 ashish 439
    session.commit()
440
 
122 ashish 441
#need to implement threads here
103 ashish 442
def retire_item_on(item_id, timestamp):
443
    if not item_id:
122 ashish 444
        raise InventoryServiceException(101, "bad item id")
635 rajveer 445
    item = get_item(item_id)
103 ashish 446
    if not item:
122 ashish 447
        raise InventoryServiceException(108, "item id not present")
103 ashish 448
 
122 ashish 449
    item.status = status.PHASED_OUT
450
    item.retireDate = datetime.datetime.fromtimestamp(to_py_date(timestamp))
451
    add_status_change_log(item, status.PHASED_OUT)
103 ashish 452
    session.commit()
453
 
454
def add_status_change_log(item, new_status):
455
    item_change_log = ItemChangeLog()
456
    item_change_log.new_status = new_status
457
    item_change_log.old_status = item.status
458
    item_change_log.timestamp = datetime.datetime.now()
459
    item_change_log.item = item
460
    session.commit()
461
 
462
def change_item_status(item_id, new_status):
463
    if not item_id:
122 ashish 464
        raise InventoryServiceException(101, "bad item id")
635 rajveer 465
    item = get_item(item_id)
103 ashish 466
    if not item:
122 ashish 467
        raise InventoryServiceException(108, "item id not present")
2116 ankur.sing 468
    add_status_change_log(item, new_status)
122 ashish 469
    item.status = new_status
2251 ankur.sing 470
    if item.status == status.PHASED_OUT:
471
        item.status_description = "This item has been phased out"
5047 amit.gupta 472
        __send_mail("Item '{0}' is Phased-Out. Item id is {1}".format(__get_product_name(item), item_id), "")
2251 ankur.sing 473
    elif item.status == status.DELETED:
474
        item.status_description = "This item has been deleted"
3924 rajveer 475
    elif item.status == status.PAUSED:
476
        item.status_description = "This item is currently out of stock"      
477
    elif item.status == status.PAUSED_BY_RISK:
478
        item.status_description = "This item is currently out of stock"
479
        #This will clear cache from tomcat
480
        __clear_homepage_cache()  
2251 ankur.sing 481
    elif item.status == status.ACTIVE:
482
        item.status_description = "This item is active"
483
    elif item.status == status.IN_PROCESS:
484
        item.status_description = "This item is in process"
485
    elif item.status == status.CONTENT_COMPLETE:
486
        item.status_description = "This item is in process"
103 ashish 487
    session.commit()
488
 
5944 mandeep.dh 489
def check_risky_item(item_id):
635 rajveer 490
    item = get_item(item_id)
2251 ankur.sing 491
    if not item.risky:
492
        return
5944 mandeep.dh 493
    client = InventoryClient().get_client()
5978 rajveer 494
    itemInfo = client.getItemAvailabilityAtLocation(item.id, sourceId)    
5944 mandeep.dh 495
    warehouse_id = itemInfo[0]
496
    availability = client.getItemAvailibilityAtWarehouse(warehouse_id, item.id)
497
    if availability <= 0:
2251 ankur.sing 498
        if item.status == status.ACTIVE:
2984 rajveer 499
            change_item_status(item.id, status.PAUSED_BY_RISK)
4797 rajveer 500
            __send_mail_for_oos_item(item)
2251 ankur.sing 501
    else:
2984 rajveer 502
        if item.status == status.PAUSED_BY_RISK:
2251 ankur.sing 503
            change_item_status(item.id, status.ACTIVE)
6255 rajveer 504
            __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 505
    session.commit()
2983 chandransh 506
 
2075 rajveer 507
def mark_item_as_content_complete(entity_id, category, brand, modelName, modelNumber):
2828 rajveer 508
    '''
509
    Get all the items for this entityID and update category, brand, modelName and modelNumber for all.
510
    Update Status for only IN_PROCESS items to CONTENT_COMPLETE
511
    '''
723 chandransh 512
    content_complete_status = status.CONTENT_COMPLETE
2828 rajveer 513
    items = Item.query.filter_by(catalog_item_id=entity_id).all()
723 chandransh 514
    current_timestamp = datetime.datetime.now()
515
    for item in items:
2828 rajveer 516
        if item.status == status.IN_PROCESS:
517
            item.status = content_complete_status
518
            item_change_log = ItemChangeLog()
519
            item_change_log.old_status = item.status
520
            item_change_log.new_status = content_complete_status
521
            item_change_log.timestamp = current_timestamp
522
            item_change_log.item = item
723 chandransh 523
 
4762 phani.kuma 524
        category_object = get_category(category)
525
        if category_object is not None:
526
            item.category = category
527
            item.product_group = category_object.display_name
2075 rajveer 528
        item.brand = brand
2081 rajveer 529
        item.model_name = modelName
530
        item.model_number = modelNumber
723 chandransh 531
        item.updatedOn = current_timestamp
532
    session.commit()
533
    return True
1294 chandransh 534
 
2404 chandransh 535
def get_child_categories(category):
536
    cm = CategoryManager()
2621 varun.gupt 537
    cat = cm.getCategory(category)
538
    return cat.children_category_ids if cat else None
2404 chandransh 539
 
626 chandransh 540
def get_best_sellers(start_index, stop_index, category=-1):
2404 chandransh 541
    '''
542
    Returns the Best Sellers between the start and the stop index in the given category
543
    '''
1926 rajveer 544
    query = get_best_sellers_query(category, None)
1098 chandransh 545
    best_sellers = query.all()[start_index:stop_index]
621 chandransh 546
    return get_thrift_item_list(best_sellers)
547
 
2093 chandransh 548
def get_best_sellers_count(category=-1):
2404 chandransh 549
    '''
550
    Returns the number of best sellers in the given category
551
    '''
1926 rajveer 552
    count = get_best_sellers_query(category, None).count()
1120 rajveer 553
    if count is None:
554
        count = 0
766 rajveer 555
    return count
621 chandransh 556
 
1926 rajveer 557
def get_best_sellers_catalog_ids(start_index, stop_index, brand, category=-1):
2404 chandransh 558
    '''
559
    Returns the Best sellers for the given brand and category between the start and the stop index.
560
    Ignores the category if it's passed as -1 and the brand if it's passed as None. 
561
    '''
1926 rajveer 562
    query = get_best_sellers_query(category, brand)
1098 chandransh 563
    best_sellers = query.all()[start_index:stop_index]
621 chandransh 564
    return [item.catalog_item_id for item in best_sellers]
1970 rajveer 565
 
1926 rajveer 566
def get_best_sellers_query(category, brand):
2404 chandransh 567
    '''
568
    Returns the query to be used for getting Best Sellers.
569
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
570
    '''
1098 chandransh 571
    query = Item.query.filter_by(status=status.ACTIVE).filter(Item.bestSellingRank != None)
626 chandransh 572
    if category != -1:
1970 rajveer 573
        all_categories = [category]
574
        child_categories = get_child_categories(category)
575
        if child_categories is not None:
576
            all_categories = all_categories + child_categories 
577
        query = query.filter(Item.category.in_(all_categories))
1926 rajveer 578
    if brand is not None:
579
        query = query.filter_by(brand=brand)
7202 amit.gupta 580
    query = query.group_by(Item.catalog_item_id).order_by(asc(Item.bestSellingRank))
621 chandransh 581
    return query
609 chandransh 582
 
1098 chandransh 583
def get_best_deals(category=-1):
2404 chandransh 584
    '''
585
    Returns the Best deals in the given category. Ignores the category if it's passed as -1.
586
    '''
587
    query = get_best_deals_query(Item, category, None)
1098 chandransh 588
    items = query.all()
609 chandransh 589
    return get_thrift_item_list(items)
590
 
1098 chandransh 591
def get_best_deals_count(category=-1):
2404 chandransh 592
    '''
593
    Returns the count of best deals in the given category.
594
    Ignores the category if it's -1.
595
    '''
596
    count = get_best_deals_counting_query(func.count(distinct(Item.catalog_item_id)), category, None).scalar()
1120 rajveer 597
    if count is None:
598
        count = 0
766 rajveer 599
    return count
501 rajveer 600
 
1926 rajveer 601
def get_best_deals_catalog_ids(start_index, stop_index, brand, category=-1):
2404 chandransh 602
    '''
603
    Returns the catalog_item_ids of best deal items for the given brand and category.
604
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
605
    '''
606
    query = get_best_deals_query(Item, category, brand)
1098 chandransh 607
    best_deal_items = query.all()[start_index:stop_index]
608
    return [item.catalog_item_id for item in best_deal_items]
609
 
2404 chandransh 610
def get_best_deals_counting_query(obj, category, brand):
611
    '''
612
    Returns the query to be used to select the best deals in the given brand and category.
613
    Ignores the category if it's passed as -1 and the brand if it's passed as None. 
614
    '''
615
    query = session.query(obj).filter_by(status=status.ACTIVE).filter(Item.bestDealValue != None)
626 chandransh 616
    if category != -1:
1970 rajveer 617
        all_categories = [category]
618
        child_categories = get_child_categories(category)
619
        if child_categories is not None:
620
            all_categories = all_categories + child_categories 
621
        query = query.filter(Item.category.in_(all_categories))
1926 rajveer 622
    if brand is not None:
623
        query = query.filter_by(brand=brand)
2404 chandransh 624
    return query
625
 
626
def get_best_deals_query(obj, category, brand):
627
    '''
628
    Returns the query to be used to get the best deals in the given category and brand.
629
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
630
    '''
631
    query = get_best_deals_counting_query(obj, category, brand)
1098 chandransh 632
    query = query.group_by(Item.catalog_item_id).order_by(desc(Item.bestDealValue))
633
    return query
609 chandransh 634
 
5217 amit.gupta 635
def get_coming_soon(category=-1):
636
    '''
637
    Returns the Coming Soon items in the given category. Ignores the category if it's passed as -1.
638
    '''
639
    query = get_coming_soon_query(Item, category, None)
640
    items = query.all()
641
    return get_thrift_item_list(items)
642
 
643
def get_coming_soon_count(category=-1):
644
    '''
645
    Returns the count of coming in the given category.
646
    Ignores the category if it's -1.
647
    '''
648
    count = get_coming_soon_counting_query(func.count(distinct(Item.catalog_item_id)), category, None).scalar()
649
    if count is None:
650
        count = 0
651
    return count
652
 
653
def get_coming_soon_catalog_ids(start_index, stop_index, brand, category=-1):
654
    '''
655
    Returns the catalog_item_ids of coming soon items for the given brand and category.
656
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
657
    '''
658
    query = get_coming_soon_query(Item, category, brand)
659
    coming_soon_items = query.all()[start_index:stop_index]
660
    return [item.catalog_item_id for item in coming_soon_items]
661
 
662
def get_coming_soon_counting_query(obj, category, brand):
663
    '''
664
    Returns the query to be used to select the coming soon product in the given brand and category.
665
    Ignores the category if it's passed as -1 and the brand if it's passed as None. 
666
    '''
667
    query = session.query(obj).filter_by(status=status.COMING_SOON)
668
    if category != -1:
669
        all_categories = [category]
670
        child_categories = get_child_categories(category)
671
        if child_categories is not None:
672
            all_categories = all_categories + child_categories 
673
        query = query.filter(Item.category.in_(all_categories))
674
    if brand is not None:
675
        query = query.filter_by(brand=brand)
676
    return query
677
 
678
def get_coming_soon_query(obj, category, brand):
679
    '''
680
    Returns the query to be used to get the coming soon products in the given category and brand.
681
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
682
    '''
683
    query = get_coming_soon_counting_query(obj, category, brand)
684
    query = query.group_by(Item.catalog_item_id).order_by(asc(Item.comingSoonStartDate))
685
    return query
686
 
1098 chandransh 687
def get_latest_arrivals(limit, category=-1):
2404 chandransh 688
    '''
689
    Returns up to limit number of Latest Arrivals in the given category.
690
    '''
2975 chandransh 691
    categories = []
692
    if category != -1:
693
        categories = [category]
694
    query = get_latest_arrivals_query(Item, categories, None)
1098 chandransh 695
    items = query.all()[0:limit]
609 chandransh 696
    return get_thrift_item_list(items)
598 chandransh 697
 
1098 chandransh 698
def get_latest_arrivals_count(limit, category=-1):
2404 chandransh 699
    '''
700
    Returns the number of latest arrivals which will be displayed on the website.
3016 chandransh 701
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 702
    '''
2975 chandransh 703
    categories = []
704
    if category != -1:
705
        categories = [category]
706
    count = get_latest_arrivals_counting_query(func.count(distinct(Item.catalog_item_id)), categories, None).scalar()
1120 rajveer 707
    if count is None:
708
        count = 0
709
    count = min(count, limit)
766 rajveer 710
    return count
602 chandransh 711
 
2975 chandransh 712
def get_latest_arrivals_catalog_ids(start_index, stop_index, brand, categories=[]):
2404 chandransh 713
    '''
714
    Returns the catalog_item_ids of the latest arrivals between the start and the stop index
3016 chandransh 715
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 716
    '''
2975 chandransh 717
    query = get_latest_arrivals_query(Item, categories, brand)
1098 chandransh 718
    latest_arrivals = query.all()[start_index:stop_index]
719
    return [item.catalog_item_id for item in latest_arrivals]
720
 
2975 chandransh 721
def get_latest_arrivals_counting_query(obj, categories, brand):
2404 chandransh 722
    '''
723
    Returns the query to be used to count Latest arrivals.
3016 chandransh 724
    To ignore the categories, pass the list as empty. To ignore brand, pass it as null.
2404 chandransh 725
    '''
726
    query = session.query(obj).filter_by(status=status.ACTIVE)
2975 chandransh 727
 
728
    all_categories = []
729
    for category in categories:
730
        all_categories.append(category)
1970 rajveer 731
        child_categories = get_child_categories(category)
2975 chandransh 732
        if child_categories:
733
            all_categories = all_categories + child_categories
734
    if all_categories: 
1970 rajveer 735
        query = query.filter(Item.category.in_(all_categories))
2975 chandransh 736
 
1926 rajveer 737
    if brand is not None:
738
        query = query.filter_by(brand=brand)
2404 chandransh 739
    return query
740
 
2975 chandransh 741
def get_latest_arrivals_query(obj, categories, brand):
2404 chandransh 742
    '''
743
    Returns the query to be used to retrieve Latest Arrivals.
744
    Ignores the category if it's passed as -1 and the brand if it's passed as None.
745
    '''
2975 chandransh 746
    query = get_latest_arrivals_counting_query(obj, categories, brand)
5167 rajveer 747
    query = query.group_by(Item.catalog_item_id).order_by(desc(Item.startDate)).order_by(Item.catalog_item_id)
1098 chandransh 748
    return query
609 chandransh 749
 
750
def get_thrift_item_list(items):
1098 chandransh 751
    return [to_t_item(item) for item in items if item != None]
635 rajveer 752
 
1155 rajveer 753
def generate_new_entity_id():
754
    generator =  EntityIDGenerator.query.one()
755
    id = generator.id + 1
756
    generator.id = id
757
    session.commit()
758
    return id
759
 
635 rajveer 760
def put_category_object(object):
761
    category = Category.get_by(id=1)
762
    if category is None:
763
        category = Category()
764
    category.object = object    
765
    session.commit()
766
    return True
767
 
768
def get_category_object():
766 rajveer 769
    object = Category.get_by(id=1).object
770
    return object
771
 
1970 rajveer 772
def add_category(t_category):
773
    category = Category.get_by(id=t_category.id)
774
    if category is None:
775
        category = Category()
776
    category.id = t_category.id 
777
    category.label = t_category.label
778
    category.description = t_category.description
4762 phani.kuma 779
    category.display_name = t_category.display_name
1970 rajveer 780
    category.parent_category_id = t_category.parent_category_id 
781
    session.commit()
782
    return True
783
 
784
def get_category(id):
785
    return Category.query.filter_by(id=id).first()
786
 
787
def get_all_categories():
788
    return Category.query.all()
789
 
2120 ankur.sing 790
def validate_item_prices(item):
2129 ankur.sing 791
    if item.mrp == None or item.sellingPrice == None or item.mrp == "" or item.sellingPrice == "":
792
        return
793
    if item.mrp < item.sellingPrice:
2120 ankur.sing 794
        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))
795
        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 796
    return
2120 ankur.sing 797
 
798
def validate_vendor_prices(item, vendorPrices):
2129 ankur.sing 799
    if item.mrp != None and item.mrp != "" and vendorPrices.mop != "" and item.mrp <  vendorPrices.mop:
2120 ankur.sing 800
        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))
801
        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)))
802
    if vendorPrices.mop != "" and vendorPrices.transferPrice != "" and vendorPrices.transferPrice > vendorPrices.mop:
803
        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))
804
        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)))
805
    return
2065 ankur.sing 806
 
4725 phani.kuma 807
def check_color_valid(color):
808
    if color is not None:
809
        color = color.strip().lower()
810
        if color != '' and color != 'na' and color != 'blank' and color != '(blank)':
811
            return True
812
    return False
813
 
814
def check_similar_item(brand, model_number, model_name, color):
2129 ankur.sing 815
    query = Item.query
2428 ankur.sing 816
    query = query.filter_by(brand=brand)
817
    query = query.filter_by(model_number=model_number)
4725 phani.kuma 818
    query = query.filter_by(model_name=model_name)
819
    similar_items = query.all()
820
    item = None
821
    # Check if a similar item already exists in our database
822
    for old_item in similar_items:
823
        if old_item.color != None and old_item.color.strip().lower() == color.strip().lower():
824
            item = old_item
825
            break
826
 
827
    # 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 828
    if item is None:
4725 phani.kuma 829
        for old_item in similar_items:
830
            if not check_color_valid(old_item.color):
831
                item = old_item
832
                break
833
    i = 0
834
    color_of_similar_item = None
835
    # Check if a similar item already exists in our database to be used to get catalog_item_id
836
    for old_item in similar_items:
837
        # get a similar item already existing in our database with valid color
838
        if check_color_valid(old_item.color):
839
            similar_item = old_item
840
            color_of_similar_item = similar_item.color
841
            break
842
        i = i + 1
843
        # get a similar item already existing in our database if similar item with valid color is not found
844
        if i == len(similar_items):
845
            similar_item = old_item
846
            color_of_similar_item = similar_item.color
847
 
848
    # Check if a similar item that is obtained above is having a valid color
849
    if check_color_valid(color_of_similar_item):
850
        # 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.
851
        # 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.
852
        if item is None and not check_color_valid(color):
853
            return similar_item.id
854
 
855
    if item is None:
2116 ankur.sing 856
        return 0
857
    else:
858
        return item.id
2286 ankur.sing 859
 
860
def change_risky_flag(item_id, risky):
861
    item = get_item(item_id)
862
    if not item:
863
        raise InventoryServiceException(101, "Item missing in our database")
864
    try:
865
        log_risky_flag(item_id, risky)
866
    except:
867
        print "Not able to log risky flag change"
868
    item.risky = risky
4295 varun.gupt 869
    if not risky and item.status == status.PAUSED_BY_RISK:
2368 ankur.sing 870
        change_item_status(item.id, status.ACTIVE)
6255 rajveer 871
        __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 872
    session.commit()
5047 amit.gupta 873
    flag = "ON" if risky else "OFF"
874
    subject = "Risky flag is {0} for Item {1}.".format(flag, __get_product_name(item))
875
    __send_mail(subject,"")
2286 ankur.sing 876
 
4957 phani.kuma 877
def get_items_for_mastersheet(categoryName, brand):
878
    if not categoryName or not brand:
879
        raise InventoryServiceException(101, "Invalid category or brand in request")
880
 
4762 phani.kuma 881
    categories = ["Handsets", "Tablets", "Laptops"]
4957 phani.kuma 882
    query = Item.query.filter(Item.status != status.PHASED_OUT)
883
    if categoryName == "ALL":
884
        pass
885
    elif categoryName == "ALL Accessories":
886
        query = query.filter(~Item.product_group.in_(categories))
887
    elif categoryName == "ALL Handsets":
888
        query = query.filter(Item.product_group.in_(categories))
889
    elif categoryName == "Mobile Accessories":
890
        child_categories = get_child_categories(10011)
891
        if child_categories is not None:
892
            child_categories.append(0)
893
            query = query.filter(Item.category.in_(child_categories))
894
    elif categoryName == "Laptop Accessories":
895
        child_categories = get_child_categories(10070)
896
        if child_categories is not None:
897
            child_categories.append(0)
898
            query = query.filter(Item.category.in_(child_categories))
899
    else:
900
        query = query.filter(Item.product_group == categoryName)
901
 
902
    if brand == "ALL":
903
        pass
904
    else:
905
        query = query.filter(Item.brand == brand)
2358 ankur.sing 906
    items = query.all()
907
    return items
2116 ankur.sing 908
 
2358 ankur.sing 909
def get_risky_items():
910
    items = Item.query.filter_by(risky=True).all()
911
    return items
3008 rajveer 912
 
2809 rajveer 913
def get_similar_items_catalog_ids(start_index, stop_index, itemId):
3008 rajveer 914
    query = SimilarItems.query.filter_by(item_id=itemId).limit(stop_index-start_index)
915
    similar_items = query.all()
3289 rajveer 916
    return_list = []
917
    for similar_item in similar_items:
918
        isActive = False
919
        try:
920
            all_items = Item.query.filter_by(catalog_item_id=similar_item.catalog_item_id).all()
921
        except:
922
            continue
923
        for item in all_items:
924
            isActive = isActive or item.status == status.ACTIVE
925
        if isActive:
926
            return_list.append(similar_item.catalog_item_id)
927
    return return_list
4423 phani.kuma 928
 
929
def get_all_similar_items_catalog_ids(itemId):
930
    query = SimilarItems.query.filter_by(item_id=itemId)
931
    similar_items = query.all()
932
    return_list = []
933
    for similar_item in similar_items:
934
        item_query = Item.query.filter_by(catalog_item_id=similar_item.catalog_item_id).limit(1)
935
        item = item_query.one()
936
        return_list.append(item)
2809 rajveer 937
 
4423 phani.kuma 938
    return get_thrift_item_list(return_list)
939
 
940
def add_similar_item_catalog_id(itemId, catalog_item_id):
941
    if not itemId or not catalog_item_id:
942
        raise InventoryServiceException(101, "Bad itemId or catalogItemId in request")
943
    items_for_entity = get_items_by_catalog_id(catalog_item_id)
944
    if not len(items_for_entity):
945
        raise InventoryServiceException(101, "catalogItemId does not exists in database")
946
 
947
    s_items = SimilarItems.query.filter_by(item_id=itemId, catalog_item_id=catalog_item_id).all()
948
    if not len(s_items):
949
        s_item = SimilarItems()
950
        s_item.item_id=itemId
951
        s_item.catalog_item_id=catalog_item_id
952
        session.commit()
953
        return items_for_entity[0]
954
    else:
955
        raise InventoryServiceException(101, "Already exists")
956
 
957
def delete_similar_item_catalog_id(itemId, catalog_item_id):
958
    if not itemId or not catalog_item_id:
959
        raise InventoryServiceException(101, "Bad itemId or catalogItemId in request")
960
 
961
    similar_item = SimilarItems.query.filter_by(item_id=itemId, catalog_item_id=catalog_item_id).all()
962
    if len(similar_item):
963
        similar_item[0].delete()
964
    session.commit()
965
    return True
5504 phani.kuma 966
 
967
def get_all_vouchers_for_item(itemId):
968
    vouchers = VoucherItemMapping.query.filter_by(item_id=itemId).all()
969
    return vouchers
970
 
971
def get_voucher_amount(itemId, voucher_type):
972
    voucher = VoucherItemMapping.query.filter_by(item_id=itemId, voucherType=voucher_type).all()
973
    if len(voucher):
974
        return voucher[0].amount
975
    else:
5518 rajveer 976
        return 0
5504 phani.kuma 977
 
978
def add_update_voucher_for_item(catalog_item_id, voucher_type, voucher_amount):
979
    if not catalog_item_id or not voucher_type or not voucher_amount:
980
        raise InventoryServiceException(101, "Bad catalogItemId or voucherType or voucherAmount in request")
981
 
982
    items_for_entity = get_items_by_catalog_id(catalog_item_id)
983
    if not len(items_for_entity):
984
        raise InventoryServiceException(101, "catalogItemId does not exists in database")
985
 
986
    for item in items_for_entity:
987
        itemId = item.id
988
        voucher = VoucherItemMapping.query.filter_by(item_id=itemId, voucherType=voucher_type).all()
989
        if not len(voucher):
990
            voucher = VoucherItemMapping()
991
            voucher.item_id=itemId
992
            voucher.voucherType=voucher_type
993
            voucher.amount=voucher_amount
994
        else:
995
            voucher[0].amount=voucher_amount
996
    session.commit()
997
    return True
4423 phani.kuma 998
 
5504 phani.kuma 999
def delete_voucher_for_item(catalog_item_id, voucher_type):
1000
    if not catalog_item_id or not voucher_type:
1001
        raise InventoryServiceException(101, "Bad catalogItemId or voucherType in request")
1002
 
1003
    items_for_entity = get_items_by_catalog_id(catalog_item_id)
1004
    if not len(items_for_entity):
1005
        raise InventoryServiceException(101, "catalogItemId does not exists in database")
1006
 
1007
    for item in items_for_entity:
1008
        itemId = item.id
1009
        voucher = VoucherItemMapping.query.filter_by(item_id=itemId, voucherType=voucher_type).all()
1010
        if len(voucher):
1011
            voucher[0].delete()
1012
    session.commit()
1013
    return True
1014
 
3079 rajveer 1015
def add_product_notification(itemId, email):
1016
    try:
3470 rajveer 1017
        try:
1018
            product_notification = ProductNotification.query.filter_by(item_id=itemId, email=email).one()
1019
        except:
1020
            product_notification = ProductNotification()
1021
            product_notification.email = email
1022
            product_notification.item_id = itemId
3079 rajveer 1023
        product_notification.addedOn = datetime.datetime.now()
1024
        session.commit()
1025
        return True
1026
    except:
1027
        return False
3086 rajveer 1028
 
1029
 
1030
def send_product_notifications():
7134 rajveer 1031
    product_notifications = ProductNotification.query.order_by(ProductNotification.addedOn).all()
1032
    itemcountmap = {}
1033
    itemstatusmap = {}
3086 rajveer 1034
    for product_notification in product_notifications:
1035
        item = product_notification.item
7134 rajveer 1036
        if itemcountmap.has_key(item.id):
1037
            itemcountmap[item.id] = itemcountmap.get(item.id) + 1
1038
        else:
1039
            client = InventoryClient().get_client()
1040
            availability = client.getItemAvailabilityAtLocation(item.id, sourceId)[4]
1041
            if item.status == status.ACTIVE and (not item.risky or availability > 0):        
1042
                itemstatusmap[item.id] = True
1043
            else:
1044
                itemstatusmap[item.id] = False
1045
            itemcountmap[item.id] = 1
1046
        if itemcountmap[item.id] > 1000:
1047
            continue
1048
 
1049
        if itemstatusmap[item.id]:
3086 rajveer 1050
            __enque_product_notification_email(product_notification.email, __get_product_name(item) , product_notification.addedOn, __get_product_url(item), item.id)
1051
            product_notification.delete()
1052
    session.commit()
1053
    return True
1054
 
1055
def __get_product_name(item):
1056
    product_name = item.brand + " " + item.model_name + " " + item.model_number
1057
    color = item.color
1058
    if color is not None and color != 'NA':
1059
        product_name = product_name + " (" + color + ")"
3201 rajveer 1060
    product_name = product_name.replace("  "," ")
3086 rajveer 1061
    return product_name
1062
 
1063
 
1064
def __get_product_url(item):
6029 rajveer 1065
    product_url = "http://" + source_url + "/mobile-phones/" + item.brand + "-" + item.model_name + "-" + item.model_number + "-" + str(item.catalog_item_id)
3086 rajveer 1066
    product_url = product_url.replace("--","-")
1067
    product_url = product_url.replace(" ","")
1068
    return product_url
1069
 
3348 varun.gupt 1070
def get_all_brands_by_category(category_id):
1071
    catm = CategoryManager()
1072
    child_categories = catm.getCategory(category_id).children_category_ids
1073
    brands = session.query(distinct(Item.brand)).filter(Item.category.in_(child_categories)).all()
1074
 
1075
    return [brand[0] for brand in brands]
3086 rajveer 1076
 
4957 phani.kuma 1077
def get_all_brands():
1078
    brands = session.query(distinct(Item.brand)).order_by(Item.brand).all()
1079
 
1080
    return [brand[0] for brand in brands]
1081
 
3086 rajveer 1082
def __enque_product_notification_email(email, product, date, url, itemId):
1083
 
1084
    html = """
1085
        <html>
1086
        <body>
1087
        <div>
1088
        <p>
1089
            Hi,<br /><br />
6029 rajveer 1090
            The product requested by you on $date is now available on $source_url.
7103 amar.kumar 1091
            <br />
1092
            We have limited stocks of this model at this moment. If you don't want to miss out, please place your order as soon as possible.
3086 rajveer 1093
        </p>
1094
 
1095
        <p>    
1096
        <strong>Product: $product </strong>
1097
        </p>
1098
 
1099
        <p>
1100
        Click the link below to visit the product: 
1101
        <br/>
1102
        $url
1103
        </p>
1104
        <p>
1105
        Regards,<br/>
6029 rajveer 1106
        $source_name Customer Support Team<br/>
1107
        $source_url<br/>
3086 rajveer 1108
        Email: help@saholic.com<br/>
1109
        </p>
1110
        </div>
1111
        </body>
1112
        </html>
1113
        """
1114
 
6029 rajveer 1115
    html = Template(html).substitute(dict(product=product,date=date,url=url,source_url=source_url,source_name=source_name))
3079 rajveer 1116
 
3086 rajveer 1117
    try:
1118
        helper_client = HelperClient().get_client()
5866 rajveer 1119
        helper_client.saveUserEmailForSending([email], "", "Product requested by you is available now.", html, str(itemId), "ProductNotification", [], [])
3086 rajveer 1120
    except Exception as e:
1121
        print e
1122
 
3557 rajveer 1123
def get_all_sources():
1124
    sources = Source.query.all()
1125
    return [to_t_source(source) for source in sources]
3086 rajveer 1126
 
3557 rajveer 1127
def get_item_pricing_by_source(itemId, sourceId):
1128
    item = Item.query.filter_by(id=itemId).first()
1129
    if item is None:
1130
        raise InventoryServiceException(101, "Bad Item")
1131
 
1132
    source = Source.query.filter_by(id=sourceId).first()
1133
    if source is None:
1134
        raise InventoryServiceException(101, "Source not found for sourceId " + str(sourceId))
1135
 
1136
    item_pricing = SourceItemPricing.query.filter_by(source=source, item=item).first()
1137
    if item_pricing is None:
1138
        raise InventoryServiceException(101, "Pricing information not found for sourceId " + str(sourceId))
1139
    return item_pricing
1140
 
1141
def add_source_item_pricing(sourceItemPricing):
1142
    if not sourceItemPricing:
1143
        raise InventoryServiceException(108, "Bad sourceItemPricing in request")
1144
 
1145
    if not sourceItemPricing.sellingPrice:
4326 mandeep.dh 1146
        raise InventoryServiceException(101, "Selling Price is not defined for sourceId " + str(sourceItemPricing.sourceId))
3557 rajveer 1147
 
1148
    sourceId = sourceItemPricing.sourceId
1149
    itemId = sourceItemPricing.itemId
1150
 
1151
    item = Item.query.filter_by(id=itemId).first()
1152
    if item is None:
1153
        raise InventoryServiceException(101, "Bad Item")
1154
 
1155
    source = Source.query.filter_by(id=sourceId).first()
1156
    if source is None:
1157
        raise InventoryServiceException(101, "Source not found for sourceId " + str(sourceId))
1158
 
3564 rajveer 1159
    ds_sourceItemPricing = SourceItemPricing.get_by(source=source, item=item)
3557 rajveer 1160
    if ds_sourceItemPricing is None:
1161
        ds_sourceItemPricing = SourceItemPricing()
1162
        ds_sourceItemPricing.source = source
1163
        ds_sourceItemPricing.item = item
1164
 
1165
    if sourceItemPricing.mrp:
1166
        ds_sourceItemPricing.mrp = sourceItemPricing.mrp
1167
    ds_sourceItemPricing.sellingPrice = sourceItemPricing.sellingPrice
1168
 
1169
    session.commit()
1170
    return
1171
 
1172
def get_all_source_pricing(itemId):
1173
    item = Item.query.filter_by(id=itemId).first()
1174
    if item is None:
1175
        raise InventoryServiceException(101, "Bad Item")
1176
    source_pricing = SourceItemPricing.query.filter_by(item=item).all()
1177
    return source_pricing
1178
 
1179
 
1180
def get_item_for_source(item_id, sourceId):
1181
    item = get_item(item_id)
1182
    if sourceId == -1:
1183
        return item
1184
    try:
1185
        sip = get_item_pricing_by_source(item_id, sourceId)
1186
        item.sellingPrice = sip.sellingPrice
1187
        if sip.mrp:
1188
            item.mrp = sip.mrp
1189
    except:
1190
        print "No source pricing"
1191
    return item
1192
 
3872 chandransh 1193
def search_items(search_terms, offset, limit):
1194
    query = Item.query
1195
 
1196
    search_terms = ['%' + search_term + '%' for search_term in search_terms]
1197
 
1198
    for search_term in search_terms:
6661 rajveer 1199
        query_clause = []
3872 chandransh 1200
        query_clause.append(Item.brand.like(search_term))
1201
        query_clause.append(Item.model_number.like(search_term))
1202
        query_clause.append(Item.model_name.like(search_term))
6661 rajveer 1203
        query = query.filter(or_(*query_clause))
3872 chandransh 1204
 
1205
    query = query.order_by(Item.product_group, Item.brand, Item.model_number, Item.model_name).offset(offset)
1206
    if limit:
1207
        query = query.limit(limit)
1208
    items = query.all()
1209
    return items
1210
 
1211
def get_search_result_count(search_terms):
1212
    query = Item.query
1213
 
1214
    search_terms = ['%' + search_term + '%' for search_term in search_terms]
1215
 
1216
    for search_term in search_terms:
6661 rajveer 1217
        query_clause = []
3872 chandransh 1218
        query_clause.append(Item.brand.like(search_term))
1219
        query_clause.append(Item.model_number.like(search_term))
1220
        query_clause.append(Item.model_name.like(search_term))
6661 rajveer 1221
        query = query.filter(or_(*query_clause))
3872 chandransh 1222
 
1223
    return query.count()
1224
 
3924 rajveer 1225
def __clear_homepage_cache():
1226
    try:
1227
        # create a password manager
1228
        password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
1229
        # Add the username and password.
1230
        configclient = ConfigClient()
4310 rajveer 1231
        ips = configclient.get_property("production_servers_private_ips");
3924 rajveer 1232
        ips = ips.split(" ")
1233
 
1234
        for ip in ips:
4310 rajveer 1235
            try:
1236
                top_level_url = "http://" + ip + ":8080/"
1237
                password_mgr.add_password(None, top_level_url, "saholic", "shop2020")
1238
                handler = urllib2.HTTPBasicAuthHandler(password_mgr)
3924 rajveer 1239
 
4310 rajveer 1240
                opener = urllib2.build_opener(handler)
3924 rajveer 1241
 
4310 rajveer 1242
                # use the opener to fetch a URL
1243
                res = opener.open(top_level_url + "cache-admin/HomePageSnippets?_method=delete")
1244
                print "Successfully cleared home page cache" + res.read()
1245
            except:
1246
                print "Unable to clear home page cache" + res.read()
3924 rajveer 1247
    except:
1248
        print "Unable to clear cache, still should continue with other operations"
4024 chandransh 1249
 
4295 varun.gupt 1250
def get_product_notifications(start_datetime):
1251
    '''
1252
    Returns a list of Product Notification objects each representing user requests for notification
1253
    '''
1254
    query = ProductNotification.query
3924 rajveer 1255
 
4295 varun.gupt 1256
    if start_datetime:
1257
        query = query.filter(ProductNotification.addedOn > start_datetime)
1258
 
1259
    notifications = query.order_by(desc('addedOn')).all()
1260
    return notifications
1261
 
1262
def get_product_notification_request_count(start_datetime):
1263
    '''
1264
    Returns list of items and the counts of product notification requests
1265
    '''
1266
    print start_datetime
1267
    query = session.query(ProductNotification, func.count(ProductNotification.email).label('count'))
1268
 
1269
    if start_datetime:
1270
        query = query.filter(ProductNotification.addedOn > start_datetime)
1271
 
1272
    counts = query.group_by(ProductNotification.item_id).order_by(desc('count')).all()
1273
    return counts
1274
 
766 rajveer 1275
def close_session():
1276
    if session.is_active:
1277
        print "session is active. closing it."
1399 rajveer 1278
        session.close()
3376 rajveer 1279
 
1280
def is_alive():
1281
    try:
1282
        session.query(Item.id).limit(1).one()
1283
        return True
1284
    except:
1285
        return False
4332 anupam.sin 1286
 
4649 phani.kuma 1287
def add_authorization_log_for_item(itemId, username, reason):
1288
    if not itemId or not username:
1289
        raise InventoryServiceException(101, "Bad itemId or Invalid username in request")
1290
    authorize_log = AuthorizationLog()
1291
    authorize_log.item_id = itemId
1292
    authorize_log.username = username
1293
    authorize_log.reason = reason
1294
    session.commit()
4797 rajveer 1295
    return True
1296
 
6255 rajveer 1297
def __send_mail_for_oos_item(item):
1298
    oos = OOSTracker.get_by(itemId = item.id)
1299
    if oos is None:
1300
        oos = OOSTracker()
1301
        oos.itemId = item.id
1302
        session.commit()
1303
        try:
6962 rajveer 1304
            EmailAttachmentSender.mail(mail_user, mail_password, to_addresses + ["pramit.singh@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)
6255 rajveer 1305
        except Exception as e:
1306
            print e
4985 mandeep.dh 1307
 
6255 rajveer 1308
def __send_mail_for_active_item(itemId, subject, message):
1309
    oos = OOSTracker.get_by(itemId = itemId)
1310
    if oos is not None:
1311
        oos.delete()
1312
        session.commit()
1313
    __send_mail(subject, message)
1314
 
7384 rajveer 1315
def __send_mail(subject, message, send_to  = to_addresses):
5080 amit.gupta 1316
    try:
7384 rajveer 1317
        thread = threading.Thread(target=partial(mail, mail_user, mail_password, send_to, subject, message))
5080 amit.gupta 1318
        thread.start()
1319
    except Exception as ex:
1320
        print ex    
5185 mandeep.dh 1321
 
6039 amit.gupta 1322
def get_vat_amount_for_item(itemId, price):
1323
    item = Item.query.filter_by(id=itemId).first()
1324
    vatPercentage = item.vatPercentage
1325
    if vatPercentage is None:
1326
        vatMaster = CategoryVatMaster.query.filter(and_(CategoryVatMaster.categoryId==item.category, CategoryVatMaster.minVal<=price,  CategoryVatMaster.maxVal>=price)).first()
1327
        vatPercentage = vatMaster.vatPercent
1328
        if  vatPercentage is None:
1329
            vatPercentage = 0
1330
    return (price*vatPercentage)/100
1331
 
7340 amit.gupta 1332
def get_vat_percentage_for_item(itemId, stateId, price):
7330 amit.gupta 1333
    itemVatMaster = ItemVatMaster.query.filter(and_(ItemVatMaster.itemId==itemId, ItemVatMaster.stateId==stateId)).first()
7340 amit.gupta 1334
    if itemVatMaster is None:
7330 amit.gupta 1335
            item = Item.query.filter_by(id=itemId).first()
7340 amit.gupta 1336
            if item is None:
1337
                raise CatalogServiceException(itemId, "Could not find item in catalog")
1338
            vatMaster = CategoryVatMaster.query.filter(and_(CategoryVatMaster.categoryId==item.category, CategoryVatMaster.minVal<=price,  CategoryVatMaster.maxVal>=price,  CategoryVatMaster.stateId == stateId)).first()
7330 amit.gupta 1339
            if vatMaster is None:
7340 amit.gupta 1340
                raise CatalogServiceException(stateId, "Could not find vat rate for this state.")
1341
            return vatMaster.vatPercent
7330 amit.gupta 1342
    else:
7340 amit.gupta 1343
        return itemVatMaster.vatPercentage
6511 kshitij.so 1344
 
6531 vikram.rag 1345
def get_all_ignored_inventoryupdate_items_list(offset,limit):
1346
    client = InventoryClient().get_client()
1347
    itemids = client.getIgnoredInventoryUpdateItemids(offset,limit)
6532 amit.gupta 1348
    result = []
1349
    if itemids is not None and len(itemids)>0:
1350
        query = Item.query.filter(Item.id.in_(itemids))
1351
        query = query.order_by(Item.product_group, Item.brand, Item.model_number, Item.model_name)
1352
        result = [to_t_item(item) for item in query.all()]
1353
    return result
6531 vikram.rag 1354
 
1355
 
6511 kshitij.so 1356
def add_tag (displayName, catalogId):
1357
    ent_tag = None
1358
    if catalogId is None or (not is_valid_catalog_id(catalogId)):            
1359
        raise InventoryServiceException(id, "Invalid CatalogId")
1360
    else:
1361
        ent_tag = EntityTag()
1362
        ent_tag.entityId = catalogId
1363
    if displayName is None:
1364
        raise InventoryServiceException(id, "Tag should not be empty")
1365
    else: 
1366
        ent_tag.tag = displayName
1367
    session.commit()
1368
    return True
1369
 
6848 kshitij.so 1370
def add_banner(bannerName, imageName,link, priority, isActive, hasMap):
1371
    banner_details=Banner()
1372
    banner_details.bannerName=bannerName
1373
    banner_details.imageName=imageName
1374
    banner_details.link=link
1375
    banner_details.priority=priority
1376
    banner_details.isActive=isActive
1377
    banner_details.hasMap=hasMap
1378
    session.commit()
1379
    return True
1380
 
1381
def get_all_banners():
1382
    return [tuple[0] for tuple in session.query(Banner.bannerName).all()]
1383
 
1384
def delete_banner(name):
1385
    session.query(Banner.bannerName).filter_by(bannerName=name).delete()
1386
    session.commit()
1387
    return True
1388
 
1389
def get_banner_details(name):
1390
    banner = Banner.get_by(bannerName=name)
1391
    return banner   
1392
 
1393
def get_active_banners():
1394
    print "Data accessor"
1395
    query= session.query(Banner)
1396
    banner= query.filter_by(isActive =True).order_by(desc(Banner.priority)).all()
1397
    print "Banner is",
1398
    print banner
1399
    return banner
1400
 
1401
def add_banner_map(bannerName, mapLink, coordinates):
1402
    banner_map_details=BannerMap()
1403
    banner_map_details.bannerName=bannerName
1404
    banner_map_details.mapLink=mapLink
1405
    banner_map_details.coordinates=coordinates
1406
    session.commit()
1407
    return True
1408
 
1409
def delete_banner_map(name):
1410
    session.query(BannerMap.bannerName).filter_by(bannerName=name).delete()
1411
    session.commit()
1412
    return True
1413
 
1414
def get_banner_map_details(name):
1415
    print "Data accessor"
1416
    query= session.query(BannerMap)
1417
    bannermap= query.filter_by(bannerName=name).all()
1418
    print "Banner is",
1419
    print bannermap
1420
    return bannermap
1421
 
6511 kshitij.so 1422
def get_all_tags ():
1423
    return [tuple[0] for tuple in session.query(EntityTag.tag).distinct().all()]
1424
 
1425
def get_all_entities_by_tag_name(displayName):
1426
    return [tuple[0] for tuple in session.query(EntityTag.entityId).filter_by(tag=displayName).all()]
1427
 
1428
def delete_tag(displayName):
1429
    session.query(EntityTag.entityId).filter_by(tag=displayName).delete()
1430
    session.commit()
1431
    return True
6518 kshitij.so 1432
 
1433
def delete_entity_tag(displayName, catalogId):
1434
    session.query(EntityTag.tag).filter_by(tag=displayName,entityId=catalogId).delete()
1435
    session.commit()
6805 anupam.sin 1436
    return True
1437
 
6921 anupam.sin 1438
def get_insurance_amount(itemId, price, insurerId, quantity):
6805 anupam.sin 1439
    itemInsurerMapping = ItemInsurerMapping.query.filter(ItemInsurerMapping.itemId == itemId).filter(ItemInsurerMapping.insurerId == insurerId).first()
1440
    if not itemInsurerMapping:
6903 anupam.sin 1441
        #Default insurance premium is 1.5%
6921 anupam.sin 1442
        return round(price * (1.5/100) * quantity)
6805 anupam.sin 1443
    insuranceAmount = 0.0
1444
    if itemInsurerMapping.premiumType == PremiumType._NAMES_TO_VALUES.get("PERCENT"):
6921 anupam.sin 1445
        insuranceAmount = price * (itemInsurerMapping.premiumAmount/100) * quantity
6805 anupam.sin 1446
    else :
1447
        insuranceAmount = itemInsurerMapping.premiumAmount * quantity
1448
 
1449
    return insuranceAmount
1450
 
1451
def get_insurer(insurerId):
6838 vikram.rag 1452
    return Insurer.get_by(id = insurerId)
6845 amit.gupta 1453
 
1454
def get_all_entity_tags():
1455
    entitiesTag = EntityTag.query.all()
1456
    entityMap = {}
1457
    for e in entitiesTag:
1458
        if not entityMap.has_key(e.entityId):
1459
            entityMap[e.entityId] = []
1460
        entityMap[e.entityId].append(e.tag)   
1461
    return entityMap
6838 vikram.rag 1462
 
1463
 
1464
def get_all_insurers():
1465
    print session.query(Insurer).all()
1466
    return session.query(Insurer).all()
6962 rajveer 1467
 
1468
def update_insurance_declared_amount(insurerId, amount):
1469
    insurer = Insurer.get_by(id = insurerId)
1470
    insurer.declaredAmount += amount
1471
    session.commit()
1472
    if insurer.declaredAmount > 0.9*insurer.creditedAmount:
1473
        __send_mail("CRITICAL: Declared Insurance Amount is critical (Declared Amount - " + str(insurer.declaredAmount) + " and Credited Amount - " + str(insurer.creditedAmount) +")", "Please top up credited amount")    
1474
    elif insurer.declaredAmount > 0.8*insurer.creditedAmount:
1475
        __send_mail("WARNING: Declared Insurance Amount is warning (Declared Amount - " + str(insurer.declaredAmount) + " and Credited Amount - " + str(insurer.creditedAmount) +")", "Please top up credited amount")    
1476
 
7190 amar.kumar 1477
def get_freebie_for_item(itemId):
1478
    freebie = FreebieItem.get_by(itemId = itemId)
1479
    if freebie is None:
1480
        return 0
1481
    else:
1482
        return freebie.freebieItemId
1483
 
1484
def add_or_update_freebie_for_item(freebieItem):
1485
    freebie = FreebieItem.get_by(itemId = freebieItem.itemId)
1486
    if freebie is None:
1487
        freebie = FreebieItem()
1488
        freebie.itemId = freebieItem.itemId
1489
    freebie.freebieItemId = freebieItem.freebieItemId
7256 rajveer 1490
    session.commit()
1491
 
7272 amit.gupta 1492
 
1493
def add_or_update_brand_info(brandInfo):
1494
    brandinfo = BrandInfo.get_by(name = brandInfo.name)
1495
    if brandinfo is None:
1496
        brandinfo = BrandInfo()
1497
        brandinfo.itemId = brandInfo.itemId
1498
        brandinfo.freebieItemId = brandInfo.freebieItemId
1499
    session.commit()
1500
 
1501
def get_brand_info():
1502
    brandInfoMap = dict()
1503
    brandInfoList = FreebieItem.query.all()
1504
    for brandInfo in brandInfoList:
1505
        brandInfoMap[brandInfo.name] = to_t_brand_info(brandInfo)
1506
    return brandInfoMap
1507
 
7382 rajveer 1508
def update_store_pricing(tsp, allColors):
7306 rajveer 1509
    validate_store_pricing(tsp)
7382 rajveer 1510
    item = get_item(tsp.itemId)
7419 rajveer 1511
    activeOnStore = item.activeOnStore
7382 rajveer 1512
    if allColors:
1513
        items = get_items_by_catalog_id(item.catalog_item_id)
1514
    else:
1515
        items = [item]
1516
    for item in items:
1517
        sp = StorePricing.get_by(item_id = item.id)
1518
        if not sp:
1519
            sp = StorePricing()
7419 rajveer 1520
        item.activeOnStore = activeOnStore
7382 rajveer 1521
        sp.recommendedPrice = tsp.recommendedPrice
1522
        sp.minPrice = tsp.minPrice
1523
        sp.minAdvancePrice = tsp.minAdvancePrice
1524
        sp.maxPrice = tsp.maxPrice
1525
        sp.item_id = item.id
1526
        sp.freebieItemId = tsp.freebieItemId
1527
        sp.bestDealText = tsp.bestDealText
1528
        sp.absoluteMinPrice = tsp.absoluteMinPrice
7265 rajveer 1529
    session.commit()
1530
 
1531
 
7306 rajveer 1532
def validate_store_pricing(tsp):
1533
    if tsp.minPrice > tsp.maxPrice:
7384 rajveer 1534
        raise InventoryServiceException(101, "DP is more than MRP")   
7306 rajveer 1535
 
1536
    item = get_item(tsp.itemId)
1537
 
7384 rajveer 1538
    if item.mrp and tsp.maxPrice > item.mrp:
1539
        raise InventoryServiceException(101, "MRP is more than Saholic MRP")
7306 rajveer 1540
 
1541
    if tsp.recommendedPrice < item.sellingPrice:
7384 rajveer 1542
        raise InventoryServiceException(101, "MOP is less than Saholic MOP.")   
7306 rajveer 1543
 
1544
    if tsp.recommendedPrice < tsp.minPrice or tsp.recommendedPrice >  tsp.maxPrice:
7384 rajveer 1545
        raise InventoryServiceException(101, "MOP price must be in the range") 
7306 rajveer 1546
 
7384 rajveer 1547
    if tsp.minPrice < item.sellingPrice:
1548
        store_message = "Saholic MOP Changed. DP {0} is less than Saholic MOP.\n".format(tsp.minPrice)
1549
        subject = "Item '{0}' is updated in Catalog. Id is {1}".format(__get_product_name(item),item.id)
1550
        __send_mail(subject, store_message, to_store_addresses)
1551
 
7306 rajveer 1552
    return True
1553
 
1554
 
1555
 
1556
def get_defalut_store_pricing(itemId):
7256 rajveer 1557
    inventoryClient = InventoryClient().get_client()
7306 rajveer 1558
    pricings = inventoryClient.getAllItemPricing(itemId)
1559
    item = get_item(itemId)
7382 rajveer 1560
    maxp = item.sellingPrice
1561
    if item.mrp:
1562
        maxp = item.mrp
1563
 
7256 rajveer 1564
    minp = 0
7265 rajveer 1565
    rp = item.sellingPrice
7256 rajveer 1566
    for pricing in pricings:
1567
        if not minp or minp > pricing.dealerPrice: 
1568
            minp = pricing.dealerPrice
7306 rajveer 1569
 
7256 rajveer 1570
 
7426 anupam.sin 1571
    minap = math.ceil(min(max(500, rp*0.1),rp))
7306 rajveer 1572
 
1573
    sp = tStorePricing()
1574
    sp.itemId = itemId
7256 rajveer 1575
    sp.recommendedPrice = rp
7351 rajveer 1576
    sp.absoluteMinPrice = minp
7256 rajveer 1577
    sp.minPrice = minp
1578
    sp.minAdvancePrice = minap
1579
    sp.maxPrice = maxp
7308 rajveer 1580
    sp.freebieItemId = 0
1581
    sp.bestDealText = ""
7306 rajveer 1582
    return sp
7322 vikram.rag 1583
 
1584
 
7256 rajveer 1585
def get_store_pricing(itemId):
7270 rajveer 1586
    store = StorePricing.get_by(item_id = itemId)
7306 rajveer 1587
    if store is None:
1588
        return get_defalut_store_pricing(itemId)
1589
 
7256 rajveer 1590
    sp = tStorePricing()
7306 rajveer 1591
    sp.itemId = itemId    
7256 rajveer 1592
    sp.recommendedPrice = store.recommendedPrice
1593
    sp.minPrice = store.minPrice
1594
    sp.minAdvancePrice = store.minAdvancePrice
1595
    sp.maxPrice = store.maxPrice
7351 rajveer 1596
    sp.absoluteMinPrice = store.absoluteMinPrice
7308 rajveer 1597
    sp.freebieItemId = store.freebieItemId
1598
    sp.bestDealText = store.bestDealText
7281 kshitij.so 1599
    return sp
1600
 
1601
def get_all_amazon_listed_items():
1602
    return session.query(Amazonlisted).all()
1603
 
1604
def get_amazon_item_details(amazonItemId):
1605
    amazonlisted = Amazonlisted.get_by(itemId=amazonItemId)
1606
    return amazonlisted
1607
 
7367 kshitij.so 1608
def update_amazon_item_details(amazonItemId,fbaPrice,sellingPrice,isFba,isNonFba,isInventoryOverride,handlingTime,isCustomTime):
7281 kshitij.so 1609
    amazonlisted = Amazonlisted.get_by(itemId = amazonItemId)
1610
    amazonlisted.fbaPrice=fbaPrice
1611
    amazonlisted.sellingPrice=sellingPrice
1612
    amazonlisted.isFba=isFba
1613
    amazonlisted.isNonFba=isNonFba
1614
    amazonlisted.isInventoryOverride=isInventoryOverride
7367 kshitij.so 1615
    amazonlisted.handlingTime=handlingTime
1616
    amazonlisted.isCustomTime=isCustomTime
7281 kshitij.so 1617
    session.commit()
1618
 
1619
def add_amazon_item(amazonlisted):
1620
    if (not amazonlisted) or (not amazonlisted.itemid) or (not amazonlisted.asin):
1621
        return
7397 kshitij.so 1622
    amazonItem = Amazonlisted.get_by(itemId=amazonlisted.itemid)
1623
    if amazonItem is None:
1624
        amazon_item = Amazonlisted()
1625
        if amazonlisted.itemid:
1626
            amazon_item.itemId=amazonlisted.itemid
1627
        if amazonlisted.asin:
1628
            amazon_item.asin=amazonlisted.asin
1629
        if amazonlisted.brand:
1630
            amazon_item.brand=amazonlisted.brand
1631
        else:
1632
            amazon_item.brand=''
1633
        if amazonlisted.model:
1634
            amazon_item.model=amazonlisted.model
1635
        else:
1636
            amazon_item.model=''
1637
        if amazonlisted.manufacturer_name:
1638
            amazon_item.manufacturer_name=amazonlisted.manufacturer_name
1639
        else:
1640
            amazon_item.manufacturer_name=''
1641
        if amazonlisted.name:
1642
            amazon_item.name=amazonlisted.name
1643
        else:
1644
            amazon_item.name=''
1645
        if amazonlisted.part_number:
1646
            amazon_item.part_number=amazonlisted.part_number
1647
        else:
1648
            amazon_item.part_number=''
1649
        if amazonlisted.ean:
1650
            amazon_item.ean=amazonlisted.ean
1651
        else:
1652
            amazon_item.ean=''
1653
        if amazonlisted.upc:
1654
            amazon_item.upc=amazonlisted.upc
1655
        else:
1656
            amazon_item.upc=''
1657
        if amazonlisted.sellingPrice:
1658
            amazon_item.sellingPrice=amazonlisted.sellingPrice
1659
        if amazonlisted.fbaPrice:
1660
            amazon_item.fbaPrice=amazonlisted.fbaPrice
1661
        if amazonlisted.isFba:
1662
            amazon_item.isFba=amazonlisted.isFba
1663
        if amazonlisted.isNonFba:
1664
            amazon_item.isNonFba=amazonlisted.isNonFba
1665
        if amazonlisted.isInventoryOverride:
1666
            amazon_item.isInventoryOverride=amazonlisted.isInventoryOverride
1667
        if amazonlisted.category:
1668
            amazon_item.category=amazonlisted.category
1669
        else:
1670
            amazon_item.category=''
1671
        if amazonlisted.color:
1672
            amazon_item.color=amazonlisted.color
1673
        else:
7404 kshitij.so 1674
            amazon_item.color=''
7397 kshitij.so 1675
    elif (amazonItem.asin!=amazonlisted.asin):
1676
        if amazonlisted.asin:
1677
            amazonItem.asin=amazonlisted.asin
1678
        if amazonlisted.brand:
1679
            amazonItem.brand=amazonlisted.brand
1680
        else:
1681
            amazonItem.brand=''
1682
        if amazonlisted.model:
1683
            amazonItem.model=amazonlisted.model
1684
        else:
1685
            amazonItem.model=''
1686
        if amazonlisted.manufacturer_name:
1687
            amazonItem.manufacturer_name=amazonlisted.manufacturer_name
1688
        else:
1689
            amazonItem.manufacturer_name=''
1690
        if amazonlisted.name:
1691
            amazonItem.name=amazonlisted.name
1692
        else:
1693
            amazonItem.name=''
1694
        if amazonlisted.part_number:
1695
            amazonItem.part_number=amazonlisted.part_number
1696
        else:
1697
            amazonItem.part_number=''
1698
        if amazonlisted.ean:
1699
            amazonItem.ean=amazonlisted.ean
1700
        else:
1701
            amazonItem.ean=''
1702
        if amazonlisted.upc:
1703
            amazonItem.upc=amazonlisted.upc
1704
        else:
1705
            amazonItem.upc=''
1706
        if amazonlisted.sellingPrice:
1707
            amazonItem.sellingPrice=amazonlisted.sellingPrice
1708
        if amazonlisted.fbaPrice:
1709
            amazonItem.fbaPrice=amazonlisted.fbaPrice
1710
        if amazonlisted.isFba:
1711
            amazonItem.isFba=amazonlisted.isFba
1712
        if amazonlisted.isNonFba:
1713
            amazonItem.isNonFba=amazonlisted.isNonFba
1714
        if amazonlisted.isInventoryOverride:
1715
            amazonItem.isInventoryOverride=amazonlisted.isInventoryOverride
1716
        if amazonlisted.category:
1717
            amazonItem.category=amazonlisted.category
1718
        else:
1719
            amazonItem.category=''
1720
        if amazonlisted.color:
1721
            amazonItem.color=amazonlisted.color
1722
        else:
7404 kshitij.so 1723
            amazonItem.color=''
7316 kshitij.so 1724
    else:
7397 kshitij.so 1725
        return
7281 kshitij.so 1726
    session.commit()
1727
 
7291 vikram.rag 1728
def get_asin_items():
7296 amit.gupta 1729
    from_date=datetime.datetime.now() - datetime.timedelta(days=10)
7291 vikram.rag 1730
    return Item.query.filter(Item.updatedOn > from_date).all()
7281 kshitij.so 1731
 
7291 vikram.rag 1732
def get_all_fba_listed_items():
1733
    return Amazonlisted.query.filter(Amazonlisted.isFba==True).all()
7281 kshitij.so 1734
 
7291 vikram.rag 1735
def get_all_nonfba_listed_items():
1736
    return Amazonlisted.query.filter(Amazonlisted.isNonFba==True).all()
7281 kshitij.so 1737
 
1738