Subversion Repositories SmartDukaan

Rev

Rev 22293 | Rev 23004 | 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, Promotion, NotificationCampaign,CrmRefundWallet
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, user_accounts
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,CREDIT_TYPE_REFUND,CREDIT_TYPE_OFFER,CREDIT_TYPE_ADJUSTMENT,REFUND_ADJUSTMENT_MAP, todict,REVERSE_SOURCE_MAP,\
    get_mongo_connection_dtr_data, SUB_CATEGORY_HEADER_RANKING
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
from string import lower
try:
    import ordereddict
except:
    pass


import bson.son as son
import math

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

DataService.initialize()
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"}
ONLINE_DEAL_SOURCE_MAP = {1:'AMAZON',2:'FLIPKART',3:'SNAPDEAL',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['sku']):
            itemCashBackMap[row['sku']] = 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"])
            if (refund["type"]) == CREDIT_TYPE_REFUND:
                batchDetails = fetchCrmRefundByBatchId(refund["batch"])
                referenceNumber = batchDetails.get('reference_no')                
                refund["description"] = "Refunded against Saholic order #%s"%(referenceNumber)
            elif (refund["type"]) == CREDIT_TYPE_ADJUSTMENT:
                batchDetails = fetchCrmRefundByBatchId(refund["batch"])
                referenceNumber = batchDetails.get('reference_no')
                referenceStore = REVERSE_SOURCE_MAP.get(batchDetails.get('store'))
                refund["description"] = "Adjusted against %s order #%s"%(referenceStore,referenceNumber)
            elif (refund["type"]) == CREDIT_TYPE_OFFER:
                refund["description"] = "April Accessories Cashback Offer"                
            else:
                refund["description"] = ""
            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,'netPriceAfterCashBack':1})
    for d in deals:
        d['persPoints'] = 0
        d['dealRankPoints'] = 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:{}}
    
    
    #Not taking accessories into account
    featuredDeals.pop(6,None)
    print featuredDeals
    
    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})
    outer_query.append({'category_id':{"$in":[3,5]}})
    brandPrefMap = {}
    pricePrefMap = {}
    actionsMap = {}
    try:
        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
    except:
        pass
    finally:
        session.close()
    
    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,'netPriceAfterCashBack':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
    
    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'))
#     
#    specialOffer = None
#    promoOffer = get_mongo_connection().Catalog.PromoOffer.find_one({'user_id':userId})
#    try:
#        if promoOffer is not None:
#            offer = get_mongo_connection().Catalog.Promotions.find_one({'_id':promoOffer.get('offer_id')})
#            if offer is None:
#                raise
#            promo = Promotion(offer.get('_id'),offer.get('offer_name'),offer.get('offer_description') , offer.get('categories_applicable'), offer.get('sub_categories_not_applicable'),
#                     offer.get('startDate'), offer.get('endDate'), promoOffer.get('target1'), promoOffer.get('target1_cash_back_percetage'), promoOffer.get('target2'), promoOffer.get('target2_cash_back_percetage'), promoOffer.get('maxCashBack'),offer.get('url'),
#                     promoOffer.get('pending_order_value'), promoOffer.get('delivered_order_value'), promoOffer.get('last_run_timestamp'))
#    
#            specialOffer = promo
#    except:
#        traceback.print_exc()
    
    
    mem_cache_val = {3:mobile_deals, 5:tablet_deals,"3_rankMap": rankMapMobiles,"5_rankMap": rankMapTablets}
    mc.set(str(userId), mem_cache_val)
    
