Subversion Repositories SmartDukaan

Rev

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

from bson.objectid import ObjectId
from datetime import datetime, timedelta
from dtr.config import PythonPropertyReader
from dtr.dao import FeaturedDeals, AppTransactions, AppOfferObj
from dtr.storage import DataService
from dtr.storage.DataService import price_preferences, brand_preferences, \
    user_actions, Brands, app_offers, approved_app_transactions, user_app_cashbacks, \
    user_app_installs, appmasters, notification_campaigns
from dtr.storage.MemCache import MemCache
from dtr.utils.MailSender import Email
from dtr.utils.utils import to_java_date, CB_PENDING, CB_APPROVED, CB_INIT, \
    to_py_date, CB_REJECTED, SUB_CATEGORY_MAP
from sqlalchemy.sql.expression import func, func, or_, desc, asc, case
from elixir import *
from operator import itemgetter
from pymongo.command_cursor import CommandCursor
import pymongo
import random
import re
import time
import traceback
from itertools import groupby
import urllib
import urllib2
import json
import collections
try:
    import ordereddict
except:
    pass

con = None
es = None
try:
    from elasticsearch import Elasticsearch
except:
    pass
from shop2020.config.client.ConfigClient import ConfigClient

DataService.initialize(db_hostname="localhost")
mc = MemCache("127.0.0.1")
config_client = ConfigClient()
elastic_search_host = config_client.get_property('elastic_search_host')
elastic_search_port = config_client.get_property('elastic_search_port')



SOURCE_MAP = {1:'AMAZON',2:'FLIPKART',3:'SNAPDEAL',4:'SAHOLIC',5:"SHOPCLUES.COM",6:"PAYTM.COM",7:"HOMESHOP18.COM"}

COLLECTION_MAP = {
                  'ExceptionalNlc':'skuBundleId',
                  'SkuDealerPrices':'skuBundleId',
                  'SkuDiscountInfo':'skuBundleId',
                  'SkuSchemeDetails':'skuBundleId',
                  'DealPoints':'skuBundleId',
                  'FeaturedDeals': 'skuBundleId'
                  }

def get_elastic_search_connection():
    global es
    if es is None:
        print "Establishing connection with elastic search %s host and port %s"%(elastic_search_host,elastic_search_port)
        es = Elasticsearch([{'host': elastic_search_host, 'port': elastic_search_port}])
        return es
    return es
    

def get_mongo_connection(host='localhost', port=27017):
    global con
    if con is None:
        print "Establishing connection %s host and port %d" %(host,port)
        try:
            con = pymongo.MongoClient(host, port)
        except Exception, e:
            print e
            return None
    return con

def populateCashBack():
    print "Populating cashback"
    cashBackMap = {}
    itemCashBackMap = {}
    cashBack = list(get_mongo_connection().Catalog.CategoryCashBack.find())
    for row in cashBack:
        temp_map = {}
        temp_list = []
        if cashBackMap.has_key(row['source_id']):
            arr = cashBackMap.get(row['source_id'])
            for val in arr:
                temp_list.append(val)
            temp_map[row['category_id']] = row
            temp_list.append(temp_map)
            cashBackMap[row['source_id']] = temp_list 
        else:
            temp_map[row['category_id']] = row
            temp_list.append(temp_map)
            cashBackMap[row['source_id']] = temp_list
    itemCashBack = list(get_mongo_connection().Catalog.ItemCashBack.find())
    for row in itemCashBack:
        if not itemCashBackMap.has_key(row['skuId']):
            itemCashBackMap[row['skuId']] = row
    mc.set("item_cash_back", itemCashBackMap, 24 * 60 * 60)
    mc.set("category_cash_back", cashBackMap, 24 * 60 * 60)

def addCategoryDiscount(data):
    collection = get_mongo_connection().Catalog.CategoryDiscount
    query = []
    data['brand'] = data['brand'].strip().upper()
    data['discountType'] = data['discountType'].upper().strip()
    query.append({"brand":data['brand']})
    query.append({"category_id":data['category_id']})
    r = collection.find({"$and":query})
    if r.count() > 0:
        return {0:"Brand & Category info already present."}
    else:
        collection.insert(data)
        get_mongo_connection().Catalog.MasterData.update({'brand':data['brand'],'category_id':data['category_id']},{"$set":{'updatedOn':to_java_date(datetime.now())}},multi=True)
        return {1:"Data added successfully"}

def updateCategoryDiscount(data,_id):
    try:
        collection = get_mongo_connection().Catalog.CategoryDiscount
        collection.update({'_id':ObjectId(_id)},{"$set":{'min_discount':data['min_discount'],'max_discount':data['max_discount'],'discountType':data['discountType'].upper().strip()}},upsert=False, multi = False)
        get_mongo_connection().Catalog.MasterData.update({'brand':data['brand'],'category_id':data['category_id']},{"$set":{'updatedOn':to_java_date(datetime.now())}},multi=True)
        return {1:"Data updated successfully"}
    except:
        return {0:"Data not updated."}
    

def getAllCategoryDiscount():
    data = []
    collection = get_mongo_connection().Catalog.CategoryDiscount
    cursor = collection.find()
    for val in cursor:
        data.append(val)
    return data

def __getBundledSkusfromSku(sku):
    masterData =  get_mongo_connection().Catalog.MasterData.find_one({"_id":sku},{"skuBundleId":1})
    if masterData is not None:
        return list(get_mongo_connection().Catalog.MasterData.find({"skuBundleId":masterData.get('skuBundleId')},{'_id':1,'skuBundleId':1}))
    else:
        return []

def addSchemeDetailsForSku(data):
    collection = get_mongo_connection().Catalog.SkuSchemeDetails
    result = collection.find_one({'skuBundleId':data['skuBundleId']})
    if result is None:
        collection.insert(data)
        get_mongo_connection().Catalog.MasterData.update({'skuBundleId':data['skuBundleId']},{"$set":{'updatedOn':to_java_date(datetime.now())}},multi=True)
        return {1:"Data added successfully"}
    return {1:"BundleId info already present"}
    
def getAllSkuWiseSchemeDetails(offset, limit):
    data = []
    collection = get_mongo_connection().Catalog.SkuSchemeDetails
    cursor = collection.find().skip(offset).limit(limit)
    for val in cursor:
        master = get_mongo_connection().Catalog.MasterData.find_one({'skuBundleId':val['skuBundleId']})
        if master is not None:
            val['brand'] = master['brand']
            val['source_product_name'] = master['source_product_name']
        else:
            val['brand'] = ""
            val['source_product_name'] = ""
        data.append(val)
    return data

def addSkuDiscountInfo(data):
    collection = get_mongo_connection().Catalog.SkuDiscountInfo
    cursor = collection.find_one({"skuBundleId":data['skuBundleId']})
    if cursor is not None:
        return {0:"BundleId information already present."}
    else:
        collection.insert(data)
        get_mongo_connection().Catalog.MasterData.update({'skuBundleId':data['skuBundleId']},{"$set":{'updatedOn':to_java_date(datetime.now())}},multi=True)
        return {1:"Data added successfully"}

def getallSkuDiscountInfo(offset, limit):
    data = []
    collection = get_mongo_connection().Catalog.SkuDiscountInfo
    cursor = collection.find().skip(offset).limit(limit)
    for val in cursor:
        master = get_mongo_connection().Catalog.MasterData.find_one({'skuBundleId':val['skuBundleId']})
        if master is not None:
            val['brand'] = master['brand']
            val['source_product_name'] = master['source_product_name']
        else:
            val['brand'] = ""
            val['source_product_name'] = ""
        data.append(val)
    return data

def updateSkuDiscount(data,_id):
    try:
        collection = get_mongo_connection().Catalog.SkuDiscountInfo
        collection.update({'_id':ObjectId(_id)},{"$set":{'min_discount':data['min_discount'],'max_discount':data['max_discount'],'discountType':data['discountType'].upper().strip()}},upsert=False, multi = False)
        get_mongo_connection().Catalog.MasterData.update({'_id':data['skuBundleId']},{"$set":{'updatedOn':to_java_date(datetime.now())}},multi=True)
        return {1:"Data updated successfully"}
    except:
        return {0:"Data not updated."}


def addExceptionalNlc(data):
    collection = get_mongo_connection().Catalog.ExceptionalNlc
    cursor = collection.find_one({"skuBundleId":data['skuBundleId']})
    if cursor is not None:
        return {0:"BundleId information already present."}
    else:
        collection.insert(data)
        get_mongo_connection().Catalog.MasterData.update({'skuBundleId':data['skuBundleId']},{"$set":{'updatedOn':to_java_date(datetime.now())}},multi=True)
        return {1:"Data added successfully"}

def getAllExceptionlNlcItems(offset, limit):
    data = []
    collection = get_mongo_connection().Catalog.ExceptionalNlc
    cursor = collection.find().skip(offset).limit(limit)
    for val in cursor:
        master = get_mongo_connection().Catalog.MasterData.find_one({'skuBundleId':val['skuBundleId']})
        if master is not None:
            val['brand'] = master['brand']
            val['source_product_name'] = master['source_product_name']
        else:
            val['brand'] = ""
            val['source_product_name'] = ""
        data.append(val)
    return data

def getMerchantOrdersByUser(userId, page=1, window=50, searchMap={}):
    if searchMap is None:
        searchMap = {}
    if page==None:
        page = 1
        
    if window==None:
        window = 50
    result = {}
    skip = (page-1)*window
    
    if userId is not None:
        searchMap['userId'] = userId
    collection = get_mongo_connection().Dtr.merchantOrder
    cursor = collection.find(searchMap).sort("orderId",-1)
    total_count = cursor.count()
    pages = total_count/window + (0 if total_count%window==0 else 1)  
    print "total_count", total_count
    if total_count > skip:
        cursor = cursor.skip(skip).limit(window)
        orders = []
        for order in cursor:
            del(order["_id"])
            orders.append(order)
        result['data'] = orders
        result['window'] = window
        result['totalCount'] = total_count 
        result['currCount'] = cursor.count()
        result['totalPages'] = pages
        result['currPage'] = page    
        return result
    else:
        return result

def getRefunds(userId, page=1, window=10):
    if page==None:
        page = 1
        
    if window==None:
        window = 10
    result = {}
    skip = (page-1)*window
    con = get_mongo_connection()
    collection = con.Dtr.refund
    user = con.Dtr.user
    credited = user.find_one({"userId":userId})
    if credited:
        credited = credited.get("credited")
    else:
        credited=0
        
    cursor = collection.find({"userId":userId})
    total_count = cursor.count()
    pages = total_count/window + (0 if total_count%window==0 else 1)  
    print "total_count", total_count
    if total_count > skip:
        cursor = cursor.skip(skip).limit(window).sort([('batch',-1)])
        refunds = []
        for refund in cursor:
            del(refund["_id"])
            refunds.append(refund)
        result['credited'] = credited
        result['data'] = refunds
        result['window'] = window
        result['totalCount'] = total_count 
        result['currCount'] = cursor.count()
        result['totalPages'] = pages
        result['currPage'] = page    
        return result
    else:
        return result
    
def getPendingRefunds(userId):
    print type(userId)
    result = get_mongo_connection().Dtr.merchantOrder\
        .aggregate([
                    {'$match':{'subOrders.cashBackStatus':CB_APPROVED, 'userId':userId}},
                    {'$unwind':"$subOrders"},
                    {'$match':{'subOrders.cashBackStatus':CB_APPROVED}},
                    { 
                     '$group':{
                               '_id':None,
                               'amount': { '$sum':'$subOrders.cashBackAmount'},
                               }
                     }
                ])['result']

    if len(result)>0:
        result = result[0]        
        result.pop("_id")
    else:
        result={}
        result['amount'] = 0.0
    result['nextCredit'] = datetime.strftime(next_weekday(datetime.now(), int(PythonPropertyReader.getConfig('CREDIT_DAY_OF_WEEK'))),"%Y-%m-%d %H:%M:%S")
    return result

def getPendingCashbacks(userId):
    result = get_mongo_connection().Dtr.merchantOrder\
        .aggregate([
                    {'$match':{'subOrders.cashBackStatus':CB_PENDING, 'userId':userId}},
                    {'$unwind':"$subOrders"},
                    {'$match':{'subOrders.cashBackStatus':CB_PENDING}},
                    { 
                     '$group':{
                               '_id':None,
                               'amount': { '$sum':'$subOrders.cashBackAmount'},
                               }
                     }
                ])['result']

    if len(result)>0:
        result = result[0]        
        result.pop("_id")
    else:
        result={}
        result['amount'] = 0.0
    return result

def __constructDummyDealObject(skuBundleId):
    temp =[]
    deals = get_mongo_connection().Catalog.Deals.find({"skuBundleId":skuBundleId,"$or":[{"showDeal":1}, {"prepaidDeal":1}]},{'_id':1,'category_id':1,'brand':1,'totalPoints':1,'bestSellerPoints':1,'nlcPoints':1,'rank':1,'available_price':1,'dealType':1,'source_id':1,'brand_id':1,'skuBundleId':1,'dp':1, 'showDp':1, 'gross_price':1,'subCategoryId':1})
    for d in deals:
        d['persPoints'] = 0
        temp.append(d)
    return temp
    
    

