Subversion Repositories SmartDukaan

Rev

Rev 22256 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

from datetime import datetime
from dtr.storage.MemCache import MemCache
from dtr.utils.utils import get_mongo_connection, SOURCE_MAP
from elixir import *
from shop2020.clients.InventoryClient import InventoryClient
from shop2020.model.v1.catalog.impl import DataService as CatalogDataService
from shop2020.model.v1.catalog.impl.DataService import Item, PrivateDeals, \
    BulkItemPricing, Tag_Listing
from shop2020.model.v1.inventory.impl import DataService as InventoryDataService
from shop2020.model.v1.inventory.impl.DataService import ItemAvailabilityCache
import optparse
import traceback

parser = optparse.OptionParser()
parser.add_option("-H", "--host", dest="hostname",
                      default="localhost",
                      type="string", help="The HOST where the DB server is running",
                      metavar="host")
parser.add_option("-m", "--m", dest="mongoHost",
                      default="localhost",
                      type="string", help="The HOST where the mongo server is running",
                      metavar="mongo_host")

(options, args) = parser.parse_args()

bundleMap = {}
inventoryMap = {}
memCon = None
maxQuantity = 100
flaggedItems = []
itemPricingMap = {}
#listingPricing map is {<itemId>:[{tag_id:<tagId>, selling_price:<sellingPrice>, mop:<mop>}]}
listingPricingMap = {}
bulkItemsMap = {}

def get_inventory_client():
    ic = InventoryClient("inventory_service_server_host2","inventory_service_server_port2").get_client()
    return ic

def get_memcache_connection(host='127.0.0.1'):
    global memCon
    if memCon is None:
        print "Establishing connection %s host" %(host)
        try:
            memCon = MemCache(host)
        except Exception, e:
            print e
            return None
    return memCon

def populateSaholicBundles():
    global bundleMap
    allSaholicBundles = get_mongo_connection(host=options.mongoHost).Catalog.MasterData.find({'source_id':SOURCE_MAP.get('SAHOLIC'),'category_id':{"$in":[3,5,6]}})
    for item in allSaholicBundles:
        try:
            if item.get('identifier') is not None or item.get('identifier').strip()!="":
                #validItems.append({'_id':item.get('_id'),'catalog_item_id':long(item.get('identifier'))})
                bundleMap[long(item.get('identifier'))] = []
                
            else:
                print "Identifier not valid for %d"%(item.get('_id'))
                print item.get('identifier')
        except Exception as e:
            print e
            print "Exception Identifier not valid for %d"%(item.get('_id'))

def addItemIdInfo():
    global bundleMap
    global itemPricingMap
    try:
        CatalogDataService.initialize(db_hostname=options.hostname,setup=False)
        item_id_tags = session.query(Tag_Listing).all()
        item_id_tags_map = {}
        for item_id_tag in item_id_tags:
            if not item_id_tags_map.has_key(item_id_tag.item_id):
                item_id_tags_map[item_id_tag.item_id] = []
            item_id_tags_map.get(item_id_tag.item_id).append(item_id_tag.tag_id)
        
        totalLength = len(bundleMap.keys())
        fetch =100
        start = 0
        toBreak = False
        while(True):
            print start
            print fetch
            if fetch > totalLength:
                fetch = totalLength
                toBreak = True
                
            item_list = bundleMap.keys()[start:fetch]
            #No more normal deals only privatedeals are to be considered here
            items = session.query(Item,PrivateDeals).join((PrivateDeals,Item.id==PrivateDeals.item_id)).filter(Item.catalog_item_id.in_(item_list)).all()
            for i in items:
                d_item = i[0]
                d_privatedeal = i[1]
                tempList = bundleMap.get(d_item.catalog_item_id)
#               sellingPrice = d_item.sellingPrice
#               sellingPriceType = "Normal"
                if d_privatedeal is not None and d_privatedeal.isActive==1 and d_privatedeal.startDate < datetime.now() and d_privatedeal.endDate > datetime.now() and d_privatedeal.dealPrice >0:
                    sellingPrice = d_privatedeal.dealPrice
                    sellingPriceType = "Private deal price"
                    temp = {'item_id':d_item.id,'color':d_item.color,'sellingPrice':sellingPrice,'sellingPriceType':sellingPriceType,'minBuyQuantity':d_item.minimumBuyQuantity,
                            'quantityStep':d_item.quantityStep,'maxQuantity':d_item.maximumBuyQuantity}
                    if item_id_tags_map.has_key(d_item.id):
                        temp['tag_ids'] = item_id_tags_map.get(d_item.id)
                    tempList.append(temp)
                    itemPricingMap[d_item.id] =sellingPrice

            if toBreak:
                print "Breaking"
                break
            start = fetch
            fetch = start + fetch
    finally:
        session.close()