def __populateCacheForAccessories(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:{}}
    
    
    #Not taking into account mobiles, tablets
    featuredDeals.pop(3,None)
    featuredDeals.pop(5,None)
    
    print "featuredDeals are ",featuredDeals
    
    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 accessory memcache for userId",userId
    outer_query = []
    outer_query.append({ "$or": [ { "showDeal": 1} , { "prepaidDeal": 1 } ] })
    query = {}
    query['$gt'] = 0
    outer_query.append({'dealRankPoints':query})
    outer_query.append({'category_id':{"$in":[6]}})

    accessories_deals = list(get_mongo_connection().Catalog.Deals.find({"$and":outer_query},{'_id':1,'category_id':1,'brand':1,'bestSellerPoints':1,'nlcPoints':1,'totalPoints':1,'dealRankPoints':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,'netPriceAfterCashBack':1}).sort([('dealRankPoints',pymongo.DESCENDING),('bestSellerPoints',pymongo.DESCENDING)]))
    
    actionsMap = {}
    actionRank = 3
    try:
        favourite_data = session.query(user_actions).filter_by(user_id=userId).order_by(asc(user_actions.created)).all()
        favourite_ids = [x.store_product_id for x in favourite_data]
        master_ids = list(get_mongo_connection().Catalog.MasterData.find({'_id':{"$in":favourite_ids},'category_id':6},{'_id':1}))
        accessory_ids = [x['_id'] for x in master_ids]
        for x in favourite_data:
            if x.store_product_id not in accessory_ids:
                continue
            action = 1 if x.action == 'like' else 0
            if action==1:
                actionsMap[x.store_product_id] = {'action':action,'rank':actionRank,'dealRankPoints':None}
                actionRank = actionRank+3
            else:
                actionsMap[x.store_product_id] = {'action':action,'rank':None,'dealRankPoints':None}
    except:
        traceback.print_exc()
        print "Exception in actionsMap creation"
    finally:    
        session.close()
    
    pseudo_count = 1
    inserted_count = 0
    try:
        if actionsMap:
            for k,v in actionsMap.iteritems():
                tmp_deal = get_mongo_connection().Catalog.Deals.find_one({'_id':k})
                if tmp_deal is None:
                    v['rank'] = None
                    continue
                if tmp_deal['category_id']!=6 and (tmp_deal['showDeal']!=1 or tmp_deal['prepaidDeal']!=1) :
                    v['rank'] = None
                    continue
                if v['action'] ==0:
                    leastDealRankPoints = list(get_mongo_connection().Catalog.Deals.find({'subCategoryId':tmp_deal.get('subCategoryId')}).sort([('dealRankPoints',pymongo.ASCENDING)]).limit(1))
                    if len(leastDealRankPoints) == 0 or leastDealRankPoints[0].get('dealRankPoints') is None:
                        v['rank'] = None
                        continue
                    v['dealRankPoints'] = leastDealRankPoints[0]['dealRankPoints'] - 1
                    v['rank'] = 999999
                else:
                    v['dealRankPoints'] = tmp_deal.get('dealRankPoints')
    except:
        print "Exception in action map"
        traceback.print_exc()         
            
    for deal in accessories_deals:

        try:
            fd_bundles.remove(deal.get('skuBundleId'))
        except:
            pass
        try:
            if actionsMap and actionsMap.get(deal['_id'])!=None:
                if actionsMap.get(deal['_id']).get('action') ==1 and actionsMap.get(deal['_id']).get('rank')!=None:
                    actionRank = actionsMap.get(deal['_id']).get('rank')
                    if actionRank < pseudo_count:
                        deal['dealRankPoints'] = accessories_deals[actionRank-1]['dealRankPoints'] +.5 + inserted_count
                        actionsMap.get(deal['_id'])['dealRankPoints'] = deal['dealRankPoints'] 
                        inserted_count = inserted_count+1
                elif actionsMap.get(deal['_id']).get('action') ==0 and actionsMap.get(deal['_id']).get('rank')!=None:
                    deal['dealRankPoints'] = actionsMap.get(deal['_id']).get('dealRankPoints')
                    actionsMap.get(deal['_id'])['dealRankPoints'] = deal['dealRankPoints']
                else:
                    pass
            pseudo_count = pseudo_count+1
        except:
            print "Exception while arranging dealRankPoints"
            traceback.print_exc()
    
    accessories_deals = sorted(accessories_deals, key = lambda x: (x['dealRankPoints'],x['bestSellerPoints'], x['nlcPoints'], x['rank']),reverse=True)
        
    if len(fd_bundles) > 0:
        print "There is still bundle in feature deals.Lets add info"
        for skuBundleId in fd_bundles:
            dummyDealObjList = __constructDummyDealObject(skuBundleId)
            for dummyDealObj in dummyDealObjList:
                if dummyDealObj['category_id'] ==6:
                    accessories_deals.append(dummyDealObj)
    
    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 ==6:
                    accessories_deals.append(dummyDealObj)

    
    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'))
     
    specialOffer = None
    promoOffer = get_mongo_connection().Catalog.PromoOffer.find_one({'user_id':userId})
    try:
        if promoOffer is not None:
            offer = get_mongo_connection().Catalog.Promotions.find_one({'_id':promoOffer.get('offer_id')})
            if offer is None:
                raise
            promo = Promotion(offer.get('_id'),offer.get('offer_name'),offer.get('offer_description') , offer.get('categories_applicable'), offer.get('sub_categories_not_applicable'),
                     offer.get('startDate'), offer.get('endDate'), promoOffer.get('target1'), promoOffer.get('target1_cash_back_percetage'), promoOffer.get('target2'), promoOffer.get('target2_cash_back_percetage'), promoOffer.get('maxCashBack'),offer.get('url'),
                     promoOffer.get('pending_order_value'), promoOffer.get('delivered_order_value'), promoOffer.get('last_run_timestamp'))
    
            specialOffer = promo
    except:
        traceback.print_exc()
    
    
    mem_cache_val = {6:accessories_deals,"6_rankMap": rankMapAccessories, "specialOffer":specialOffer }
    mc.set(str(userId)+'_acc', 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],'offer_id':dealObject.get('offer_id')}
            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')