def __populateCache(userId):
    try:
        if mc.get("featured_deals") is None:
            __populateFeaturedDeals()
        featuredDeals = mc.get("featured_deals")
            
    except Exception as e:
        print traceback.print_exc()
        featuredDeals = {3:{},5:{},6:{}}
    
    fd_bundles = []
    
    for catMap in featuredDeals.itervalues():
        for fd_map in catMap.itervalues():
            if not fd_map.get('skuBundleId') in fd_bundles:
                fd_bundles.append(fd_map.get('skuBundleId'))
    
    print "Populating memcache for userId",userId
    outer_query = []
    outer_query.append({ "$or": [ { "showDeal": 1} , { "prepaidDeal": 1 } ] })
    query = {}
    query['$gt'] = -100
    outer_query.append({'totalPoints':query})
    brandPrefMap = {}
    pricePrefMap = {}
    actionsMap = {}
    brand_p = session.query(price_preferences).filter_by(user_id=userId).all()
    for x in brand_p:
        pricePrefMap[x.category_id] = [x.min_price,x.max_price]
    for x in session.query(brand_preferences).filter_by(user_id=userId).all():
        temp_map = {}
        if brandPrefMap.has_key((x.brand).strip().upper()):
            val = brandPrefMap.get((x.brand).strip().upper())
            temp_map[x.category_id] = 1 if x.status == 'show' else 0
            val.append(temp_map)
        else:
            temp = []
            temp_map[x.category_id] = 1 if x.status == 'show' else 0
            temp.append(temp_map)
            brandPrefMap[(x.brand).strip().upper()] = temp
        
    for x in session.query(user_actions).filter_by(user_id=userId).all():
        actionsMap[x.store_product_id] = 1 if x.action == 'like' else 0
    all_deals = list(get_mongo_connection().Catalog.Deals.find({"$and":outer_query},{'_id':1,'category_id':1,'brand':1,'totalPoints':1,'bestSellerPoints':1,'nlcPoints':1,'rank':1,'available_price':1,'dealType':1,'source_id':1,'brand_id':1,'skuBundleId':1,'dp':1, 'showDp':1, 'gross_price':1, 'subCategoryId':1}).sort([('totalPoints',pymongo.DESCENDING),('bestSellerPoints',pymongo.DESCENDING),('nlcPoints',pymongo.DESCENDING),('rank',pymongo.DESCENDING)]))
    mobile_deals = []
    tablet_deals = []
    accessories_deals = []
    for deal in all_deals:
        
        
        try:
            fd_bundles.remove(deal.get('skuBundleId'))
        except:
            pass
        
        if actionsMap.get(deal['_id']) == 0:
            fav_weight =.25
        elif actionsMap.get(deal['_id']) == 1:
            fav_weight = 1.5
        else:
            fav_weight = 1
        
        if brandPrefMap.get(deal['brand'].strip().upper()) is not None:

            brand_weight = 1
            for brandInfo in brandPrefMap.get(deal['brand'].strip().upper()):
                if brandInfo.get(deal['category_id']) is not None:
                    if brandInfo.get(deal['category_id']) == 1:
                        brand_weight = 2.0
        else:
            brand_weight = 1
        
        if pricePrefMap.get(deal['category_id']) is not None:
        
            if deal['available_price'] >= pricePrefMap.get(deal['category_id'])[0] and deal['available_price'] <= pricePrefMap.get(deal['category_id'])[1]:
                asp_weight = 1.5
            elif  deal['available_price'] >= pricePrefMap.get(deal['category_id'])[0] - 0.5 * pricePrefMap.get(deal['category_id'])[0] and deal['available_price'] <= pricePrefMap.get(deal['category_id'])[1] + 0.5 * pricePrefMap.get(deal['category_id'])[1]:
                asp_weight = 1.2
            else:
                asp_weight = 1
        else:
            asp_weight = 1
        
        persPoints = deal['totalPoints'] * fav_weight * brand_weight * asp_weight
        deal['persPoints'] = persPoints
        
        if deal['category_id'] ==3:
            mobile_deals.append(deal)
        elif deal['category_id'] ==5:
            tablet_deals.append(deal)
        elif deal['category_id'] ==6:
            accessories_deals.append(deal)
        else:
            continue
    
    session.close()
    
    mobile_deals = sorted(mobile_deals, key = lambda x: (x['persPoints'],x['totalPoints'],x['bestSellerPoints'], x['nlcPoints'], x['rank']),reverse=True)
    tablet_deals = sorted(tablet_deals, key = lambda x: (x['persPoints'],x['totalPoints'],x['bestSellerPoints'], x['nlcPoints'], x['rank']),reverse=True)
    accessories_deals = sorted(accessories_deals, key = lambda x: (x['persPoints'],x['totalPoints'],x['bestSellerPoints'], x['nlcPoints'], x['rank']),reverse=True)
    
    
    if len(fd_bundles) > 0:
        print "There is still bundle in feature deals with points less than -100.Lets add info"
        for skuBundleId in fd_bundles:
            dummyDealObjList = __constructDummyDealObject(skuBundleId)
            for dummyDealObj in dummyDealObjList:
                if dummyDealObj['category_id'] ==3:
                    mobile_deals.append(dummyDealObj)
                elif dummyDealObj['category_id'] ==5:
                    tablet_deals.append(dummyDealObj)
                elif dummyDealObj['category_id'] ==6:
                    accessories_deals.append(dummyDealObj)
                else:
                    pass
    
    for super_category, categoryFeaturedDeals in featuredDeals.iteritems():
        for val in categoryFeaturedDeals.itervalues():
            dummyDealObjList = __constructDummyDealObject(val.get('skuBundleId'))
            for dummyDealObj in dummyDealObjList:
                if super_category == dummyDealObj['category_id']:
                    continue  
                
                if super_category ==3:
                    mobile_deals.append(dummyDealObj)
                elif super_category ==5:
                    tablet_deals.append(dummyDealObj)
                elif super_category ==6:
                    accessories_deals.append(dummyDealObj)
                else:
                    pass

    sortedMapMobiles = {}
    rankMapMobiles = {}
    rankMobiles = 0
    
    blockedRanksMobiles = []
    blockedSkuBundlesMobiles = []
    blockedInfoMobiles = {}
    
    featuredDealsMobiles = featuredDeals.get(3)
    
    for k, v in featuredDealsMobiles.iteritems():
        blockedRanksMobiles.append(k-1)
        blockedSkuBundlesMobiles.append(v.get('skuBundleId'))
        
    
    for sorted_deal in mobile_deals:
       
        while(True):
            if rankMobiles in blockedRanksMobiles:
                rankMobiles = rankMobiles +1
            else:
                break
             
        if sorted_deal['skuBundleId'] in blockedSkuBundlesMobiles:
            if blockedInfoMobiles.has_key(sorted_deal['skuBundleId']):
                blockedInfoMobiles.get(sorted_deal['skuBundleId']).append(sorted_deal)
            else:
                blockedInfoMobiles[sorted_deal['skuBundleId']] = [sorted_deal]
            continue
         
        if sortedMapMobiles.get(sorted_deal['skuBundleId']) is None:
            sortedMapMobiles[sorted_deal['skuBundleId']] = {rankMobiles:[sorted_deal]}
            rankMapMobiles[rankMobiles] = (sortedMapMobiles[sorted_deal['skuBundleId']].values())[0]
            rankMobiles = rankMobiles +1
        else:
            for temp_list in sortedMapMobiles.get(sorted_deal['skuBundleId']).itervalues():
                temp_list.append(sorted_deal)
            rankMapMobiles[(sortedMapMobiles.get(sorted_deal['skuBundleId']).keys())[0]] = temp_list
    
            
    for rank in blockedRanksMobiles:
        if blockedInfoMobiles.get((featuredDealsMobiles.get(rank+1)).get('skuBundleId')) is not None:
            rankMapMobiles[rank] = blockedInfoMobiles.get((featuredDealsMobiles.get(rank+1)).get('skuBundleId'))
        
    
    sortedMapTablets = {}
    rankMapTablets = {}
    rankTablets = 0
    
    blockedRanksTablets = []
    blockedSkuBundlesTablets = []
    blockedInfoTablets = {}
    
    featuredDealsTablets = featuredDeals.get(5)
    
    
    for k, v in featuredDealsTablets.iteritems():
        blockedRanksTablets.append(k-1)
        blockedSkuBundlesTablets.append(v.get('skuBundleId'))
    
    
    for sorted_deal in tablet_deals:
        while(True):
            if rankTablets in blockedRanksTablets:
                rankTablets = rankTablets +1
            else:
                break
             
        if sorted_deal['skuBundleId'] in blockedSkuBundlesTablets:
            if blockedInfoTablets.has_key(sorted_deal['skuBundleId']):
                blockedInfoTablets.get(sorted_deal['skuBundleId']).append(sorted_deal)
            else:
                blockedInfoTablets[sorted_deal['skuBundleId']] = [sorted_deal]
            continue
         
        if sortedMapTablets.get(sorted_deal['skuBundleId']) is None:
            sortedMapTablets[sorted_deal['skuBundleId']] = {rankTablets:[sorted_deal]}
            rankMapTablets[rankTablets] = (sortedMapTablets[sorted_deal['skuBundleId']].values())[0]
            rankTablets = rankTablets +1
        else:
            for temp_list in sortedMapTablets.get(sorted_deal['skuBundleId']).itervalues():
                temp_list.append(sorted_deal)
            rankMapTablets[(sortedMapTablets.get(sorted_deal['skuBundleId']).keys())[0]] = temp_list
            
    for rank in blockedRanksTablets:
        if blockedInfoTablets.get((featuredDealsTablets.get(rank+1)).get('skuBundleId')) is not None:
            rankMapTablets[rank] = blockedInfoTablets.get((featuredDealsTablets.get(rank+1)).get('skuBundleId'))
            
    
    sortedMapAccessories = {}
    rankMapAccessories = {}
    rankAccessories = 0
    
    blockedRanksAccessories = []
    blockedSkuBundlesAccessories = []
    blockedInfoAccessories = {}
    
    featuredDealsAccessories = featuredDeals.get(6)
    
    for k, v in featuredDealsAccessories.iteritems():
        blockedRanksAccessories.append(k-1)
        blockedSkuBundlesAccessories.append(v.get('skuBundleId'))
    
    
    for sorted_deal in accessories_deals:
       
        while(True):
            if rankAccessories in blockedRanksAccessories:
                rankAccessories = rankAccessories +1
            else:
                break
             
        if sorted_deal['skuBundleId'] in blockedSkuBundlesAccessories:
            if blockedInfoAccessories.has_key(sorted_deal['skuBundleId']):
                blockedInfoAccessories.get(sorted_deal['skuBundleId']).append(sorted_deal)
            else:
                blockedInfoAccessories[sorted_deal['skuBundleId']] = [sorted_deal]
            continue
         
        if sortedMapAccessories.get(sorted_deal['skuBundleId']) is None:
            sortedMapAccessories[sorted_deal['skuBundleId']] = {rankAccessories:[sorted_deal]}
            rankMapAccessories[rankAccessories] = (sortedMapAccessories[sorted_deal['skuBundleId']].values())[0]
            rankAccessories = rankAccessories +1
        else:
            for temp_list in sortedMapAccessories.get(sorted_deal['skuBundleId']).itervalues():
                temp_list.append(sorted_deal)
            rankMapAccessories[(sortedMapAccessories.get(sorted_deal['skuBundleId']).keys())[0]] = temp_list
    
            
    for rank in blockedRanksAccessories:
        if blockedInfoAccessories.get((featuredDealsAccessories.get(rank+1)).get('skuBundleId')) is not None:
            rankMapAccessories[rank] = blockedInfoAccessories.get((featuredDealsAccessories.get(rank+1)).get('skuBundleId'))
    
    
    mem_cache_val = {3:mobile_deals, 5:tablet_deals, 6: accessories_deals,"3_rankMap": rankMapMobiles,"5_rankMap": rankMapTablets,"6_rankMap": rankMapAccessories }
    mc.set(str(userId), mem_cache_val)
    

def __populateFeaturedDeals():
    print "Populating featured deals....."
    featuredDealsMobiles = {}
    featuredDealsTablets = {}
    featuredDealsAccessories = {}
    activeFeaturedDeals = get_mongo_connection().Catalog.FeaturedDeals.find({'startDate':{'$lte':to_java_date(datetime.now())},'endDate':{'$gte':to_java_date(datetime.now())}})
    for activeFeaturedDeal in activeFeaturedDeals:
        deals = get_mongo_connection().Catalog.Deals.find({"skuBundleId":activeFeaturedDeal.get('skuBundleId'),"$or":[{"showDeal":1}, {"prepaidDeal":1}]})
        for deal in deals:
            if deal.get('available_price') <= activeFeaturedDeal.get('thresholdPrice'):
                for category_id, rank  in activeFeaturedDeal['otherInfo'].iteritems():
                    f_deal = {'skuBundleId':activeFeaturedDeal.get('skuBundleId'), 'thresholdPrice':activeFeaturedDeal.get('thresholdPrice'), 'rank':rank,'category_id':int(category_id),'totalPoints':activeFeaturedDeal.get('totalPoints')}
                    if f_deal['category_id'] == 3:
                        featuredDealsMobiles[rank] = f_deal
                    elif f_deal['category_id']==5:
                        featuredDealsTablets[rank] = f_deal
                    elif f_deal['category_id']==6:
                        featuredDealsAccessories[rank] = f_deal
                break
                
#                f_deal = {'skuBundleId':activeFeaturedDeal.get('skuBundleId'), 'thresholdPrice':activeFeaturedDeal.get('thresholdPrice'), 'rank':activeFeaturedDeal.get('rank'),'category_id':activeFeaturedDeal.get('category_id'),'totalPoints':activeFeaturedDeal.get('totalPoints')}
#                 if activeFeaturedDeal.get('category_id') == 3:
#                     featuredDealsMobiles[activeFeaturedDeal.get('rank')] = f_deal
#                 else:
#                     featuredDealsTablets[activeFeaturedDeal.get('rank')] = f_deal
#                 break
                
        
    mc.set("featured_deals", {3:featuredDealsMobiles,5:featuredDealsTablets,6:featuredDealsAccessories}, 600)