def addInfoToMemCache():
    for k, v in bundleMap.iteritems():
        for item in v:
            availability = inventoryMap.get(item.get('item_id'))
            if availability is None:
                availability = 0
            item['availability'] = availability
            if availability < maxQuantity:
                temp_maxQuantity = availability
            else:
                temp_maxQuantity = maxQuantity
            if item.get('maxQuantity') is None or item.get('maxQuantity')==0:
                item['maxQuantity'] = temp_maxQuantity
            else:
                item['maxQuantity'] = min(availability,item.get('maxQuantity'))
            if item['minBuyQuantity'] > availability:
                item['minBuyQuantity'] = availability
            checkBulkPrices(item)
            item['bulkPricing'] = sorted(item['bulkPricing'], key=lambda k: k['quantity'],reverse=False)
            
        temp = sorted(v, key = lambda x: (x['availability']),reverse=True)
        mc = get_memcache_connection(host=options.mongoHost)
        mc.set(str("item_availability_"+str(k)), temp, 60*60)

def checkBulkPrices(item):
    adjusted = False
    """Lets check minBuyQty exist in bulkPricing"""
    minBuyQty = item['minBuyQuantity']
    for bulkPricingDict in item['bulkPricing']:
        if bulkPricingDict.get('quantity') == minBuyQty:
            adjusted = True
    if minBuyQty > 1 and not adjusted:
        allBulkPricing = bulkItemsMap.get(item.get('item_id'))
        if allBulkPricing is None or len(allBulkPricing) == 0:
            item['bulkPricing'] = [{'quantity':minBuyQty,'price':item.get('sellingPrice')}]
        else:
            allBulkPricing = sorted(allBulkPricing, key=lambda k: k['quantity'],reverse=False)
            effectiveBulkPrice = None
            for bulkPricing in allBulkPricing:
                if bulkPricing.get('quantity') < minBuyQty:
                    effectiveBulkPrice = bulkPricing
            if effectiveBulkPrice is None:
                item['bulkPricing'].append({'quantity':minBuyQty,'price':item.get('sellingPrice')})
            else:
                item['bulkPricing'].append({'quantity':minBuyQty,'price':effectiveBulkPrice['price']})
    toremove = []
    for bulkPricing in item['bulkPricing']:
        if bulkPricing['quantity'] < item['minBuyQuantity'] or bulkPricing['quantity'] > item['maxQuantity']:
            toremove.append(bulkPricing)
    for removePricing in toremove:
        item['bulkPricing'].remove(removePricing)
    
                    
def flagNoAvailableItems():
    global flaggedItems
    for k, v in bundleMap.iteritems():
        for item in v:
            availability = inventoryMap.get(item.get('item_id'))
            if availability is None:
                flaggedItems.append(item.get('item_id'))

def addBulkPricingInfo():
    global bulkItemsMap
    bulkItems = session.query(BulkItemPricing).all()
    for item in bulkItems:
        if bulkItemsMap.has_key(item.item_id):
            temp_list = bulkItemsMap.get(item.item_id)
            temp_list.append({'quantity':item.quantity,'price':item.price}) 
        else:
            bulkItemsMap[item.item_id] = [{'quantity':item.quantity,'price':item.price}]
    for k, v in bundleMap.iteritems():
        for item in v:
            bulkPricing = bulkItemsMap.get(item.get('item_id'))
            if bulkPricing is None:
                item['bulkPricing'] = []
            else:
                singleUnitPricing = False
                for temp in bulkPricing:
                    if temp.get('quantity') ==1:
                        singleUnitPricing = True
                if not singleUnitPricing:
                    bulkPricing.append({'quantity':1,'price':itemPricingMap.get(item.get('item_id'))})
                item['bulkPricing'] = bulkPricing

    
def fetchItemAvailablity():
    global inventoryMap
    try: 
        InventoryDataService.initialize(db_hostname=options.hostname,setup=False)
        allInventory = session.query(ItemAvailabilityCache).filter(ItemAvailabilityCache.sourceId==1).all()
        for itemInventory in allInventory:
            inventoryMap[itemInventory.itemId] = itemInventory.totalAvailability
    finally:
        session.close()


if __name__ == '__main__':
    populateSaholicBundles()
    addItemIdInfo()
    addBulkPricingInfo()
    #Gets tagListing
    
    fetchItemAvailablity()
    flagNoAvailableItems()
    if len(flaggedItems) > 0:
        print "Flagged items ",flaggedItems
        get_inventory_client().updateItemAvailabilityForItemIds(flaggedItems)
        fetchItemAvailablity()
    addInfoToMemCache()
    mc = get_memcache_connection(host=options.mongoHost)
    print mc.get("item_availability_1019937")