#introducing online/deals with fofo flag
def getNewDeals(userId, category_id, offset, limit, sort, direction, filterData=None, source=None, tag_ids=None):
    defaultFilter = False
    if filterData is not None:
        defaultFilter = True
    if mc.get("category_cash_back") is None or not bool(mc.get("category_cash_back")):
        populateCashBack()
    
    if source is not None:
        if source=="online":
            sourceToFilter =   [str(i) for i in ONLINE_DEAL_SOURCE_MAP.keys()]  #filter categores on basis of source and tags
        #For saholic specific deals
        elif source=="deals":
            sourceToFilter = ['4']
        #we should override sourceFilterString
        sourceFiterString = "sourceFilter:" + "^".join(sourceToFilter) 
        
        if filterData is None:
            filterData = sourceFiterString
        else:
            a = filterData.split('sourceFilter:')
            if len(a) > 1:
                filterData =  a[0] + sourceFiterString
                b = a[1].split("|")
                if len(b) > 1:
                    filterData = "|".join([filterData] + b[1:])
            else:
                filterData = a + "|" + sourceFiterString
    
    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
    #filter categores on basis of source and tags
    if source=="online":
        category_specific_deals = filter(lambda x: x['source_id'] in ONLINE_DEAL_SOURCE_MAP.keys(), category_specific_deals)
    #For saholic specific deals
    elif source=="deals":
        category_specific_deals = filter(lambda x: x['source_id'] == 4, category_specific_deals)        

    if filterData:
        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 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 = {}
    
    
    specialOffer = user_specific_deals.get('specialOffer')
    
    for dealList in [rankMap.get(k, []) for k in range(offset, offset+limit)]:
        if not defaultFilter:
            while(True):
                
                rankCounter = rankCounter+1
                if (fd_dealObject.get(category_id).get(rankCounter)) is not None:
                    if (fd_dealObject.get(category_id).get(rankCounter).get('offer_id') !=0):
                        #Check whether user can see offer
                        if specialOffer is None or specialOffer.endDate < to_java_date(datetime.now()):
                            continue
                    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 not defaultFilter:
                if item[0]['category_id']!=6:
                    try:
                        item[0]['filterLinkBrand'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['brand'])+'&filter=brand&brands='+str(int(item[0]['brand_id']))
                        item[0]['filterTextBrand'] = (item[0]['brand'])
                    except:
                        pass
                else:
                    try:
                        if item[0]['subCategory']=='' or item[0]['subCategory'] is None or item[0]['subCategoryId']==0:
                            raise
                        item[0]['filterLinkSubCategory'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['subCategory'])+'&filter=subcategory&subcategories='+str(int(item[0]['subCategoryId']))
                        item[0]['filterTextSubCategory'] = (item[0]['subCategory'])
                        item[0]['filterLinkBrand'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['brand'])+'&filter=brand&brands='+str(int(item[0]['brand_id']))
                        item[0]['filterTextBrand'] = (item[0]['brand'])
                    except:
                        pass
            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'] = [{}]
                        continue
                    else:
                        #remove items that are mapped with tag_ids recieved
                        if tag_ids:
                            #construct item_availability_info TAGS not matched 
                            item_availability_info = [av_info for av_info in item_availability_info if not (av_info.has_key('tag_ids') and not set(tag_ids).isdisjoint(av_info.get('tag_ids')))]
                            if len(item_availability_info)==0:
                                #item_availability_info = [{}]
                                continue
                        item[0]['availabilityInfo'] = item_availability_info
            except:
                continue
                #item[0]['availabilityInfo'] = [{}]
            
            if item[0]['source_id']==4:
                for av_info in item[0]['availabilityInfo']:
                    if not av_info:
                        continue
                    av_info['cash_back'] = item[0]['cash_back']
                    av_info['cash_back_type'] = item[0]['cash_back_type']
                    netPriceAfterCashBack = av_info['sellingPrice'] 
                    if av_info['cash_back_type'] ==1:
                        netPriceAfterCashBack = av_info['sellingPrice'] - math.floor(float(av_info['sellingPrice'])*av_info['cash_back']/100)
                    elif av_info['cash_back_type'] ==2:
                        netPriceAfterCashBack = av_info['sellingPrice'] - math.floor(av_info['cash_back'])
                    else:
                        pass
                    av_info['netPriceAfterCashBack'] = netPriceAfterCashBack
                
            #item[0]['netPriceAfterCashBack'] = d['netPriceAfterCashBack']
            
            if item[0]['source_id'] == SOURCE_MAP.get("PAYTM.COM"):
                if item[0]['codAvailable'] ==1:
                    paytmPrice = item[0]['available_price']
                else:
                    paytmPrice = item[0]['gross_price']
                  
                if item[0]['cash_back_type'] ==1:
                    item[0]['netPriceAfterCashBack'] = paytmPrice -  math.floor(float(paytmPrice)*item[0]['cash_back']/100)
                elif item[0]['cash_back_type'] ==2:
                    item[0]['netPriceAfterCashBack'] = paytmPrice -  math.floor(item[0]['cash_back'])
                else:
                    item[0]['netPriceAfterCashBack'] = paytmPrice
                
            else:
                if item[0]['cash_back_type'] ==1:
                    item[0]['netPriceAfterCashBack'] = item[0]['available_price'] -  math.floor(float(item[0]['available_price'])*item[0]['cash_back']/100)
                elif item[0]['cash_back_type'] ==2:
                    item[0]['netPriceAfterCashBack'] = item[0]['available_price'] -  math.floor(item[0]['cash_back'])
                else:
                    item[0]['netPriceAfterCashBack'] = item[0]['available_price']
            
            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 getAccesoryDeals(userId, category_id, offset, limit, sort, direction, filterData=None, source=None, tag_ids=None):
    defaultFilter = False
    if filterData is not None:
        defaultFilter = True
    
    if mc.get("category_cash_back") is None or not bool(mc.get("category_cash_back")):
        populateCashBack()
    

    if source is not None:
        if source=="online":
            sourceToFilter =   [str(i) for i in ONLINE_DEAL_SOURCE_MAP.keys()]  #filter categores on basis of source and tags
        #For saholic specific deals
        elif source=="deals":
            sourceToFilter = ['4']
        #we should override sourceFilterString
        sourceFiterString = "sourceFilter:" + "^".join(sourceToFilter) 
        
        if filterData is None:
            filterData = sourceFiterString
        else:
            a = filterData.split('sourceFilter:')
            if len(a) > 1:
                filterData =  a[0] + sourceFiterString
                b = a[1].split("|")
                if len(b) > 1:
                    filterData = "|".join([filterData] + b[1:])
            else:
                filterData = a + "|" + sourceFiterString
                    
    
    dealsListMap = []
    user_specific_deals = mc.get(str(userId)+'_acc')
    if user_specific_deals is None:
        __populateCacheForAccessories(userId)
        user_specific_deals = mc.get(str(userId)+'_acc')
    else:
        print "Getting user deals from accessory 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['dealRankPoints'], 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 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 = {}
    
    
    specialOffer = user_specific_deals.get('specialOffer')
    
    for dealList in [rankMap.get(k, []) for k in range(offset, offset+limit)]:
        if not defaultFilter:
            while(True):
                
                rankCounter = rankCounter+1
                if (fd_dealObject.get(category_id).get(rankCounter)) is not None:
                    if (fd_dealObject.get(category_id).get(rankCounter).get('offer_id') !=0):
                        #Check whether user can see offer
                        if specialOffer is None or specialOffer.endDate < to_java_date(datetime.now()):
                            continue
                    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]['dealRankPoints'] = d.get('dealRankPoints')
            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 not defaultFilter:
                if item[0]['category_id']!=6:
                    try:
                        item[0]['filterLinkBrand'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['brand'])+'&filter=brand&brands='+str(int(item[0]['brand_id']))
                        item[0]['filterTextBrand'] = (item[0]['brand'])
                    except:
                        pass
                else:
                    try:
                        if item[0]['subCategory']=='' or item[0]['subCategory'] is None or item[0]['subCategoryId']==0:
                            raise
                        item[0]['filterLinkSubCategory'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['subCategory'])+'&filter=subcategory&subcategories='+str(int(item[0]['subCategoryId']))
                        item[0]['filterTextSubCategory'] = (item[0]['subCategory'])
                        item[0]['filterLinkBrand'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['brand'])+'&filter=brand&brands='+str(int(item[0]['brand_id']))
                        item[0]['filterTextBrand'] = (item[0]['brand'])
                    except:
                        pass
            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:
                        continue
                        #item[0]['availabilityInfo'] = [{}]
                    else:
                        #remove items that are mapped with tag_ids recieved
                        if tag_ids:
                            #construct item_availability_info TAGS not matched 
                            item_availability_info = [av_info for av_info in item_availability_info if not (av_info.has_key('tag_ids') and not set(tag_ids).isdisjoint(av_info.get('tag_ids')))]
                            if len(item_availability_info)==0:
                                continue
                                #item_availability_info = [{}]
                        item[0]['availabilityInfo'] = item_availability_info
            except:
                continue
                #item[0]['availabilityInfo'] = [{}]
            
            if item[0]['source_id']==4:
                for av_info in item[0]['availabilityInfo']:
                    if not av_info:
                        continue
                    av_info['cash_back'] = item[0]['cash_back']
                    av_info['cash_back_type'] = item[0]['cash_back_type']
                    netPriceAfterCashBack = av_info['sellingPrice']
                    if av_info['cash_back_type'] ==1:
                        netPriceAfterCashBack = av_info['sellingPrice'] - math.floor(float(av_info['sellingPrice'])*av_info['cash_back']/100)
                    elif av_info['cash_back_type'] ==2:
                        netPriceAfterCashBack = av_info['sellingPrice'] - math.floor(av_info['cash_back'])
                    else:
                        pass
                    av_info['netPriceAfterCashBack'] = netPriceAfterCashBack
                
            #item[0]['netPriceAfterCashBack'] = d['netPriceAfterCashBack']
            
            if item[0]['source_id'] == SOURCE_MAP.get("PAYTM.COM"):
                if item[0]['codAvailable'] ==1:
                    paytmPrice = item[0]['available_price']
                else:
                    paytmPrice = item[0]['gross_price']
                  
                if item[0]['cash_back_type'] ==1:
                    item[0]['netPriceAfterCashBack'] = paytmPrice -  math.floor(float(paytmPrice)*item[0]['cash_back']/100)
                elif item[0]['cash_back_type'] ==2:
                    item[0]['netPriceAfterCashBack'] = paytmPrice -  math.floor(item[0]['cash_back'])
                else:
                    item[0]['netPriceAfterCashBack'] = paytmPrice
                
            else:
                if item[0]['cash_back_type'] ==1:
                    item[0]['netPriceAfterCashBack'] = item[0]['available_price'] -  math.floor(float(item[0]['available_price'])*item[0]['cash_back']/100)
                elif item[0]['cash_back_type'] ==2:
                    item[0]['netPriceAfterCashBack'] = item[0]['available_price'] -  math.floor(item[0]['cash_back'])
                else:
                    item[0]['netPriceAfterCashBack'] = item[0]['available_price']
            