def __populateFeaturedDealsForDealObject():
    print "Caching deal objects...."
    featuredDealObjectMobiles = {}
    featuredDealObjectTablets = {}
    featuredDealObjectAccessories = {}
    dealObjects = get_mongo_connection().Catalog.FeaturedDealsDealObject.find({'startDate':{'$lte':to_java_date(datetime.now())},'endDate':{'$gte':to_java_date(datetime.now())}})
    for dealObject in dealObjects:
        d_object = list(get_mongo_connection().Catalog.DealObject.find({'_id':dealObject['_id']}))
        if len(d_object) == 0:
            continue
        for category_id, rank  in dealObject['otherInfo'].iteritems():
            d_object[0]['dealObject'] = 1
            f_deal = {'rank':rank,'category_id':int(category_id),'object':d_object[0]}
            if f_deal['category_id'] == 3:
                featuredDealObjectMobiles[rank] = f_deal
            elif f_deal['category_id']==5:
                featuredDealObjectTablets[rank] = f_deal
            elif f_deal['category_id']==6:
                featuredDealObjectAccessories[rank] = f_deal
    mc.set("featured_deals_deal_object", {3:featuredDealObjectMobiles,5:featuredDealObjectTablets,6:featuredDealObjectAccessories}, 600)
    print mc.get('featured_deals_deal_object')

def getNewDeals(userId, category_id, offset, limit, sort, direction, filterData=None):
    if mc.get("category_cash_back") is None or not bool(mc.get("category_cash_back")):
        populateCashBack()
    
    dealsListMap = []
    user_specific_deals = mc.get(str(userId))
    if user_specific_deals is None:
        __populateCache(userId)
        user_specific_deals = mc.get(str(userId))
    else:
        print "Getting user deals from cache"
    category_specific_deals = user_specific_deals.get(category_id)
    
    insert_featured_deals = False
    if sort is None or direction is None:
        insert_featured_deals = True
        rankMap = user_specific_deals.get(str(category_id)+"_rankMap")
    else:
        if sort == "bestSellerPoints":
            sorted_deals = sorted(category_specific_deals, key = lambda x: (x['bestSellerPoints'], x['rank'], x['nlcPoints']),reverse=True)
        else:
            if direction == -1:
                rev = True
            else:
                rev = False
            sorted_deals = sorted(category_specific_deals, key = lambda x: (x['available_price']),reverse=rev)
    
    
    filtered_deals = []
    dataExist = True
    if filterData is not None:
        try:
            filtered_deals = filterDeals(category_specific_deals, filterData)
            if len(filtered_deals)==0:
                dataExist = False
        except:
            traceback.print_exc()
    if dataExist:
    
        if not insert_featured_deals:
            sortedMap = {}
            rankMap = {}
            rank = 0
            for sorted_deal in sorted_deals:
                
                if len(filtered_deals) > 0 and  sorted_deal['skuBundleId'] not in filtered_deals:
                    continue
                
                if sortedMap.get(sorted_deal['skuBundleId']) is None:
                    sortedMap[sorted_deal['skuBundleId']] = {rank:[sorted_deal]}
                    rankMap[rank] = (sortedMap[sorted_deal['skuBundleId']].values())[0]
                    rank = rank +1
                else:
                    for temp_list in sortedMap.get(sorted_deal['skuBundleId']).itervalues():
                        temp_list.append(sorted_deal)
                    rankMap[(sortedMap.get(sorted_deal['skuBundleId']).keys())[0]] = temp_list
        else:
            filterMap = {}
            rank = 0
            if len(filtered_deals) > 0:
                try:
                    od = collections.OrderedDict(sorted(rankMap.items()))
                except:
                    od = ordereddict.OrderedDict(sorted(rankMap.items()))
                for k, v in od.iteritems():
                    if v[0].get('skuBundleId') in filtered_deals:
                        filterMap[rank] = v
                        rank =rank+1
                rankMap = filterMap
        
        rankCounter = offset
        if filterData is None:
            if mc.get("featured_deals_deal_object") is None or not bool(mc.get("featured_deals_deal_object")):
                try:
                    __populateFeaturedDealsForDealObject()
                    fd_dealObject = mc.get("featured_deals_deal_object")
                except:
                    fd_dealObject = {3:{},5:{},6:{}}
            else:
                fd_dealObject = mc.get("featured_deals_deal_object")
        
    else:
        rankMap = {}
    
    for dealList in [rankMap.get(k, []) for k in range(offset, offset+limit)]:
        if filterData is None:
            while(True):
                
                rankCounter = rankCounter+1
                if (fd_dealObject.get(category_id).get(rankCounter)) is not None:
                    deal_object_temp = []
                    deal_object_temp.append(fd_dealObject.get(category_id).get(rankCounter).get('object'))
                    dealsListMap.append(deal_object_temp)
                else:
                    break
            
        temp = []
        if dealList is None or len(dealList)==0:
            continue
        for d in dealList:
            item = list(get_mongo_connection().Catalog.MasterData.find({'_id':d['_id']}))
            if len(item) ==0:
                continue
            item[0]['persPoints'] = d['persPoints']
            if d['dealType'] == 1 and d['source_id'] ==1:
                try:
                    manualDeal = list(get_mongo_connection().Catalog.ManualDeals.find({'sku':d['_id'],'startDate':{'$lte':to_java_date(datetime.now())},'endDate':{'$gte':to_java_date(datetime.now())}}))
                    item[0]['marketPlaceUrl'] = manualDeal[0]['dealUrl'].strip()
                except:
                    pass
            elif d['source_id'] ==3:
                item[0]['marketPlaceUrl'] = item[0]['marketPlaceUrl']+'?supc='+item[0].get('identifier')
            else:
                pass 
            try:
                cashBack = getCashBack(item[0]['_id'], item[0]['source_id'], item[0]['category_id'])
                if not cashBack or cashBack.get('cash_back_status')!=1:
                    item[0]['cash_back_type'] = 0
                    item[0]['cash_back'] = 0
                else:
                    if cashBack.get('maxCashBack') is not None:
                        
                        if cashBack.get('cash_back_type') ==1 and (float(cashBack.get('cash_back'))*item[0]['available_price'])/100 > cashBack.get('maxCashBack'):
                            cashBack['cash_back_type'] = 2
                            cashBack['cash_back'] = cashBack['maxCashBack']
                        elif cashBack.get('cash_back_type') ==2 and cashBack.get('cash_back') > cashBack.get('maxCashBack'):
                            cashBack['cash_back'] = cashBack['maxCashBack']
                    
                    item[0]['cash_back_type'] = int(cashBack['cash_back_type'])
                    item[0]['cash_back'] = cashBack['cash_back']
            except:
                print "Error in adding cashback to deals"
                item[0]['cash_back_type'] = 0
                item[0]['cash_back'] = 0
            try:
                item[0]['dp'] = d['dp']
                item[0]['showDp'] = d['showDp']
            except:
                item[0]['dp'] = 0.0
                item[0]['showDp'] = 0
            try:
                item[0]['thumbnail'] = item[0]['thumbnail'].strip()
            except:
                pass
            
            try:
                if item[0]['showVideo']==0:
                    item[0]['videoLink'] =""
            except:
                item[0]['videoLink'] =""
            try:
                if item[0]['quantity'] >1:
                    ppq = float(item[0]['available_price'])/item[0]['quantity']
                     
                    if ppq == round(ppq):
                        item[0]['ppq'] = int(ppq)
                    else:
                        item[0]['ppq'] = round(ppq,2)
                else:
                    item[0]['ppq'] = 0
            except:
                item[0]['ppq'] = 0
            if filterData is None:
                if item[0]['category_id']!=6:
                    try:
                        item[0]['filterLink'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['brand'])+'&filter=brand&brands='+str(int(item[0]['brand_id']))
                        item[0]['filterText'] = 'More %s items'%(item[0]['brand'])
                    except:
                        item[0]['filterLink'] = ""
                        item[0]['filterText'] = ""
                else:
                    try:
                        if item[0]['subCategory']=='' or item[0]['subCategory'] is None or item[0]['subCategoryId']==0:
                            raise
                        item[0]['filterLink'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['subCategory'])+'&filter=subcategory&subcategories='+str(int(item[0]['subCategoryId']))
                        item[0]['filterText'] = 'More %s'%(item[0]['subCategory'])
                    except:
                        item[0]['filterLink'] = ''
                        item[0]['filterText'] = ""
            try:
                if item[0]['source_id']==4:
                    item_availability_info = mc.get("item_availability_"+str(item[0]['identifier']).strip())
                    if item_availability_info is None or len(item_availability_info)==0:
                        item[0]['availabilityInfo'] = [{}]
                    else:
                        item[0]['availabilityInfo'] = item_availability_info
            except:
                item[0]['availabilityInfo'] = [{}]
            temp.append(item[0])
        if len(temp) > 1:
            temp = sorted(temp, key = lambda x: (x['available_price']),reverse=False)
        dealsListMap.append(temp)
    return dealsListMap

def filterDeals(deals, filterData):
    print "Filter data ", filterData
    brandsFiltered = []
    subCategoryFiltered = []
    filterArray = filterData.split('|')
    for data in filterArray:
        try:
            filter, info = data.split(':')
        except Exception as ex:
            traceback.print_exc()
            continue
        if filter == 'brandFilter':
            toFilter = info.split('^')
            print "brand filter ",toFilter
            for deal in deals:
                if str(int(deal['brand_id'])) in toFilter:
                    brandsFiltered.append(deal)
        elif filter =='subCategoryFilter':
            toFilter = info.split('^')
            print "Sub Category filter ",toFilter
            for deal in deals:
                if str(int(deal['subCategoryId'])) in toFilter:
                    subCategoryFiltered.append(deal)
    print "No of brand filtered ",len(brandsFiltered)
    print "No of sub-cat filtered ",len(subCategoryFiltered)
    if len(subCategoryFiltered) == 0:
        return [trend['skuBundleId'] for trend in brandsFiltered]
    elif len(brandsFiltered) == 0:
        return [trend['skuBundleId'] for trend in subCategoryFiltered]
    return [i['skuBundleId'] for i in subCategoryFiltered for j in brandsFiltered if i['_id']==j['_id']]
    

def getDeals(userId, category_id, offset, limit, sort, direction):
    if mc.get("category_cash_back") is None or not bool(mc.get("category_cash_back")):
        populateCashBack()
    rank = 1
    deals = {}
    outer_query = []
    outer_query.append({"showDeal":1})
    query = {}
    query['$gt'] = 0
    outer_query.append({'totalPoints':query})
    if category_id in (3,5):
        outer_query.append({'category_id':category_id})
    if sort is None or direction is None:
        direct = -1
        print outer_query
        data = list(get_mongo_connection().Catalog.Deals.find({"$and":outer_query}).sort([('totalPoints',direct),('bestSellerPoints',direct),('nlcPoints',direct),('rank',direct)]).skip(offset).limit(limit))
    else:
        print outer_query
        direct = direction
        if sort == "bestSellerPoints":
            print "yes,sorting by bestSellerPoints"
            data = list(get_mongo_connection().Catalog.Deals.find({"$and":outer_query}).sort([('bestSellerPoints',direct),('rank',direct),('nlcPoints',direct)]).skip(offset).limit(limit))
        else:
            data = list(get_mongo_connection().Catalog.Deals.find({"$and":outer_query}).sort([(sort,direct)]).skip(offset).limit(limit))
    for d in data:
        item = list(get_mongo_connection().Catalog.MasterData.find({'_id':d['_id']}))
        if not deals.has_key(item[0]['identifier']):
            item[0]['dealRank'] = rank
            try:
                cashBack = getCashBack(item[0]['_id'], item[0]['source_id'], item[0]['category_id'])
                if not cashBack or cashBack.get('cash_back_status')!=1:
                    item[0]['cash_back_type'] = 0
                    item[0]['cash_back'] = 0
                else:
                    item[0]['cash_back_type'] = int(cashBack['cash_back_type'])
                    item[0]['cash_back'] = cashBack['cash_back']
            except:
                print "Error in adding cashback to deals"
                item[0]['cash_back_type'] = 0
                item[0]['cash_back'] = 0
            deals[item[0]['identifier']] = item[0]
            
            rank +=1
    return sorted(deals.values(), key=itemgetter('dealRank'))

def getItem(skuId,showDp=None):
    temp = []
    if mc.get("category_cash_back") is None or not bool(mc.get("category_cash_back")):
        populateCashBack()
    try:
        skuData = get_mongo_connection().Catalog.MasterData.find_one({'_id':int(skuId)})
        if skuData is None:
            raise
        try:
            cashBack = getCashBack(skuData['_id'], skuData['source_id'], skuData['category_id'])
            if not cashBack or cashBack.get('cash_back_status')!=1:
                skuData['cash_back_type'] = 0
                skuData['cash_back'] = 0
            else:
                skuData['cash_back_type'] = cashBack['cash_back_type']
                skuData['cash_back'] = cashBack['cash_back']
        except:
            print "Error in adding cashback to deals"
            skuData['cash_back_type'] = 0
            skuData['cash_back'] = 0
        skuData['in_stock'] = int(skuData['in_stock'])
        skuData['is_shortage'] = int(skuData['is_shortage'])
        skuData['category_id'] = int(skuData['category_id'])
        skuData['subCategoryId'] = int(skuData['subCategoryId'])
        skuData['status'] = int(skuData['status'])
        try:
            skuData['thumbnail'] = skuData['thumbnail'].strip()
        except:
            pass 
        if showDp is not None:
            dealerPrice = get_mongo_connection().Catalog.SkuDealerPrices.find_one({'skuBundleId':skuData['skuBundleId']})
            skuData['dp'] = 0.0
            skuData['showDp'] = 0
            if dealerPrice is not None:
                skuData['dp'] = dealerPrice['dp']
                skuData['showDp'] = dealerPrice['showDp']
        temp.append(skuData)
        return temp
    except:
        return []