#             if specialOffer is not None and item[0]['source_id']==4:
#                 if item[0]['category_id'] in specialOffer.categories_applicable and item[0]['subCategoryId'] not in specialOffer.sub_categories_not_applicable:
#                     item[0]['specialOffer'] = specialOffer.__dict__
#             else:
#                 item[0]['specialOffer'] = {}
            
            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
    print "Length deals before filter ", len(deals)
    brandsToFilter = []
    subCategoryToFilter = []
    priceToFilter = []
    sourceToFilter = []
        
    if filterData:
        filterArray = filterData.split('|')
        for data in filterArray:
            try:
                filter, info = data.split(':')
            except Exception as ex:
                traceback.print_exc()
                continue
            if filter == 'brandFilter':
                brandsToFilter = info.split('^')
            if filter == 'subCategoryFilter':
                subCategoryToFilter = info.split('^')
            if filter == 'priceFilter':
                priceToFilter = info.split('^')
            if filter == 'sourceFilter':
                sourceToFilter = sourceToFilter + info.split('^')
                    
    if brandsToFilter:
        temp = []    
        for deal in deals:
            if str(int(deal['brand_id'])) in brandsToFilter:
                temp.append(deal)
        deals = temp

    print "Length deals after brandfilter ", len(deals)
    
    if subCategoryToFilter:
        temp = []
        for deal in deals:
            if str(int(deal['subCategoryId'])) in subCategoryToFilter:
                temp.append(deal)
        deals = temp
    
    print "Length deals after subCatfilter ", len(deals)
        
    if sourceToFilter:
        temp = []
        for deal in deals:
            if str(int(deal['source_id'])) in sourceToFilter:
                temp.append(deal)
        deals = temp
    
    print "Length deals after source filter ", len(deals)

    if priceToFilter and len(priceToFilter) ==2:
        print "Inside price filter ",priceToFilter 
        temp = []
        for deal in deals:
            if deal.get('available_price') > float(priceToFilter[0]) and deal.get('available_price') <= float(priceToFilter[1]):
                temp.append(deal)
        deals = temp
        
        print "Length deals after price filter ", len(deals)
                
    return [trend['skuBundleId'] for trend in temp]

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}
    category_id = skuData[0]['category_id']
    if category_id != 6:
        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 mobiles/tablets"
    else:
        user_specific_deals = mc.get(str(userId)+'_acc')
        if user_specific_deals is None:
            __populateCacheForAccessories(userId)
            user_specific_deals = mc.get(str(userId)+'_acc')
        else:
            print "Getting user deals from accessory cache"
    
    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 = {}
        return {'rank':0, 'description':'Deal deleted from system','maxNlc':None, 'minNlc':None,'status':None,'dp':None}
    
    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')}
    
    if category_id!=6:
        sorted_deals = sorted(category_specific_deals, key = lambda x: (x['persPoints'],x['totalPoints'],x['bestSellerPoints'], x['nlcPoints'], x['rank']),reverse=True)
    else:
        sorted_deals = sorted(category_specific_deals, key = lambda x: (x['dealRankPoints'],x['totalPoints'],x['bestSellerPoints'], x['nlcPoints']),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'])
            return {}
        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(cache_type, keys):
    if (cache_type == 'deals'):
        for userId in keys.split(','):
            mc.delete(userId)
            mc.delete(userId+'_acc')
        return {1:'Cache cleared.'}
    elif (cache_type == 'itemCashBack'):
        mc.delete('item_cash_back')
        populateCashBack()
        return {1:'Cache cleared.'}
    else:
        {0:'Illegal cache type'}

        
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']
                val['product_name'] = master['product_name']
                val['source'] = SOURCE_MAP.get(master['source_id'])
            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']
                        val['product_name'] = master[0]['product_name']
                        val['source'] = SOURCE_MAP.get(master[0]['source_id'])
                    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'])
        data['internalRank'] = int(data['internalRank'])
        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'])
        data['internalRank'] = int(data['internalRank'])
        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['internalRank'] = int(data['internalRank'])
            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)
            get_mongo_connection().Catalog.MasterData.update({'skuBundleId':skuBundleId},{"$set":{'internalRank':data['internalRank']}},upsert=False, multi=True)
            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'])
            data['internalRank'] = int(data['internalRank'])
            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']
                item['internalRank'] = data['internalRank']
                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:
        traceback.print_exc()
        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,"dealRankPoints":{"$gt":0}}
                                                                    },
                                                                 {"$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)
      
        mc.set("brandFilter",{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]['filterLinkBrand'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['brand'])+'&filter=brand&brands='+str(int(item[0]['brand_id']))
                    item[0]['filterTextBrand'] = (item[0]['brand'])
                except:
                    pass
            else:
                try:
                    if item[0]['subCategory']=='' or item[0]['subCategory'] is None or item[0]['subCategoryId']==0:
                        raise
                    item[0]['filterLinkSubCategory'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['subCategory'])+'&filter=subcategory&subcategories='+str(int(item[0]['subCategoryId']))
                    item[0]['filterTextSubCategory'] = (item[0]['subCategory'])
                    item[0]['filterLinkBrand'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['brand'])+'&filter=brand&brands='+str(int(item[0]['brand_id']))
                    item[0]['filterTextBrand'] = (item[0]['brand'])
                except:
                    pass
            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'] = [{}]
            
            if item[0]['source_id']==4:
                for av_info in item[0]['availabilityInfo']:
                    if not av_info:
                        continue
                    av_info['cash_back'] = item[0]['cash_back']
                    av_info['cash_back_type'] = item[0]['cash_back_type']
                    netPriceAfterCashBack = av_info['sellingPrice'] 
                    if av_info['cash_back_type'] ==1:
                        netPriceAfterCashBack = av_info['sellingPrice'] - math.floor(float(av_info['sellingPrice'])*av_info['cash_back']/100)
                    elif av_info['cash_back_type'] ==2:
                        netPriceAfterCashBack = av_info['sellingPrice'] - math.floor(av_info['cash_back'])
                    else:
                        pass
                    av_info['netPriceAfterCashBack'] = netPriceAfterCashBack
            
            if item[0]['source_id'] != SOURCE_MAP.get("PAYTM.COM"):
                if item[0]['codAvailable'] ==1:
                    paytmPrice = item[0]['available_price']
                else:
                    paytmPrice = item[0]['gross_price']
                  
                if item[0]['cash_back_type'] ==1:
                    item[0]['netPriceAfterCashBack'] = paytmPrice -  math.floor(float(paytmPrice)*item[0]['cash_back']/100)
                elif item[0]['cash_back_type'] ==2:
                    item[0]['netPriceAfterCashBack'] = paytmPrice -  math.floor(item[0]['cash_back'])
                else:
                    item[0]['netPriceAfterCashBack'] = paytmPrice
                
            else:
                if item[0]['cash_back_type'] ==1:
                    item[0]['netPriceAfterCashBack'] = item[0]['available_price'] -  math.floor(float(item[0]['available_price'])*item[0]['cash_back']/100)
                elif item[0]['cash_back_type'] ==2:
                    item[0]['netPriceAfterCashBack'] = item[0]['available_price'] -  math.floor(item[0]['cash_back'])
                else:
                    item[0]['netPriceAfterCashBack'] = item[0]['available_price']
            
            
            item[0]['totalPoints'] = d['totalPoints']
        
            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','ritesh.chauhan@saholic.com','khushal.bhatia@saholic.com']
    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', sendsms=False, smstext=None):
    max_id = list(get_mongo_connection_dtr_data().User.notificationcampaigns.find().sort([('_id',pymongo.DESCENDING)]).limit(1))
    if len(max_id) ==0:
        max_id = 0
    else:
        max_id = max_id[0]['_id']
    max_id = max_id +1
    campaign = NotificationCampaign(max_id, campaignName, title, message, "SELECT User.id from users User where User.id="+str(userIds[0]), url, to_java_date(datetime.now()), to_java_date(datetime.now()+timedelta(days=730)), notificationtype, 'active', sendsms, smstext, 0, 0, 'BATCH_CREDIT')
    get_mongo_connection_dtr_data().User.notificationcampaigns.insert(campaign.__dict__)

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):
    print 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 or y=="":
            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,"dealRankPoints":{"$gt":0}}
                                                                    },
                                                                 {"$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
                    }
                }

            ]
        }
    },
    "sort": { "dealRankPoints": { "order": "desc" }}
}
    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 len(item) ==0:
        return {}
    if d is None:
        d = {'showDp':0,'dp':0}
    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]['filterLinkBrand'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['brand'])+'&filter=brand&brands='+str(int(item[0]['brand_id']))
            item[0]['filterTextBrand'] = (item[0]['brand'])
        except:
            pass
    else:
        try:
            if item[0]['subCategory']=='' or item[0]['subCategory'] is None or item[0]['subCategoryId']==0:
                raise
            item[0]['filterLinkSubCategory'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['subCategory'])+'&filter=subcategory&subcategories='+str(int(item[0]['subCategoryId']))
            item[0]['filterTextSubCategory'] = (item[0]['subCategory'])
            item[0]['filterLinkBrand'] = '/category/'+str(int(item[0]['category_id']))+'?searchFor='+urllib.quote(item[0]['brand'])+'&filter=brand&brands='+str(int(item[0]['brand_id']))
            item[0]['filterTextBrand'] = (item[0]['brand'])
        except:
            pass
    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'] = [{}]
    
    if item[0]['source_id']==4:
        for av_info in item[0]['availabilityInfo']:
            if not av_info:
                continue
            av_info['cash_back'] = item[0]['cash_back']
            av_info['cash_back_type'] = item[0]['cash_back_type']
            netPriceAfterCashBack = av_info['sellingPrice'] 
            if av_info['cash_back_type'] ==1:
                netPriceAfterCashBack = av_info['sellingPrice'] - math.floor(float(av_info['sellingPrice'])*av_info['cash_back']/100)
            elif av_info['cash_back_type'] ==2:
                netPriceAfterCashBack = av_info['sellingPrice'] - math.floor(av_info['cash_back'])
            else:
                pass
            av_info['netPriceAfterCashBack'] = netPriceAfterCashBack
    
    if item[0]['source_id'] != SOURCE_MAP.get("PAYTM.COM"):
        if item[0]['codAvailable'] ==1:
            paytmPrice = item[0]['available_price']
        else:
            paytmPrice = item[0]['gross_price']
          
        if item[0]['cash_back_type'] ==1:
            item[0]['netPriceAfterCashBack'] = paytmPrice -  math.floor(float(paytmPrice)*item[0]['cash_back']/100)
        elif item[0]['cash_back_type'] ==2:
            item[0]['netPriceAfterCashBack'] = paytmPrice -  math.floor(item[0]['cash_back'])
        else:
            item[0]['netPriceAfterCashBack'] = paytmPrice
        
    else:
        if item[0]['cash_back_type'] ==1:
            item[0]['netPriceAfterCashBack'] = item[0]['available_price'] -  math.floor(float(item[0]['available_price'])*item[0]['cash_back']/100)
        elif item[0]['cash_back_type'] ==2:
            item[0]['netPriceAfterCashBack'] = item[0]['available_price'] -  math.floor(item[0]['cash_back'])
        else:
            item[0]['netPriceAfterCashBack'] = item[0]['available_price']
        
    return item[0]