def getCashBack(skuId, source_id, category_id):
    if mc.get("category_cash_back") is None or not bool(mc.get("category_cash_back")):
        populateCashBack()
    itemCashBackMap = mc.get("item_cash_back")
    itemCashBack = itemCashBackMap.get(skuId)
    if itemCashBack is not None:
        return itemCashBack
    cashBackMap = mc.get("category_cash_back")
    sourceCashBack = cashBackMap.get(source_id)
    if sourceCashBack is not None and len(sourceCashBack) > 0:
        for cashBack in sourceCashBack:
            if cashBack.get(category_id) is None:
                continue
            else:
                return cashBack.get(category_id)
    else:
        return {}
    
def getBundleBySourceSku(source_id, identifier):
    if source_id in (1,2,4,5,6,7):
        skuData = list(get_mongo_connection().Catalog.MasterData.find({'identifier':identifier.strip(), 'source_id':source_id}))
    elif source_id == 3:
        skuData = list(get_mongo_connection().Catalog.MasterData.find({'secondaryIdentifier':identifier.strip(), 'source_id':source_id}))
    else:
        return {}
    
    if not skuData:
        return {}
    else:
        bundleId = skuData[0]["skuBundleId"]
        itemIds = list(get_mongo_connection().Catalog.MasterData.find({'skuBundleId':bundleId, 'in_stock':1, 'source_id':{"$in":[1,2,3,5,6,7]}}, 
                       {"source_id":1, "available_price":1, "marketPlaceUrl":1, "gross_price":1, "codAvailable":1, "source_product_name":1, "offer":1, "coupon":1}))
        return {'products':itemIds}
        
    

def getDealRank(identifier, source_id, userId):
    if source_id in (1,2,4,5,6,7):
        skuData = list(get_mongo_connection().Catalog.MasterData.find({'identifier':identifier.strip(), 'source_id':source_id}))
    elif source_id == 3:
        skuData = list(get_mongo_connection().Catalog.MasterData.find({'secondaryIdentifier':identifier.strip(), 'source_id':source_id}))
    else:
        return {'rank':0, 'description':'Source not valid','maxNlc':None, 'minNlc':None,'status':None,'dp':None}
    if len(skuData) == 0:
        return {'rank':0, 'description':'No matching product identifier found','maxNlc':None, 'minNlc':None,'status':None,'dp':None}
    user_specific_deals = mc.get(str(userId))
    if user_specific_deals is None:
        __populateCache(userId)
        user_specific_deals = mc.get(str(userId))
    else:
        print "Getting user deals from cache"
    category_id = skuData[0]['category_id']
    category_specific_deals = user_specific_deals.get(category_id)
    
    dealsData = get_mongo_connection().Catalog.Deals.find_one({'skuBundleId':skuData[0]['skuBundleId']})
    if dealsData is None:
        dealsData = {}
    
    if category_specific_deals is None or len(category_specific_deals) ==0:
        return {'rank':0,'description':'Category specific deals is empty','maxNlc':dealsData.get('maxNlc'),'minNlc':dealsData.get('minNlc'),'status':dealsData.get('status'),'dp':dealsData.get('dp')}
    sorted_deals = sorted(category_specific_deals, key = lambda x: (x['persPoints'],x['totalPoints'],x['bestSellerPoints'], x['nlcPoints'], x['rank']),reverse=True)
    sortedMap = {}
    rankMap = {}
    rank = 0
    for sorted_deal in sorted_deals:
        if sortedMap.get(sorted_deal['skuBundleId']) is None:
            sortedMap[sorted_deal['skuBundleId']] = {rank:[sorted_deal]}
            rankMap[rank] = (sortedMap[sorted_deal['skuBundleId']].values())[0]
            rank = rank +1
        else:
            for temp_list in sortedMap.get(sorted_deal['skuBundleId']).itervalues():
                temp_list.append(sorted_deal)
            rankMap[(sortedMap.get(sorted_deal['skuBundleId']).keys())[0]] = temp_list
                
    for dealRank ,dealList in rankMap.iteritems():
        for d in dealList:
            if d['skuBundleId'] == skuData[0]['skuBundleId']:
                return {'rank':dealRank+1,'description':'Rank found','maxNlc':dealsData.get('maxNlc'),'minNlc':dealsData.get('minNlc'),'status':dealsData.get('status'),'dp':dealsData.get('dp')}
    
    return {'rank':0,'description':'Rank not found','maxNlc':dealsData.get('maxNlc'),'minNlc':dealsData.get('minNlc'),'status':dealsData.get('status'),'dp':dealsData.get('dp')}
    

def getCashBackDetails(identifier, source_id):
    if mc.get("category_cash_back") is None or not bool(mc.get("category_cash_back")):
        populateCashBack()
    
    if source_id in (1,2,4,5,6,7):
        skuData = list(get_mongo_connection().Catalog.MasterData.find({'identifier':identifier.strip(), 'source_id':source_id}))
    elif source_id == 3:
        skuData = list(get_mongo_connection().Catalog.MasterData.find({'secondaryIdentifier':identifier.strip(), 'source_id':source_id}))
    else:
        return {}
    if len(skuData) > 0:
        itemCashBackMap = mc.get("item_cash_back")
        itemCashBack = itemCashBackMap.get(skuData[0]['_id'])
        if itemCashBack is not None:
            return itemCashBack
        cashBackMap = mc.get("category_cash_back")
        sourceCashBack = cashBackMap.get(source_id)
        if sourceCashBack is not None and len(sourceCashBack) > 0:
            for cashBack in sourceCashBack:
                if cashBack.get(skuData[0]['category_id']) is None:
                    continue
                else:
                    return cashBack.get(skuData[0]['category_id'])
        else:
            return {} 
    else:
        return {}
    
def getImgSrc(identifier, source_id):
    skuData = None
    if source_id in (1,2,4,5,6,7):
        skuData = get_mongo_connection().Catalog.MasterData.find_one({'identifier':identifier.strip(), 'source_id':source_id})
    elif source_id == 3:
        skuData = get_mongo_connection().Catalog.MasterData.find_one({'secondaryIdentifier':identifier.strip(), 'source_id':source_id})
    if skuData is None:
        return {}
    else:
        try:
            return {'thumbnail':skuData.get('thumbnail').strip()}
        except:
            return {'thumbnail':skuData.get('thumbnail')}
    
def next_weekday(d, weekday):
    days_ahead = weekday - d.weekday()
    if days_ahead <= 0: # Target day already happened this week
        days_ahead += 7
    return d + timedelta(days_ahead)
    

def getAllDealerPrices(offset, limit):
    data = []
    collection = get_mongo_connection().Catalog.SkuDealerPrices
    cursor = collection.find().skip(offset).limit(limit)
    for val in cursor:
        master = get_mongo_connection().Catalog.MasterData.find_one({'skuBundleId':val['skuBundleId']})
        if master is not None:
            val['brand'] = master['brand']
            val['source_product_name'] = master['source_product_name']
        else:
            val['brand'] = ""
            val['source_product_name'] = ""
        val['showDp'] = int(val['showDp'])
        data.append(val)
    return data

def addSkuDealerPrice(data):
    collection = get_mongo_connection().Catalog.SkuDealerPrices
    cursor = collection.find_one({"skuBundleId":data['skuBundleId']})
    if cursor is not None:
        return {0:"BundleId information already present."}
    else:
        collection.insert(data)
        get_mongo_connection().Catalog.MasterData.update({'skuBundleId':data['skuBundleId']},{"$set":{'updatedOn':to_java_date(datetime.now())}},multi=True)
        return {1:"Data added successfully"}

def updateSkuDealerPrice(data, _id):
    try:
        collection = get_mongo_connection().Catalog.SkuDealerPrices
        collection.update({'_id':ObjectId(_id)},{"$set":{'dp':data['dp']}},upsert=False, multi = False)
        get_mongo_connection().Catalog.MasterData.update({'skuBundleId':data['skuBundleId']},{"$set":{'updatedOn':to_java_date(datetime.now())}},multi=True)
        return {1:"Data updated successfully"}
    except:
        return {0:"Data not updated."}

def updateExceptionalNlc(data, _id):
    try:
        collection = get_mongo_connection().Catalog.ExceptionalNlc
        collection.update({'_id':ObjectId(_id)},{"$set":{'maxNlc':data['maxNlc'], 'minNlc':data['minNlc'], 'overrideNlc':data['overrideNlc']}},upsert=False, multi = False)
        get_mongo_connection().Catalog.MasterData.update({'skuBundleId':data['skuBundleId']},{"$set":{'updatedOn':to_java_date(datetime.now())}},multi=True)
        return {1:"Data updated successfully"}
    except:
        return {0:"Data not updated."}

def resetCache(userId):
    try:
        mc.delete(userId)
        return {1:'Cache cleared.'}
    except:
        return {0:'Unable to clear cache.'}
    
def updateCollection(data):
    try:
        collection = get_mongo_connection().Catalog[data['class']]
        class_name = data.pop('class')
        _id = data.pop('oid')
        result = collection.update({'_id':ObjectId(_id)},{"$set":data},upsert=False, multi = False)
        if class_name != "Notifications":
            record = list(collection.find({'_id':ObjectId(_id)}))
            if class_name !="CategoryDiscount":
                if record[0].has_key('sku'):
                    field = '_id'
                    val = record[0]['sku']
                else:
                    field = 'skuBundleId'
                    val = record[0]['skuBundleId']
                get_mongo_connection().Catalog.MasterData.update({field:val},{"$set":{'updatedOn':to_java_date(datetime.now())}},upsert=False, multi = True)
            else:
                get_mongo_connection().Catalog.MasterData.update({'brand':re.compile(record[0]['brand'], re.IGNORECASE),'category_id':record[0]['category_id']}, \
                                                                 {"$set":{'updatedOn':to_java_date(datetime.now())}},upsert=False,multi=True)
        if class_name =='SkuDealerPrices':
            get_mongo_connection().Catalog.Deals.update({'skuBundleId':val},{"$set":data},upsert=False, multi=True)
        return {1:"Data updated successfully"}
    except Exception as e:
        print e
        return {0:"Data not updated."}
        
    
def addNegativeDeals(data, multi):
    if multi !=1: 
        collection = get_mongo_connection().Catalog.NegativeDeals
        cursor = collection.find({"sku":data['sku']})
        if cursor.count() > 0:
            return {0:"Sku information already present."}
        else:
            collection.insert(data)
            return {1:"Data added successfully"}
    else:
        skuIds = __getBundledSkusfromSku(data['sku'])
        for sku in skuIds:
            data['sku'] = sku.get('_id')
            collection = get_mongo_connection().Catalog.NegativeDeals
            cursor = collection.find({"sku":data['sku']})
            if cursor.count() > 0:
                continue
            else:
                data.pop('_id',None)
                collection.insert(data)
        return {1:"Data added successfully"}

def getAllNegativeDeals(offset, limit):
    data = []
    collection = get_mongo_connection().Catalog.NegativeDeals
    cursor = collection.find().skip(offset).limit(limit)
    for val in cursor:
        master = list(get_mongo_connection().Catalog.MasterData.find({'_id':val['sku']}))
        if len(master) > 0:
            val['brand'] = master[0]['brand']
            val['source_product_name'] = master[0]['source_product_name']
            val['skuBundleId'] = master[0]['skuBundleId']
        else:
            val['brand'] = ""
            val['source_product_name'] = ""
            val['skuBundleId'] = ""
        data.append(val)
    return data

def getAllManualDeals(offset, limit):
    data = []
    collection = get_mongo_connection().Catalog.ManualDeals
    cursor = collection.find().skip(offset).limit(limit)
    for val in cursor:
        master = list(get_mongo_connection().Catalog.MasterData.find({'_id':val['sku']}))
        if len(master) > 0:
            val['brand'] = master[0]['brand']
            val['source_product_name'] = master[0]['source_product_name']
            val['skuBundleId'] = master[0]['skuBundleId']
        else:
            val['brand'] = ""
            val['source_product_name'] = ""
            val['skuBundleId'] = ""
        data.append(val)
    return data
    
def addManualDeal(data, multi):
    if multi !=1:
        collection = get_mongo_connection().Catalog.ManualDeals
        cursor = collection.find({'sku':data['sku']})
        if cursor.count() > 0:
            return {0:"Sku information already present."}
        else:
            collection.insert(data)
            get_mongo_connection().Catalog.MasterData.update({'_id':data['sku']},{"$set":{'updatedOn':to_java_date(datetime.now())}},multi=False)
            return {1:"Data added successfully"}
    else:
        skuIds = __getBundledSkusfromSku(data['sku'])
        for sku in skuIds:
            data['sku'] = sku.get('_id')
            collection = get_mongo_connection().Catalog.ManualDeals
            cursor = collection.find({'sku':data['sku']})
            if cursor.count() > 0:
                continue
            else:
                data.pop('_id',None)
                collection.insert(data)
        get_mongo_connection().Catalog.MasterData.update({'skuBundleId':sku.get('skuBundleId')},{"$set":{'updatedOn':to_java_date(datetime.now())}},multi=True)
        return {1:"Data added successfully"}
        
def deleteDocument(data):
    print "inside detete document"
    print data
    try:
        collection = get_mongo_connection().Catalog[data['class']]
        class_name = data.pop('class')
        _id = data.pop('oid')
        record = list(collection.find({'_id':ObjectId(_id)}))
        collection.remove({'_id':ObjectId(_id)})
        if class_name != "Notifications":
            if class_name !="CategoryDiscount":
                print record[0]
                if record[0].has_key('sku'):
                    field = '_id'
                    val = record[0]['sku']
                else:
                    field = 'skuBundleId'
                    val = record[0]['skuBundleId']
                print "Updating master"
                print field
                print val
                get_mongo_connection().Catalog.MasterData.update({field:val},{"$set":{'updatedOn':to_java_date(datetime.now())}},multi=True)
            else:
                get_mongo_connection().Catalog.MasterData.update({'brand':re.compile(record[0]['brand'], re.IGNORECASE),'category_id':record[0]['category_id']}, \
                                                                 {"$set":{'updatedOn':to_java_date(datetime.now())}},upsert=False,multi=True)
        return {1:"Document deleted successfully"}
    except Exception as e:
        print e
        return {0:"Document not deleted."}