def getOfferForUser(userId):
    specialOffer = {}
    promoOffer = get_mongo_connection().Catalog.PromoOffer.find_one({'user_id':userId})
    try:
        if promoOffer is not None:
            offer = get_mongo_connection().Catalog.Promotions.find_one({'_id':promoOffer.get('offer_id')})
            if offer is None:
                raise
            promo = Promotion(offer.get('_id'),offer.get('offer_name'),offer.get('offer_description') , offer.get('categories_applicable'), offer.get('sub_categories_not_applicable'),
                     offer.get('startDate'), offer.get('endDate'), promoOffer.get('target1'), promoOffer.get('target1_cash_back_percetage'), promoOffer.get('target2'), promoOffer.get('target2_cash_back_percetage'), promoOffer.get('maxCashBack'), offer.get('url'),
                     promoOffer.get('pending_order_value'), promoOffer.get('delivered_order_value'), promoOffer.get('last_run_timestamp'))
            
            promo.offer_description = "Get upto %d%% cashback"%(promo.target2_cash_back_percetage)
    
            specialOffer = promo.__dict__
    except:
        pass
    return specialOffer

def getBrandSubCategoryInfo(category_id, id_list, type):
    try:
        id_list_mapping = {}
        if type == "brandInfo":
            brands = [int(brand_id) for brand_id in id_list.split('^')]
            for brand in brands:
                tm_brand = get_mongo_connection().Catalog.Deals.find_one({'brand_id':brand},{'brand':1})
                id_list_mapping[brand] = tm_brand.get('brand')
        elif type == "subCategoryInfo":
            subCategories = [int(subCategoryId) for subCategoryId in id_list.split('^')]
            for subCat in subCategories:
                id_list_mapping[subCat] = SUB_CATEGORY_MAP.get(subCat)
        else:
            return {}
        
        if mc.get("brandSubCategoryInfo") is None:
            collection =  get_mongo_connection().Catalog.Deals
            result = collection.aggregate( 
                    [
                        {'$match':{'category_id':category_id,'showDeal':1}},
                        {"$group": { "_id": { "subCategoryId": "$subCategoryId", "brand_id": "$brand_id", "brand":"$brand","subCategory":"$subCategory" }, "count": {"$sum": 1} } }
                    ]
                );
            #from pprint import pprint
            #pprint(result)
            
            subCategoryMap = {}
            brandMap = {}
            
            for data in result['result']:
                result_set = data['_id']
                count = data['count']
                subCategoryId = result_set['subCategoryId']
                brand_id = result_set['brand_id']
                subCategory = result_set['subCategory']
                brand = result_set['brand']
                 
                if subCategoryMap.has_key(subCategoryId):
                    subCategoryMap.get(subCategoryId).append({'brand_id':brand_id, 'count':count, 'subCategory':subCategory, 'brand':brand})
                else:
                    subCategoryMap[subCategoryId] = [{'brand_id':brand_id, 'count':count, 'subCategory':subCategory, 'brand':brand}]
                    
                if brandMap.has_key(brand_id):
                    brandMap.get(brand_id).append({'subCategoryId':subCategoryId, 'count':count, 'subCategory':subCategory, 'brand':brand})
                else:
                    brandMap[brand_id] = [{'subCategoryId':subCategoryId, 'count':count, 'subCategory':subCategory, 'brand':brand}]
            
            mc.set("brandSubCategoryInfo",{'subCategoryMap':subCategoryMap, 'brandMap': brandMap}, 600)
        
        
        returnMap = {}    
        brandSubCategoryInfo = mc.get("brandSubCategoryInfo")
        if brandSubCategoryInfo is None:
            return {'idListInfo':id_list_mapping,'result':[]}
        
        if type == "subCategoryInfo":
            if brandSubCategoryInfo.get('subCategoryMap') is None:
                return {'idListInfo':id_list_mapping,'result':[]}
            subCategories = [int(subCategoryId) for subCategoryId in id_list.split('^')]
            subCategoryMap = brandSubCategoryInfo.get('subCategoryMap')
            for subCategory in subCategories:
                tempList = subCategoryMap.get(subCategory)
                print tempList
                if tempList is None:
                    continue
                for v in tempList:
                    if returnMap.has_key(v['brand_id']):
                        existing = returnMap.get(v['brand_id'])
                        existing['count'] = existing['count'] + v['count'] 
                    else:
                        returnMap[v['brand_id']] = {'brand_id':v['brand_id'],'brand':v['brand'],'count':v['count']}
                
                
        elif type == "brandInfo":
            if brandSubCategoryInfo.get('brandMap') is None:
                return {'idListInfo':id_list_mapping,'result':[]}
            brands = [int(brand_id) for brand_id in id_list.split('^')]
            brandMap = brandSubCategoryInfo.get('brandMap')
            for brand_id in brands:
                tempList = brandMap.get(brand_id)
                print tempList
                if tempList is None:
                    continue
                for v in tempList:
                    if returnMap.has_key(v['subCategoryId']):
                        existing = returnMap.get(v['subCategoryId'])
                        existing['count'] = existing['count'] + v['count'] 
                    else:
                        returnMap[v['subCategoryId']] = {'subCategoryId':v['subCategoryId'],'subCategory':v['subCategory'],'count':v['count']}
        
        return {'idListInfo':id_list_mapping,'result':returnMap.values()}
    except:
        traceback.print_exc()
        return {}

def refundAmountInWallet(jsonReq):
    userId = int(jsonReq.get('user_id'))
    emailId = jsonReq.get('email_id')
    amount = int(jsonReq.get('amount'))
    store = jsonReq.get('store')
    refundType = jsonReq.get('type')
    mobileNumber = jsonReq.get('mobile')
    referenceId = jsonReq.get('reference_no')
    referenceDescription = jsonReq.get('reference_description')
    if not store:
        store = None
    else:
        store = store
    if lower(refundType)=='refund':
        refundType = CREDIT_TYPE_REFUND
    elif lower(refundType)=='adjustment':
        refundType = CREDIT_TYPE_ADJUSTMENT
    collection = get_mongo_connection().Dtr.crmrefundwallet
    offer1 = CrmRefundWallet(userId,emailId,mobileNumber,amount,refundType,store,referenceId,referenceDescription,REFUND_ADJUSTMENT_MAP.get(0),to_java_date(datetime.now()))    
    dict1 = todict(offer1)
    collection.save(dict1)
    return True

def updateCrmWalletStatus(status,_id,userId,batchId,approvedBy):
    if batchId is None:
        get_mongo_connection().Dtr.crmrefundwallet.update({'_id':ObjectId(_id),},{"$set":{"status":status,"update_timestamp":to_java_date(datetime.now())}})
    else:
        #Batch id should be none to ensure that it does not get override
        get_mongo_connection().Dtr.crmrefundwallet.update({'_id':ObjectId(_id), 'batchId':None},{"$set":{"status":status,"update_timestamp":to_java_date(datetime.now()),"batchId":batchId,"approved_by":approvedBy}})