def searchMaster(offset, limit, search_term):
    data = []
    if search_term is not None:
        terms = search_term.split(' ')
        outer_query = []
        for term in terms:
            outer_query.append({"source_product_name":re.compile(term, re.IGNORECASE)})
        try:
            collection = get_mongo_connection().Catalog.MasterData.find({"$and":outer_query,'source_id':{'$in':SOURCE_MAP.keys()}}).skip(offset).limit(limit)
            for record in collection:
                data.append(record)
        except:
            pass
    else:
        collection = get_mongo_connection().Catalog.MasterData.find({'source_id':{'$in':SOURCE_MAP.keys()}}).skip(offset).limit(limit)
        for record in collection:
            data.append(record)
    return data

def getAllFeaturedDeals(offset, limit):
    data = []
    collection = get_mongo_connection().Catalog.FeaturedDeals
    cursor = collection.find({}).skip(offset).limit(limit)
    for val in cursor:
        master = list(get_mongo_connection().Catalog.MasterData.find({'skuBundleId':val['skuBundleId']}))
        if len(master) > 0:
            val['brand'] = master[0]['brand']
            val['source_product_name'] = master[0]['source_product_name']
            val['skuBundleId'] = master[0]['skuBundleId']
        else:
            val['brand'] = ""
            val['source_product_name'] = ""
            val['skuBundleId'] = ""
        data.append(val)
    return data
    
def addFeaturedDeal(data, multi):
    collection = get_mongo_connection().Catalog.FeaturedDeals
    cursor = collection.find({'skuBundleId':data['skuBundleId']})
    master = get_mongo_connection().Catalog.MasterData.find_one({'skuBundleId':data['skuBundleId']})
    if master is None:
        return {0:"BundleId is wrong"}
    otherInfoObj = data['otherInfo']
    toPop = []
    for x,y in otherInfoObj.iteritems():
        if y==0:
            toPop.append(x)
    
    for popItem in toPop:
        otherInfoObj.pop(popItem)
    if len(otherInfoObj.keys())==0:
        return {0:"No rank info to add"}
    
    for x,y in otherInfoObj.iteritems():
        exist = get_mongo_connection().Catalog.FeaturedDeals.find({'otherInfo.'+x:y})
        if exist.count() >0:
            return {0:"Rank already assigned bundleId %s"%(exist[0]['skuBundleId'])}
    if cursor.count() > 0:
        return {0:"SkuBundleId information already present."}
    else:
        collection.insert(data)
        return {1:"Data added successfully"}

def searchCollection(class_name, sku, skuBundleId):
    data = []
    collection = get_mongo_connection().Catalog[class_name]
    if class_name == "Notifications":
        cursor = collection.find({'skuBundleId':skuBundleId})
        for val in cursor:
            master = list(get_mongo_connection().Catalog.MasterData.find({'skuBundleId':val['skuBundleId']}))
            if len(master) > 0:
                val['brand'] = master[0]['brand']
                val['model_name'] = master[0]['model_name']
                val['skuBundleId'] = master[0]['skuBundleId']
            else:
                val['brand'] = ""
                val['model_name'] = ""
                val['skuBundleId'] = val['skuBundleId']
            data.append(val)
        return data
    master = None
    if sku is not None:
        if COLLECTION_MAP.has_key(class_name):
            master = get_mongo_connection().Catalog.MasterData.find_one({'_id':sku})
            cursor = collection.find({'skuBundleId':master['skuBundleId']})
        else:
            cursor = collection.find({'sku':sku})
        for val in cursor:
            if master is None:
                master = get_mongo_connection().Catalog.MasterData.find_one({'_id':val['sku']})
            if master is not None:
                val['brand'] = master['brand']
                val['source_product_name'] = master['source_product_name']
                val['skuBundleId'] = master['skuBundleId']
            else:
                val['brand'] = ""
                val['source_product_name'] = ""
                val['skuBundleId'] = ""
            data.append(val)
        return data
    else:
        if not COLLECTION_MAP.has_key(class_name):
            skuIds = get_mongo_connection().Catalog.MasterData.find({'skuBundleId':skuBundleId}).distinct('_id')
            for sku in skuIds:
                cursor = collection.find({'sku':sku})
                for val in cursor:
                    master = list(get_mongo_connection().Catalog.MasterData.find({'_id':val['sku']}))
                    if len(master) > 0:
                        val['brand'] = master[0]['brand']
                        val['source_product_name'] = master[0]['source_product_name']
                        val['skuBundleId'] = master[0]['skuBundleId']
                    else:
                        val['brand'] = ""
                        val['source_product_name'] = ""
                        val['skuBundleId'] = ""
                    data.append(val)
            return data
        else:
            cursor = collection.find({'skuBundleId':skuBundleId})
            for val in cursor:
                master = list(get_mongo_connection().Catalog.MasterData.find({'skuBundleId':val['skuBundleId']}))
                if len(master) > 0:
                    val['brand'] = master[0]['brand']
                    val['source_product_name'] = master[0]['source_product_name']
                else:
                    val['brand'] = ""
                    val['source_product_name'] = ""
                data.append(val)
            return data

def __getBrandIdForBrand(brandName, category_id):
    brandInfo = Brands.query.filter(Brands.category_id==category_id).filter(Brands.name == brandName).all()
    if brandInfo is None or len(brandInfo)!=1:
        raise
    else:
        return brandInfo[0].id

def addNewItem(data):
    try:
        data['updatedOn'] = to_java_date(datetime.now())
        data['addedOn'] = to_java_date(datetime.now())
        data['priceUpdatedOn'] = to_java_date(datetime.now())
        max_id = list(get_mongo_connection().Catalog.MasterData.find().sort([('_id',pymongo.DESCENDING)]).limit(1))
        max_bundle = list(get_mongo_connection().Catalog.MasterData.find().sort([('skuBundleId',pymongo.DESCENDING)]).limit(1))
        data['_id'] = max_id[0]['_id'] + 1
        data['skuBundleId'] = max_bundle[0]['skuBundleId'] + 1
        data['identifier'] = str(data['identifier'])
        data['secondaryIdentifier'] = str(data['secondaryIdentifier'])
        data['model_name'] = str(data['model_name'])
        data['brand_id'] = __getBrandIdForBrand(data['brand'], data['category_id'])
        data['shippingCost'] = float(data['shippingCost'])
        if data['category_id'] ==6 and data['subCategoryId'] ==0:
            return {0:'Sub-Category not selected'}
        elif data['category_id'] !=6 and data['subCategoryId'] !=0:
            return {0:'Sub-Category not valid'}
        else:
            pass
        data['subCategory'] = SUB_CATEGORY_MAP.get(data['subCategoryId'])
        get_mongo_connection().Catalog.MasterData.insert(data)
        return {1:'Data added successfully'}
    except Exception as e:
        print e
        return {0:'Unable to add data.'}
    finally:
        session.close()
    
def addItemToExistingBundle(data):
    try:
        data['updatedOn'] = to_java_date(datetime.now())
        data['addedOn'] = to_java_date(datetime.now())
        data['priceUpdatedOn'] = to_java_date(datetime.now())
        max_id = list(get_mongo_connection().Catalog.MasterData.find().sort([('_id',pymongo.DESCENDING)]).limit(1))
        data['_id'] = max_id[0]['_id'] + 1
        data['identifier'] = str(data['identifier'])
        data['secondaryIdentifier'] = str(data['secondaryIdentifier'])
        data['model_name'] = str(data['model_name'])
        data['brand_id'] = __getBrandIdForBrand(data['brand'], data['category_id'])
        data['shippingCost'] = float(data['shippingCost'])
        if data['category_id'] ==6 and data['subCategoryId'] ==0:
            return {0:'Sub-Category not selected'}
        elif data['category_id'] !=6 and data['subCategoryId'] !=0:
            return {0:'Sub-Category not valid'}
        else:
            pass
        data['subCategory'] = SUB_CATEGORY_MAP.get(data['subCategoryId'])
        get_mongo_connection().Catalog.MasterData.insert(data)
        return {1:'Data added successfully.'}
    except Exception as e:
        print e
        return {0:'Unable to add data.'}
    finally:
        session.close()

def updateMaster(data, multi):
    try:
        print data
        if multi != 1:
            _id = data.pop('_id')
            skuBundleId = data.pop('skuBundleId')
            data['updatedOn'] = to_java_date(datetime.now())
            data['identifier'] = str(data['identifier'])
            data['secondaryIdentifier'] = str(data['secondaryIdentifier'])
            data['model_name'] = str(data['model_name'])
            data['shippingCost'] = float(data['shippingCost'])
            data['brand_id'] = __getBrandIdForBrand(data['brand'], data['category_id'])
            if data['category_id'] ==6 and data['subCategoryId'] ==0:
                return {0:'Sub-Category not selected'}
            elif data['category_id'] !=6 and data['subCategoryId'] !=0:
                return {0:'Sub-Category not valid'}
            else:
                pass
            data['subCategory'] = SUB_CATEGORY_MAP.get(data['subCategoryId'])
            get_mongo_connection().Catalog.MasterData.update({'_id':_id},{"$set":data},upsert=False)
            return {1:'Data updated successfully.'}
        else:
            _id = data.pop('_id')
            skuBundleId = data.pop('skuBundleId')
            data['updatedOn'] = to_java_date(datetime.now())
            data['identifier'] = str(data['identifier'])
            data['secondaryIdentifier'] = str(data['secondaryIdentifier'])
            data['brand_id'] = __getBrandIdForBrand(data['brand'], data['category_id'])
            data['model_name'] = str(data['model_name'])
            data['shippingCost'] = float(data['shippingCost'])
            if data['category_id'] ==6 and data['subCategoryId'] ==0:
                return {0:'Sub-Category not selected'}
            elif data['category_id'] !=6 and data['subCategoryId'] !=0:
                return {0:'Sub-Category not valid'}
            else:
                pass
            data['subCategory'] = SUB_CATEGORY_MAP.get(data['subCategoryId'])
            get_mongo_connection().Catalog.MasterData.update({'_id':_id},{"$set":data},upsert=False)
            similarItems = get_mongo_connection().Catalog.MasterData.find({'skuBundleId':skuBundleId})
            for item in similarItems:
                if item['_id'] == _id:
                    continue
                item['updatedOn'] = to_java_date(datetime.now())
                item['thumbnail'] = data['thumbnail']
                item['category'] = data['category']
                item['category_id'] = data['category_id']
                item['is_shortage'] = data['is_shortage']
                item['mrp'] = data['mrp']
                item['status'] = data['status']
                item['maxPrice'] = data['maxPrice']
                item['brand_id'] = data['brand_id']
                item['subCategoryId'] = data['subCategoryId']
                item['subCategory'] = data['subCategory']
                similar_item_id = item.pop('_id')
                get_mongo_connection().Catalog.MasterData.update({'_id':similar_item_id},{"$set":item},upsert=False)
            return {1:'Data updated successfully.'}
    except:
        return {0:'Unable to update data'}
    finally:
        session.close()

def getLiveCricScore():
    return mc.get('liveScore')

def addBundleToNotification(data):
    try:
        collection = get_mongo_connection().Catalog.Notifications
        cursor = collection.find({'skuBundleId':data['skuBundleId']})
        if cursor.count() > 0:
            return {0:"SkuBundleId information already present."}
        else:
            collection.insert(data)
            return {1:'Data updated successfully.'}
    except:
        return {0:'Unable to add data.'}

def getAllNotifications(offset, limit):
    data = []
    collection = get_mongo_connection().Catalog.Notifications
    cursor = collection.find().sort([('endDate',pymongo.DESCENDING)]).skip(offset).limit(limit)
    for val in cursor:
        master = list(get_mongo_connection().Catalog.MasterData.find({'skuBundleId':val['skuBundleId']}))
        if len(master) > 0:
            val['brand'] = master[0]['brand']
            val['model_name'] = master[0]['model_name']
            val['skuBundleId'] = master[0]['skuBundleId']
        else:
            val['brand'] = ""
            val['model_name'] = ""
            val['skuBundleId'] = val['skuBundleId']
        data.append(val)
    return data