def fetchCrmRefundUsers(status,offset,limit):
    if status is not None:
        cursor = list(get_mongo_connection().Dtr.crmrefundwallet.find({"status":status}).skip(offset).limit(limit).sort("created_timestamp",-1))
    else:
        cursor = list(get_mongo_connection().Dtr.crmrefundwallet.find().skip(offset).limit(limit).sort("created_timestamp",-1))
    return cursor

def fetchCrmRefundByBatchId(batchId):
    cursor = get_mongo_connection().Dtr.crmrefundwallet.find_one({"batchId":int(batchId)})
    return cursor

def userLookUpForSaholicId(userId):
    result = None
    try:
        response = session.query(user_accounts.account_key).filter_by(user_id=userId).filter(user_accounts.account_type=='saholic').first()
        if response is None:
            result = 'User Not present in profitmandi'
        else:
            result = response[0]
    except:
        result = 'User Not present in profitmandi'
        traceback.print_exc()
    finally:
        session.close()
    return result

  
def getAllItemCasback(itemcashback_id,offset,limit):
    itemcashbackcon = get_mongo_connection().Catalog.ItemCashBack
    masterData = get_mongo_connection().Catalog.MasterData
    if itemcashback_id is None: 
        response = []
        response_cash_back = list(itemcashbackcon.find().skip(offset).limit(limit))
        for r in response_cash_back:
            master = masterData.find_one({'_id':r['sku']})
            r['source'] = SOURCE_MAP.get(master['source_id'])
            r['product_name'] = master['product_name']
            response.append(r)
    else:
        response = itemcashbackcon.find_one({'_id' : ObjectId(itemcashback_id)})
        master = masterData.find_one({'_id':response['sku']})
        response['source'] = SOURCE_MAP.get(master['source_id'])
        response['product_name'] = master['product_name']
    return response

def itemCashbackAdd(item_skuId,cb,cb_description,cb_type,cb_status):
    itemcashbackcon = get_mongo_connection().Catalog.ItemCashBack
    response = list(itemcashbackcon.find({'sku':item_skuId}))
            
    if len(response) ==  0:
        itemcashbackcon.insert({'sku':item_skuId,'cash_back_description':cb_description,'cash_back':cb,'cash_back_type':cb_type,'cash_back_status': cb_status})
        return True     
        

def getHeaderLinks(category_id):
    result = {}
    if category_id == 6:
        rank = 1
        for subCat in SUB_CATEGORY_HEADER_RANKING:
            result[rank] = {'subCategoryId':subCat,'subCategory':SUB_CATEGORY_MAP.get(subCat)}
            rank = rank + 1
    return result.values()

def getDealsByType(category_id, offset, limit, type):
    dealListMap = []
    if type == 'exclusive':
        exclusive_deals = mc.get("exclusive_deals_"+str(category_id))
        if exclusive_deals is None:
            print "Populating exclusive_deals for ",category_id
            exclusive_deals = list(get_mongo_connection().Catalog.Deals.find({'category_id': category_id,'showDeal': 1, 'source_id': 4},{'_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,'netPriceAfterCashBack':1}).sort([('totalPoints',pymongo.DESCENDING),('bestSellerPoints',pymongo.DESCENDING),('nlcPoints',pymongo.DESCENDING),('rank',pymongo.DESCENDING)]))
            mc.set("exclusive_deals_"+str(category_id), exclusive_deals)
        
        for d in exclusive_deals[offset:limit+offset]:
            item = list(get_mongo_connection().Catalog.MasterData.find({'_id':d['_id']}))
            if len(item) ==0:
                continue 
            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
            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'] = [{}]
            
            if item[0]['source_id']==4:
                for av_info in item[0]['availabilityInfo']:
                    if not av_info:
                        continue
                    av_info['cash_back'] = item[0]['cash_back']
                    av_info['cash_back_type'] = item[0]['cash_back_type']
                    netPriceAfterCashBack = av_info['sellingPrice'] 
                    if av_info['cash_back_type'] ==1:
                        netPriceAfterCashBack = av_info['sellingPrice'] - math.floor(float(av_info['sellingPrice'])*av_info['cash_back']/100)
                    elif av_info['cash_back_type'] ==2:
                        netPriceAfterCashBack = av_info['sellingPrice'] - math.floor(av_info['cash_back'])
                    else:
                        pass
                    av_info['netPriceAfterCashBack'] = netPriceAfterCashBack
                
            if item[0]['cash_back_type'] ==1:
                item[0]['netPriceAfterCashBack'] = item[0]['available_price'] -  math.floor(float(item[0]['available_price'])*item[0]['cash_back']/100)
            elif item[0]['cash_back_type'] ==2:
                item[0]['netPriceAfterCashBack'] = item[0]['available_price'] -  math.floor(item[0]['cash_back'])
            else:
                item[0]['netPriceAfterCashBack'] = item[0]['available_price']         
            dealListMap.append([item[0]])
    return dealListMap
    


def main():
    #print getAccesoryDeals(47, 6, 0, 20, None, None, None)
    getCashBackDetails('1204769399', 3)
    
    
if __name__=='__main__':
    main()