def getBrandsForFilter(category_id):
    if mc.get("brandFilter") is None:
        print "Populating brand data for category_id %d" %(category_id)
        tabData, mobData, accData = [], [], []
        mobileDeals = get_mongo_connection().Catalog.Deals.aggregate([
                                                                      {"$match":{"category_id":3,"showDeal":1,"totalPoints":{"$gt":-100}}
                                                                    },
                                                                 {"$group" : 
                                                                  {'_id':{'brand_id':'$brand_id','brand':'$brand'},'count':{'$sum':1}}
                                                                  }
                                                                ])
        
        tabletDeals = get_mongo_connection().Catalog.Deals.aggregate([
                                                                      {"$match":{"category_id":5,"showDeal":1,"totalPoints":{"$gt":-100}}
                                                                    },
                                                                 {"$group" : 
                                                                  {'_id':{'brand_id':'$brand_id','brand':'$brand'},'count':{'$sum':1}}
                                                                  }
                                                                ])
        
        accessoriesDeals = get_mongo_connection().Catalog.Deals.aggregate([
                                                                      {"$match":{"category_id":6,"showDeal":1,"totalPoints":{"$gt":-100}}
                                                                    },
                                                                 {"$group" : 
                                                                  {'_id':{'brand_id':'$brand_id','brand':'$brand'},'count':{'$sum':1}}
                                                                  }
                                                                ])
        
        allDeals = get_mongo_connection().Catalog.Deals.aggregate([
                                                                   {"$match":{"showDeal":1,"totalPoints":{"$gt":-100}}
                                                                    },
                                                                 {"$group" : 
                                                                  {'_id':{'brand_id':'$brand_id','brand':'$brand'},'count':{'$sum':1}}
                                                                  }
                                                                ])
        #print mobileDeals
        #print "==========Mobile data ends=========="
        
        #print tabletDeals
        #print "==========Tablet data ends=========="
        
        #print allDeals
        #print "==========All deal data ends========="
        
        for mobileDeal in mobileDeals['result']:
            if mobileDeal.get('_id').get('brand_id') != 0:
                tempMap = {}
                tempMap['brand'] = mobileDeal.get('_id').get('brand')
                tempMap['brand_id'] = mobileDeal.get('_id').get('brand_id')
                tempMap['count'] = mobileDeal.get('count')
                mobData.append(tempMap)
        
        for tabletDeal in tabletDeals['result']:
            if tabletDeal.get('_id').get('brand_id') != 0:
                tempMap = {}
                tempMap['brand'] = tabletDeal.get('_id').get('brand')
                tempMap['brand_id'] = tabletDeal.get('_id').get('brand_id')
                tempMap['count'] = tabletDeal.get('count')
                tabData.append(tempMap)
        
        for accessoryDeal in accessoriesDeals['result']:
            if accessoryDeal.get('_id').get('brand_id') != 0:
                tempMap = {}
                tempMap['brand'] = accessoryDeal.get('_id').get('brand')
                tempMap['brand_id'] = accessoryDeal.get('_id').get('brand_id')
                tempMap['count'] = accessoryDeal.get('count')
                accData.append(tempMap)
        
        
        brandMap = {}
        for allDeal in allDeals['result']:
            if allDeal.get('_id').get('brand_id') != 0:
                if brandMap.has_key(allDeal.get('_id').get('brand')):
                    brand_ids = brandMap.get(allDeal.get('_id').get('brand')).get('brand_ids')
                    brand_ids.append(allDeal.get('_id').get('brand_id'))
                    brandMap[allDeal.get('_id').get('brand')] = {'brand_ids':brand_ids,'count':brandMap.get(allDeal.get('_id').get('brand')).get('count') + allDeal.get('count')}
                else:
                    temp = []
                    temp.append(allDeal.get('_id').get('brand_id'))
                    brandMap[allDeal.get('_id').get('brand')] = {'brand_ids':temp,'count':allDeal.get('count')}
      
        mc.set("brandFilter",{0:brandMap, 3:mobData, 5:tabData, 6:accData}, 600)  
    
    return sorted(mc.get("brandFilter").get(category_id), key = lambda x: (-x['count'], x['brand']))

def getStaticDeals(offset, limit, category_id, direction):
    user_specific_deals = mc.get("staticDeals")
    if user_specific_deals is None:
        __populateStaticDeals()
        user_specific_deals = mc.get("staticDeals")
    rev = False
    if direction is None or direction == -1:
        rev=True
    return sorted((user_specific_deals.get(category_id))[offset:offset+limit],reverse=rev)

def __populateStaticDeals():
    print "Populating memcache for static deals"
    outer_query = []
    outer_query.append({"showDeal":1})
    query = {}
    query['$gt'] = -100
    outer_query.append({'totalPoints':query})
    all_deals = list(get_mongo_connection().Catalog.Deals.find({"$and":outer_query},{'_id':1,'category_id':1,'brand':1,'totalPoints':1,'bestSellerPoints':1,'nlcPoints':1,'rank':1,'available_price':1,'dealType':1,'source_id':1,'brand_id':1,'skuBundleId':1}).sort([('totalPoints',pymongo.DESCENDING),('bestSellerPoints',pymongo.DESCENDING),('nlcPoints',pymongo.DESCENDING),('rank',pymongo.DESCENDING)]))
    mobile_deals = []
    tablet_deals = []
    for deal in all_deals:
        item = get_mongo_connection().Catalog.MasterData.find({'_id':deal['_id']})
        if deal['category_id'] ==3:
            mobile_deals.append(getItemObjForStaticDeals(item[0]))
        elif deal['category_id'] ==5:
            tablet_deals.append(getItemObjForStaticDeals(item[0]))
        else:
            continue
    
    random.shuffle(mobile_deals,random.random)
    random.shuffle(tablet_deals,random.random)
    
    mem_cache_val = {3:mobile_deals, 5:tablet_deals}
    mc.set("staticDeals", mem_cache_val, 3600)

def getItemObjForStaticDeals(item,transform=None):
    mpu = str(item.get('marketPlaceUrl'))
    if transform:
        if mpu.find("snapdeal")!=-1:
            mpu = "http://m.snapdeal.com"+mpu[mpu.find("/product"):]
        elif mpu.find("homeshop18")!=-1:
            mpu = "http://m.homeshop18.com/product.mobi?productId="+item['identifier']
        elif mpu.find("saholic.com")!=-1:
            mpu = "http://m."+mpu[mpu.find("saholic.com"):]
        elif mpu.find("shopclues.com")!=-1:
            mpu = "http://m."+mpu[mpu.find("shopclues.com"):]
        else:
            pass
    
    return {'marketPlaceUrl':mpu,'available_price':int(item.get('available_price')),'source_product_name':item.get('source_product_name'),'thumbnail':item.get('thumbnail'),'source_id':int(item.get('source_id'))}

def getItemByMerchantIdentifier(identifier, source_id):
    skuData = None
    if source_id in (1,2,4,5,6,7):
        skuData = get_mongo_connection().Catalog.MasterData.find_one({'identifier':identifier.strip(), 'source_id':source_id})
    elif source_id == 3:
        skuData = get_mongo_connection().Catalog.MasterData.find_one({'secondaryIdentifier':identifier.strip(), 'source_id':source_id})
    if skuData is None:
        return {}
    else:
        return skuData
    
def getDealsForNotification(skuBundleIds,skipSplitting=False):
    if not skipSplitting:
        bundles= [int(skuBundleId) for skuBundleId in skuBundleIds.split(',')]
        print bundles
    else:
        bundles = skuBundleIds
    dealsList = []
    dealsListMap = []
    for bundleId in bundles:
        outer_query = []
        outer_query.append({ "$or": [ { "showDeal": 1} , { "prepaidDeal": 1 } ] })
        outer_query.append({'skuBundleId':bundleId})
        deals = get_mongo_connection().Catalog.Deals.find({"$and":outer_query})
        for deal in deals:
            dealsList.append(deal)
    sortedMap = {}
    rankMap = {}
    rank = 0
    for sorted_deal in dealsList:
        if sortedMap.get(sorted_deal['skuBundleId']) is None:
            sortedMap[sorted_deal['skuBundleId']] = {rank:[sorted_deal]}
            rankMap[rank] = (sortedMap[sorted_deal['skuBundleId']].values())[0]
            rank = rank +1
        else:
            for temp_list in sortedMap.get(sorted_deal['skuBundleId']).itervalues():
                temp_list.append(sorted_deal)
            rankMap[(sortedMap.get(sorted_deal['skuBundleId']).keys())[0]] = temp_list
                
    for dealList in [rankMap.get(k, []) for k in range(0, len(bundles))]:
        temp = []
        for d in dealList:
            item = list(get_mongo_connection().Catalog.MasterData.find({'_id':d['_id']}))
            if len(item) ==0:
                continue
            if d['dealType'] == 1 and d['source_id'] ==1:
                item[0]['marketPlaceUrl'] = "http://www.amazon.in/dp/%s"%(item[0]['identifier'].strip())
            elif d['source_id'] ==3:
                item[0]['marketPlaceUrl'] = item[0]['marketPlaceUrl']+'?supc='+item[0].get('identifier')
            else:
                pass 
            try:
                cashBack = getCashBack(item[0]['_id'], item[0]['source_id'], item[0]['category_id'])
                if not cashBack or cashBack.get('cash_back_status')!=1:
                    item[0]['cash_back_type'] = 0
                    item[0]['cash_back'] = 0
                else:
                    item[0]['cash_back_type'] = int(cashBack['cash_back_type'])
                    item[0]['cash_back'] = cashBack['cash_back']
            except:
                print "Error in adding cashback to deals"
                item[0]['cash_back_type'] = 0
                item[0]['cash_back'] = 0
            try:
                item[0]['dp'] = d['dp']
                item[0]['showDp'] = d['showDp']
            except:
                item[0]['dp'] = 0.0
                item[0]['showDp'] = 0
                
            try:
                if item[0]['showVideo']==0:
                    item[0]['videoLink'] =""
            except:
                item[0]['videoLink'] =""
            try:
                if item[0]['quantity'] >1:
                    ppq = float(item[0]['available_price'])/item[0]['quantity']
                    
                    if ppq == round(ppq):
                        item[0]['ppq'] = int(ppq)
                    else:
                        item[0]['ppq'] = round(ppq,2)
                else:
                    item[0]['ppq'] = 0
            except:
                item[0]['ppq'] = 0
            
            if item[0]['category_id']!=6:
                try:
                    item[0]['filterLink'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['brand'])+'&filter=brand&brands='+str(int(item[0]['brand_id']))
                    item[0]['filterText'] = 'More %s items'%(item[0]['brand'])
                except:
                    item[0]['filterLink'] = ""
                    item[0]['filterText'] = ""
            else:
                try:
                    if item[0]['subCategory']=='' or item[0]['subCategory'] is None or item[0]['subCategoryId']==0:
                        raise
                    item[0]['filterLink'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['subCategory'])+'&filter=subcategory&subcategories='+str(int(item[0]['subCategoryId']))
                    item[0]['filterText'] = 'More %s'%(item[0]['subCategory'])
                except:
                    item[0]['filterLink'] = ''
                    item[0]['filterText'] = ""
            try:
                if item[0]['source_id']==4:
                    item_availability_info = mc.get("item_availability_"+str(item[0]['identifier']).strip())
                    if item_availability_info is None or len(item_availability_info)==0:
                        item[0]['availabilityInfo'] = [{}]
                    else:
                        item[0]['availabilityInfo'] = item_availability_info
            except:
                item[0]['availabilityInfo'] = [{}]
        
            temp.append(item[0])
        if len(temp) > 1:
            temp = sorted(temp, key = lambda x: (x['available_price']),reverse=False)
        dealsListMap.append(temp)
    return dealsListMap

def getSkuBrandData(sku):
    if sku is None:
        return {}
    else:
        orders = get_mongo_connection().Catalog.MasterData.find_one({'skuBundleId':sku})
        if orders is None:
            return {}
        return orders

def addDealPoints(data):
    collection = get_mongo_connection().Catalog.DealPoints
    cursor = collection.find({'skuBundleId':data['skuBundleId']})
    if cursor.count() > 0:
        return {0:"Sku information already present."}
    else:
        collection.insert(data)
        get_mongo_connection().Catalog.MasterData.update({'skuBundleId':data['skuBundleId']},{"$set":{'updatedOn':to_java_date(datetime.now())}},multi=True)
        return {1:"Data added successfully"}

def getAllBundlesWithDealPoints(offset, limit):
    data = []
    collection = get_mongo_connection().Catalog.DealPoints
    cursor = collection.find().sort([('endDate',pymongo.DESCENDING)]).skip(offset).limit(limit)
    for val in cursor:
        master = get_mongo_connection().Catalog.MasterData.find_one({'skuBundleId':val.get('skuBundleId')})
        if master is not None:
            val['brand'] = master['brand']
            val['source_product_name'] = master['product_name']
        else:
            val['brand'] = ""
            val['source_product_name'] = ""
        data.append(val)
    return data

def generateRedirectUrl(retailer_id, app_id):
    try:
        if retailer_id <= 0:
            return {'url':"","message":"Retailer Id not valid"}
        d_app_offer = app_offers.get_by(id=app_id)
    except:
        traceback.print_exc()
    finally:
        session.close()
    if d_app_offer is None:
        return {'url':"","message":"App id doesn't exist"}
    
    final_user_payout = 0
    if d_app_offer.override_payout:
        final_user_payout = d_app_offer.overriden_payout
    else:
        final_user_payout = d_app_offer.user_payout
    
    appTransactions = AppTransactions(app_id, retailer_id, to_java_date(datetime.now()), None, 1, CB_INIT, 1, CB_INIT, None, None, d_app_offer.offer_price, d_app_offer.overriden_payout, d_app_offer.override_payout, d_app_offer.user_payout, final_user_payout)
    
    get_mongo_connection().AppOrder.AppTransaction.insert(appTransactions.__dict__)
    embedd = str((appTransactions.__dict__).get('_id'))
    try:
        index = d_app_offer.link.index(".freeb.co.in")
    except:
        traceback.print_exc()
        return {'url':"","message":"Substring not found"}
    redirect_url = d_app_offer.link[0:index]+"."+embedd+d_app_offer.link[index:]
    get_mongo_connection().AppOrder.AppTransaction.update({'_id':ObjectId(embedd)},{"$set":{'redirect_url':redirect_url}})
    return {'url':redirect_url,"message":"Success"}

def addPayout(payout, transaction_id):
    try:
        print 'Got Response for Transaction Id:- '+ str(transaction_id)+ ' and Actual Payout:- '+str(payout)
        transaction = list(get_mongo_connection().AppOrder.AppTransaction.find({'_id':ObjectId(transaction_id)}))
        if len(transaction) > 0:
            if (transaction[0])['payout_status'] ==1:
                get_mongo_connection().AppOrder.AppTransaction.update({'_id':ObjectId(transaction_id)},{"$set":{'payout_amount':float(payout), 'payout_description': CB_APPROVED,'payout_status':2, 'cashback_status': 2, 'cash_back_description': CB_APPROVED, 'payout_time':to_java_date(datetime.now())}})
                
                approvedAppTransaction = approved_app_transactions.get_by(transaction_id=transaction_id)
                if approvedAppTransaction is None:
                    approvedAppTransaction = approved_app_transactions()
                    approvedAppTransaction.app_id = transaction[0].get('app_id')
                    approvedAppTransaction.cash_back_description = CB_APPROVED
                    approvedAppTransaction.retailer_id = transaction[0].get('retailer_id')
                    approvedAppTransaction.transaction_id = transaction_id
                    approvedAppTransaction.transaction_time = to_py_date(long(transaction[0].get('transaction_time')))
                    approvedAppTransaction.redirect_url = transaction[0].get('redirect_url')
                    approvedAppTransaction.payout_status = 2
                    approvedAppTransaction.payout_description = CB_APPROVED
                    approvedAppTransaction.cashback_status = 2 
                    approvedAppTransaction.payout_amount = long(payout)
                    approvedAppTransaction.payout_time = datetime.now()
                    approvedAppTransaction.offer_price = long(transaction[0].get('offer_price')) 
                    approvedAppTransaction.overridenCashBack = transaction[0].get('overridenCashBack')
                    approvedAppTransaction.isCashBackOverriden = transaction[0].get('isCashBackOverriden')
                    approvedAppTransaction.user_payout = transaction[0].get('user_payout')
                    approvedAppTransaction.cashBackConsidered = False
                    if transaction[0].get('final_user_payout') is not None:
                        approvedAppTransaction.final_user_payout = transaction[0].get('final_user_payout')
                    else:
                        if transaction[0].get('isCashBackOverriden'):
                            approvedAppTransaction.final_user_payout = transaction[0].get('overridenCashBack')
                        else:
                            approvedAppTransaction.final_user_payout = transaction[0].get('user_payout')
                    session.commit()
                    
                    updateResult = _updateApprovedCashbackToUser(approvedAppTransaction.id)
                else:
                    approvedAppTransaction.payout_amount = long(payout)
                    approvedAppTransaction.payout_time = datetime.now()
                    if approvedAppTransaction.cashBackConsidered == False:
                        updateResult = _updateApprovedCashbackToUser(approvedAppTransaction.id)
                    session.commit()
                    
                    '''
                    try:
                        if int(transaction[0]['offer_price']) != payout or int(transaction[0]['user_payout']) < payout:
                            _sendAlertForAppPayouts(int(transaction[0]['app_id']), int(transaction[0]['offer_price']), int(transaction[0]['user_payout']), payout)
                    except:
                        print traceback.print_exc()
                    '''
                return {'status':'ok','message':'Payout updated'}
            elif (transaction[0])['payout_status'] ==2:
                return {'status':'ok','message':'Payout already processed'}
            else:
                return {'status':'fail','message':'Something is wrong'}
        else:
            return {'status':'fail','message':'transaction_id not found'}
    except:
        print traceback.print_exc()
        try:
            get_mongo_connection().AppOrder.AppTransaction.update({'_id':ObjectId(transaction_id)},{"$set":{'payout_amount':None, 'payout_description': CB_INIT,'payout_status':1, 'cashback_status': 1, 'cash_back_description': CB_INIT, 'payout_time':None}})
        except:
            print 'Data Inconsistency in Cashback Process'
            print traceback.print_exc()
        return  {'status':'fail','message':'Something is wrong'}
    finally:
        session.close()
        
def _updateApprovedCashbackToUser(approvedAppTransactionId):
    approvedAppTransaction = approved_app_transactions.get_by(id=approvedAppTransactionId)
    if approvedAppTransaction.retailer_id < 0:
        return False
    
    currentMonth = datetime.today().month
    currentDay = datetime.today().day
    currentYear = datetime.today().year
    fortNight = (currentMonth - 1)*2 + (currentDay/15)
    if currentDay == 30 or currentDay ==31:
        fortNight = fortNight-1
    userAppCashbackObj = user_app_cashbacks.query.filter(user_app_cashbacks.yearVal==currentYear).filter(user_app_cashbacks.user_id==approvedAppTransaction.retailer_id).filter(user_app_cashbacks.fortnightOfYear==fortNight).filter(user_app_cashbacks.status=='Approved').first()
    userAppInstallObj = user_app_installs.query.filter(user_app_installs.user_id==approvedAppTransaction.retailer_id).filter(user_app_installs.app_id==approvedAppTransaction.app_id).filter(user_app_installs.transaction_date==datetime(currentYear, currentMonth, currentDay, 0, 0, 0, 0).date()).first()
    try:
        if userAppCashbackObj is None:
            userAppCashbackObj = user_app_cashbacks()
            userAppCashbackObj.user_id = approvedAppTransaction.retailer_id
            userAppCashbackObj.status = 'Approved'
            userAppCashbackObj.amount = approvedAppTransaction.final_user_payout
            userAppCashbackObj.fortnightOfYear = fortNight
            userAppCashbackObj.yearVal = currentYear
        else:
            userAppCashbackObj.amount = userAppCashbackObj.amount + approvedAppTransaction.final_user_payout
            
        if userAppInstallObj is None:
            app_offer = app_offers.get_by(id=approvedAppTransaction.app_id)
            userAppInstallObj = user_app_installs()
            userAppInstallObj.user_id = approvedAppTransaction.retailer_id
            userAppInstallObj.fortnightOfYear = fortNight
            userAppInstallObj.transaction_date = datetime(currentYear, currentMonth, currentDay, 0, 0, 0, 0).date()
            userAppInstallObj.app_id = approvedAppTransaction.app_id
            userAppInstallObj.app_name = app_offer.app_name
            userAppInstallObj.installCount = 1
            userAppInstallObj.payoutAmount = approvedAppTransaction.final_user_payout
        else:
            userAppInstallObj.installCount = userAppInstallObj.installCount + 1
            userAppInstallObj.payoutAmount = userAppInstallObj.payoutAmount +approvedAppTransaction.final_user_payout
            
        approvedAppTransaction.cashBackConsidered = True
        session.commit()
        return True
    except:
        session.rollback()
        print traceback.print_exc()
        return False
    
def _sendAlertForAppPayouts(app_id, offerPrice, userPayout, payout):
    m = Email('localhost')
    mFrom = "dtr@shop2020.in"
    m.setFrom(mFrom)
    mTo = ['rajneesh.arora@saholic.com','kshitij.sood@saholic.com','chaitnaya.vats@saholic.com','manoj.kumar@saholic.com','manish.sharma@shop2020.in']
    for receipient in mTo:
        m.addRecipient(receipient)
    appOffer = app_offers.get_by(id=app_id)
    if offerPrice != payout:
        m.setSubject("Mismatch in Offer Price and Actual Pay Out for App Id:- "+str(appOffer.id)+" App Name:- "+str(appOffer.app_name))
        message1 = "Offer Price:- "+ str(appOffer.offer_price) + "\n" + "Actual Pay Out:- "+ str(payout)
        m.setTextBody(message1)
    if userPayout > payout:
        m.setSubject("User Pay Out greater than actual PayOut for App Id:- "+str(appOffer.id)+" App Name:- "+str(appOffer.app_name))
        message2 = "User Pay Out Price:- "+ str(appOffer.user_payout) + "\n" + "Actual Pay Out:- "+ str(payout)
        m.setTextBody(message2)
    m.send()
        
def rejectCashback(orderId, subOrderId):
    cashBack = get_mongo_connection().Dtr.merchantOrder.update({"orderId":orderId, "subOrders.merchantSubOrderId":subOrderId}, 
                                                               {"$set":{"subOrders.$.cashBackStatus":CB_REJECTED}})
    print cashBack
    return cashBack.get("nModified")

def getAppOffers(retailer_id):
    if not bool(mc.get("cached_app_offers_"+str(retailer_id))):
        populateAppOffers(retailer_id)
    return mc.get("cached_app_offers_"+str(retailer_id)) 
    
def populateAppOffers(retailerId):
    retailerId = int(retailerId)
    #offset = req.get_param_as_int("offset")
    #limit = req.get_param_as_int("limit")
    nonPriortizedOffers = session.query(app_offers.id).join((appmasters,appmasters.id==app_offers.appmaster_id)).filter(app_offers.affiliate_id==retailerId).filter(appmasters.showApp==True).filter(app_offers.show==True).filter(app_offers.offer_active==True).filter(app_offers.offer_price>0).filter(appmasters.rank==0).order_by(desc('user_payout')).all()
    priortizeders = session.query(app_offers.id, appmasters.rank).join((appmasters,appmasters.id==app_offers.appmaster_id)).filter(app_offers.affiliate_id==retailerId).filter(appmasters.showApp==True).filter(app_offers.show==True).filter(app_offers.offer_active==True).filter(app_offers.offer_price>0).filter(appmasters.rank>0).order_by(asc(appmasters.rank)).all()
    #session.query(app_offers.id,app_offers.appmaster_id, app_offers.app_name, app_offers.affiliate_offer_id, app_offers.image_url, app_offers.downloads, app_offers.link, app_offers.offer_price, app_offers.offerCategory, app_offers.package_name, app_offers.promoImage, app_offers.ratings, case([(app_offers.override_payout == True, app_offers.overriden_payout)], else_=app_offers.user_payout).label('user_payout'), case([(appmasters.shortDescription != None, appmasters.shortDescription)], else_=None).label('shortDescription'), case([(appmasters.longDescription != None, appmasters.longDescription)], else_=None).label('longDescription'), appmasters.customerOneLiner, appmasters.retailerOneLiner,app_offers.priority, app_offers.offerCondition, app_offers.location).join((appmasters,appmasters.id==app_offers.appmaster_id)).filter(app_offers.affiliate_id==retailerId).filter(appmasters.showApp==True).filter(app_offers.show==True).filter(app_offers.offer_active==True).filter(app_offers.offer_price>0).order_by(case([(app_offers.priority.in_(tuple(nullCheckList)), 1)], else_=0), asc(app_offers.priority),desc('user_payout')).all()
    
    appOffersMap = {}
    priorityList = []
    priorityMap = {}
    for offer in priortizeders:
        if priorityMap.has_key(long(offer[1])):
            offersVal = priorityMap.get(long(offer[1]))
            offersVal.append(offer)
            priorityMap[long(offer[1])]=offersVal
        else:
            offersVal = []
            offersVal.append(offer)
            priorityMap[long(offer[1])]=offersVal

    priorityList = sorted(priorityMap)
      
    maxCount = len(nonPriortizedOffers) + len(priortizeders)
    
    if priorityList is not None and len(priorityList)>0:
        if maxCount < max(priorityList):
            maxCount = max(priorityList)
    
    count = 1
    blockedPlaces = []
    availablePlaces = []
    while count <= maxCount:
        if count in priorityList:
            blockedPlaces.append(count)
        else:
            availablePlaces.append(count)
        count = count +1
    print 'Blocked Places', blockedPlaces
    for val in blockedPlaces:
        key = val
        for offerObj in priorityMap.get(val):
            while appOffersMap.has_key(key):
                key = key+1
            appOffersMap[key] = long(offerObj[0])
            if key in availablePlaces:
                availablePlaces.remove(key)

    print 'Available Places', availablePlaces

    i=0
    for val in availablePlaces:
        if i<len(nonPriortizedOffers):
            appOffersMap[val]= long(nonPriortizedOffers[i][0])
        else:
            break
        i=i+1
    print 'AppOffersMap', appOffersMap
    
    finalAppOffersMap = {}
    if len(appOffersMap) > 0:
        for key in sorted(appOffersMap):               
            finalAppOffersMap[key] = appOffersMap[key]
            
        mc.set("cached_app_offers_"+str(retailerId), finalAppOffersMap, 120)
    else:
        print 'No Offers'
        mc.set("cached_app_offers_"+str(retailerId), {}, 10)              
        
def sendNotification(userIds, campaignName, title, message,notificationtype, url, expiresat='2999-01-01'):
    campaignId = addNotificationCampaign(campaignName, title, message, notificationtype, url, None)
    payload = {}
    payload["user_id"]= userIds[0]
    payload["type"]="pending"
    payload["notification_campaign_id"]= campaignId
    payload["status"]=0
    
    payloadList = []
    payloadList.append(payload)
    jsonObj = json.dumps([dict(pn) for pn in payloadList])
    print jsonObj
    pushpostrequest = urllib2.Request("http://45.33.50.227:3001/addPushNotification")
    pushpostrequest.add_header('Content-Type', 'application/json')
    response = urllib2.urlopen(pushpostrequest, jsonObj).read()
    print response
        
def addNotificationCampaign(name, title, message, type, url, sql):
    notificationCampaign = notification_campaigns()
    notificationCampaign.name = name
    notificationCampaign.title = title
    notificationCampaign.type = type
    notificationCampaign.message = message
    notificationCampaign.url = url
    notificationCampaign.sql = sql
    notificationCampaign.expiresat = datetime(2999, 1, 1)
    notificationCampaign.status = 'active'
    notificationCampaign.created = datetime.now()
    
    session.commit()
    campaignId = notificationCampaign.id
    
    session.close()
    return campaignId

def getDummyDeals(categoryId, offset, limit):
    outer_query = []
    outer_query.append({"showDeal":1})
    outer_query.append({"category_id":categoryId})
    query = {}
    query['$gt'] = -100
    outer_query.append({'totalPoints':query})
    all_deals = list(get_mongo_connection().Catalog.Deals.find({"$and":outer_query},{'_id':1}).sort([('totalPoints',pymongo.DESCENDING),('bestSellerPoints',pymongo.DESCENDING),('nlcPoints',pymongo.DESCENDING),('rank',pymongo.DESCENDING)]).skip(offset).limit(limit))
    returnObj = []
    for deal in all_deals:
        item = list(get_mongo_connection().Catalog.MasterData.find({'_id':deal['_id']}))
        returnObj.append(getItemObjForStaticDeals(item[0],transform=True))
    return returnObj

def searchDummyDeals(search_term , limit, offset):
    data = []
    uniqueMap = {}
    if search_term is not None:
        terms = search_term.split(' ')
        outer_query = []
        for term in terms:
            outer_query.append({"source_product_name":re.compile(term, re.IGNORECASE)})
        try:
            collection = get_mongo_connection().Catalog.MasterData.find({"$and":outer_query,'source_id':{'$in':SOURCE_MAP.keys()}})
            for record in collection:
                data.append(record)
        except:
            pass
    else:
        collection = get_mongo_connection().Catalog.MasterData.find({'source_id':{'$in':SOURCE_MAP.keys()}})
        for record in collection:
            data.append(record)
    for x in data:
        if not uniqueMap.has_key(x['skuBundleId']):
            uniqueMap[x['skuBundleId']] = {'source_product_name':x['source_product_name'],'skuBundleId':x['skuBundleId'],'thumbnail':x['thumbnail']}
    
    if (offset + limit) > len(uniqueMap.values()):
        limit = len(uniqueMap.values()) - offset - 1
        
    count = 0
#     for x in uniqueMap.values():
#         print count,
#         print '\t',
#         print x
#         count = count+1

    print offset
    print limit
    
    return uniqueMap.values()[offset:limit+offset]


def getDummyPricing(skuBundleId):
    collection = get_mongo_connection().Catalog.MasterData.find({'source_id':{'$in':SOURCE_MAP.keys()},'skuBundleId':skuBundleId,'in_stock':1})
    print collection.count()
    cheapest = 99999999
    cheapestDetails= None
    returnMap = {}
    
    for d in collection:
        if d['available_price'] < cheapest:
            cheapestDetails = d
            cheapest = int(d['available_price'])
        if returnMap.has_key(d['source_id']):
            d = getItemObjForStaticDeals(d,transform=True)
            d['toShowStore'] = 0
            returnMap[d['source_id']].append(d)
        else:
            temp = []
            d = getItemObjForStaticDeals(d,transform=True)
            d['toShowStore'] = 1
            temp.append(d)
            returnMap[d['source_id']] = temp
    returnMap['cheapest'] = cheapestDetails
    for y in returnMap.itervalues():
        if isinstance(y, (list, tuple)):
            (y[len(y)-1])['lastElement'] = 1
        else:
            pass
    if returnMap['cheapest'] ==None:
        dum = get_mongo_connection().Catalog.MasterData.find_one({'skuBundleId':skuBundleId,'source_id':{"$in":SOURCE_MAP.keys()}})
        returnMap['cheapest'] = {'thumbnail':dum['thumbnail'],'source_product_name':dum['source_product_name']}
    return returnMap


def addDealObject(data):
    if data.get('img_url') is None or data.get('img_url')=="" or data.get('name') is None or data.get('name')=="":
        return {0:'Invalid data'}   
    try:
        max_id = list(get_mongo_connection().Catalog.DealObject.find().sort([('_id',pymongo.DESCENDING)]).limit(1))
        if len(max_id) ==0:
            max_id = 0
        else:
            max_id = max_id[0]['_id']
        data['_id'] = max_id +1
        get_mongo_connection().Catalog.DealObject.insert(data)
        return {1:'Data added successfully'}
    except:
        return {0:'Error in adding data'}

def getAllDealObjects(offset, limit):
    data = []
    collection = get_mongo_connection().Catalog.DealObject
    cursor = collection.find({}).skip(offset).limit(limit)
    for val in cursor:
        data.append({'_id':val['_id'],'name':val['name']})
    return data

def deleteDealObject(id):
    try:
        get_mongo_connection().Catalog.DealObject.remove({'_id':id})
        get_mongo_connection().Catalog.FeaturedDealsDealObject.remove({'_id':id})
        return {1:"Deal Object deleted"}
    except:
        return {0:"Error in deleting object"}

def getDealObjectById(id):
    try:
        data = get_mongo_connection().Catalog.DealObject.find({'_id':id})
        return data
    except:
        return {}

def updateDealObject(data):
    try:
        _id = data['_id']
        data.pop('_id')
        get_mongo_connection().Catalog.DealObject.update({'_id':_id},{"$set":data},upsert=False)
        return {1:"Data updated successfully"}
    except:
        return {0:"Error in updating data"}

def getAllFeaturedDealsForDealObject(offset, limit):
    data = []
    collection = get_mongo_connection().Catalog.FeaturedDealsDealObject
    cursor = collection.find({}).skip(offset).limit(limit)
    for val in cursor:
        data.append(val)
    return data

def addFeaturedDealForDealObject(data):
    collection = get_mongo_connection().Catalog.FeaturedDealsDealObject
    cursor = collection.find({'_id':data['_id']})
    master = get_mongo_connection().Catalog.DealObject.find_one({'_id':data['_id']})
    if master is None:
        return {0:"Deal Object id wrong"}
    otherInfoObj = data['otherInfo']
    toPop = []
    for x,y in otherInfoObj.iteritems():
        if y==0:
            toPop.append(x)
    
    for popItem in toPop:
        otherInfoObj.pop(popItem)
    if len(otherInfoObj.keys())==0:
        return {0:"No rank info to add"}
    
    for x,y in otherInfoObj.iteritems():
        exist = get_mongo_connection().Catalog.FeaturedDealsDealObject.find({'otherInfo.'+x:y})
        if exist.count() >0:
            return {0:"Rank already assigned Deal Object Id %s"%(exist[0]['_id'])}
    if cursor.count() > 0:
        return {0:"Deal Object Id information already present."}
    else:
        collection.insert(data)
        return {1:"Data added successfully"}

def deleteFeaturedDealObject(id):
    try:
        get_mongo_connection().Catalog.FeaturedDealsDealObject.remove({'_id':id})
        return {1:"Deal Object deleted"}
    except:
        return {0:"Error in deleting object"}
    
def getSubCategoryForFilter(category_id):
    if mc.get("subCategoryFilter") is None:
        print "Populating subcategory data for category_id %d" %(category_id)
        tabData, mobData, accData = [], [], []
        
        accessoriesDeals = get_mongo_connection().Catalog.Deals.aggregate([
                                                                      {"$match":{"category_id":6,"showDeal":1,"totalPoints":{"$gt":-100}}
                                                                    },
                                                                 {"$group" : 
                                                                  {'_id':{'subCategoryId':'$subCategoryId','subCategory':'$subCategory'},'count':{'$sum':1}}
                                                                  }
                                                                ])
        
        for accessoryDeal in accessoriesDeals['result']:
            if accessoryDeal.get('_id').get('subCategoryId') != 0:
                tempMap = {}
                tempMap['subCategory'] = accessoryDeal.get('_id').get('subCategory')
                tempMap['subCategoryId'] = accessoryDeal.get('_id').get('subCategoryId')
                tempMap['count'] = accessoryDeal.get('count')
                accData.append(tempMap)
        
        
        mc.set("subCategoryFilter",{3:mobData, 5:tabData, 6:accData}, 600)  
    
    return sorted(mc.get("subCategoryFilter").get(category_id), key = lambda x: (-x['count'], x['subCategory']))

def dummyLogin(data):
    exist = list(get_mongo_connection().Catalog.DummyUser.find({'email':data['email'],'password':data['password']}))
    if len(exist) > 0:
        return {'user_id':exist[0]['_id'],'fullName':exist[0]['fullName']}
    else:
        return {'user_id':0}

def dummyRegister(data):
    try:
        exist = list(get_mongo_connection().Catalog.DummyUser.find({'email':data['email']}))
        if len(exist) > 0:
            return {'msg':"Email already registered",'user_id':0}
        else:
            max_id = list(get_mongo_connection().Catalog.DummyUser.find().sort([('_id',pymongo.DESCENDING)]).limit(1))
            if len(max_id) ==0:
                max_id = 0
            else:
                max_id = max_id[0]['_id']
            data['_id'] = max_id +1
            get_mongo_connection().Catalog.DummyUser.insert(data)
            return {'msg':"Registration successful",'user_id':data['_id'],'fullName':data['fullName']}
    except:
        return {'msg':"Error in registration.",'user_id':0}

def getDummyUser(user_id):
    exist = list(get_mongo_connection().Catalog.DummyUser.find({'_id':user_id}))
    if len(exist) > 0:
        return exist[0]
    else:
        return {'user_id':0,'fullName':"",'email':"","contactNumber":""}

def updateDummyUser(data):
    try:
        get_mongo_connection().Catalog.DummyUser.update({'_id':data['user_id']},{"$set":data},upsert=False)
        return {'msg':"Data updated successfuly",'response':1}
    except:
        return {'msg':"Unable to update data",'response':0}
    
def getDealsForSearchText(subCategoryIds, searchTerm, offset, limit):
    subCategories= [int(subCategoryId) for subCategoryId in subCategoryIds.split('^')]
    print "SubCategories are ",subCategories
    payload = {
    "query": {
        "bool": {
            "must": [{
                    "match": {
                        "title": {
                            "query": searchTerm,
                            "operator": "and"
                        }
                    }
                },

                {
                    "in": {
                        "subCategoryId": subCategories
                    }
                }

            ]
        }
    }
}
    result =  get_elastic_search_connection().search(index="my_index", body=payload, from_=offset, size=limit)
    totalCount= result['hits']['total']
    temp = []
    bundles = []
    if len(result['hits']['hits']) > 0:
        for x in result['hits']['hits']:
            tempMap = {}
            tempMap = {'skuBundleId':x['_source']['id'],'title':x['_source']['title']}
            temp.append(tempMap)
            bundles.append(x['_source']['id'])
    #return temp
    return getDealsForNotification(bundles, skipSplitting=True)

def getCountForSearchText(subCategoryIds, searchTerm):
    subCategories= [int(subCategoryId) for subCategoryId in subCategoryIds.split('^')]
    payload = {
    "query": {
        "bool": {
            "must": [{
                    "match": {
                        "title": {
                            "query": searchTerm,
                            "operator": "and"
                        }
                    }
                },

                {
                    "in": {
                        "subCategoryId": subCategories
                    }
                }

            ]
        }
    }
}
    
    result =  get_elastic_search_connection().search(index="my_index", body=payload)
    totalCount= result['hits']['total']
    return {'searchTerm':searchTerm,'count':totalCount}

def getDealById(id):
    item = list(get_mongo_connection().Catalog.MasterData.find({'_id':int(id)}))
    d = get_mongo_connection().Catalog.Deals.find_one({'_id':int(id)})
    if d is None:
        d = {'showDp':0,'dp':0}
    if len(item) ==0:
        return {}
    try:
        cashBack = getCashBack(item[0]['_id'], item[0]['source_id'], item[0]['category_id'])
        if not cashBack or cashBack.get('cash_back_status')!=1:
            item[0]['cash_back_type'] = 0
            item[0]['cash_back'] = 0
        else:
            if cashBack.get('maxCashBack') is not None:
                
                if cashBack.get('cash_back_type') ==1 and (float(cashBack.get('cash_back'))*item[0]['available_price'])/100 > cashBack.get('maxCashBack'):
                    cashBack['cash_back_type'] = 2
                    cashBack['cash_back'] = cashBack['maxCashBack']
                elif cashBack.get('cash_back_type') ==2 and cashBack.get('cash_back') > cashBack.get('maxCashBack'):
                    cashBack['cash_back'] = cashBack['maxCashBack']
            
            item[0]['cash_back_type'] = int(cashBack['cash_back_type'])
            item[0]['cash_back'] = cashBack['cash_back']
    except:
        print "Error in adding cashback to deals"
        item[0]['cash_back_type'] = 0
        item[0]['cash_back'] = 0
    try:
        item[0]['dp'] = d['dp']
        item[0]['showDp'] = d['showDp']
    except:
        item[0]['dp'] = 0.0
        item[0]['showDp'] = 0
    try:
        item[0]['thumbnail'] = item[0]['thumbnail'].strip()
    except:
        pass
    
    try:
        if item[0]['showVideo']==0:
            item[0]['videoLink'] =""
    except:
        item[0]['videoLink'] =""
    try:
        if item[0]['quantity'] >1:
            ppq = float(item[0]['available_price'])/item[0]['quantity']
             
            if ppq == round(ppq):
                item[0]['ppq'] = int(ppq)
            else:
                item[0]['ppq'] = round(ppq,2)
        else:
            item[0]['ppq'] = 0
    except:
        item[0]['ppq'] = 0
    if item[0]['category_id']!=6:
        try:
            item[0]['filterLink'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['brand'])+'&filter=brand&brands='+str(int(item[0]['brand_id']))
            item[0]['filterText'] = 'More %s items'%(item[0]['brand'])
        except:
            item[0]['filterLink'] = ""
            item[0]['filterText'] = ""
    else:
        try:
            if item[0]['subCategory']=='' or item[0]['subCategory'] is None or item[0]['subCategoryId']==0:
                raise
            item[0]['filterLink'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['subCategory'])+'&filter=subcategory&subcategories='+str(int(item[0]['subCategoryId']))
            item[0]['filterText'] = 'More %s'%(item[0]['subCategory'])
        except:
            item[0]['filterLink'] = ''
            item[0]['filterText'] = ""
    try:
        if item[0]['source_id']==4:
            item_availability_info = mc.get("item_availability_"+str(item[0]['identifier']).strip())
            if item_availability_info is None or len(item_availability_info)==0:
                item[0]['availabilityInfo'] = [{}]
            else:
                item[0]['availabilityInfo'] = item_availability_info
    except:
        item[0]['availabilityInfo'] = [{}]
    return item[0]

            
def main():
    "8-cable , 15- charger, 20-screen guard"
    
    res = getDealsForSearchText("20^8","iph",0,1000)
    for i in res:
        print i
    
if __name__=='__main__':
    main()