Subversion Repositories SmartDukaan

Rev

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

from bson import json_util
from bson.json_util import dumps
from datetime import datetime, timedelta
from dtr import main
from dtr.config import PythonPropertyReader
from dtr.storage import Mongo
from dtr.storage.DataService import Retailers, Users, CallHistory, RetryConfig, \
    RetailerLinks, Activation_Codes, Agents,Agent_Roles,AgentLoginTimings
from dtr.utils import FetchLivePrices, DealSheet as X_DealSheet, \
    UserSpecificDeals
from dtr.utils.utils import getLogger
from elixir import *
from sqlalchemy.sql.expression import or_
from urllib import urlencode
import contextlib
import falcon
import json
import traceback
import urllib
import urllib2
import uuid
from operator import and_
import string

alphalist = list(string.uppercase)
alphalist.remove('O')
numList = ['1','2','3','4','5','6','7','8','9']
codesys = [alphalist, alphalist, numList, numList, numList]


def getNextCode(codesys, code=None):
    if code is None:
        code = []
        for charcode in codesys:
            code.append(charcode[0])
        return string.join(code, '')
    carry = True
    code = list(code)
    lastindex = len(codesys) - 1
    while carry:
        listChar = codesys[lastindex]
        newIndex = (listChar.index(code[lastindex])+1)%len(listChar)
        print newIndex
        code[lastindex] = listChar[newIndex]
        if newIndex != 0:
            carry = False
        lastindex -= 1
        if lastindex ==-1:
            raise BaseException("All codes are exhausted")
        
    return string.join(code, '')
        
        


global RETAILER_DETAIL_CALL_COUNTER
RETAILER_DETAIL_CALL_COUNTER = 0

lgr = getLogger('/var/log/retailer-acquisition-api.log')
DEALER_RETRY_FACTOR = int(PythonPropertyReader.getConfig('DEALER_RETRY_FACTOR'))
class CategoryDiscountInfo(object):
    
    def on_get(self, req, resp):
        
        result = Mongo.getAllCategoryDiscount()
        json_docs = [json.dumps(doc, default=json_util.default) for doc in result]
        resp.body = json.dumps(json_docs, encoding='utf-8')
    
    def on_post(self, req, resp):
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.addCategoryDiscount(result_json)
        resp.body = json.dumps(result, encoding='utf-8')
    
    def on_put(self, req, resp, _id):
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.updateCategoryDiscount(result_json, _id)
        resp.body = json.dumps(result, encoding='utf-8')
            
        
        
class SkuSchemeDetails(object):
    
    def on_get(self, req, resp):
        
        offset = req.get_param_as_int("offset")
        limit = req.get_param_as_int("limit")
        
        result = Mongo.getAllSkuWiseSchemeDetails(offset, limit)
        json_docs = [json.dumps(doc, default=json_util.default) for doc in result]
        resp.body = json.dumps(json_docs, encoding='utf-8')

    
    def on_post(self, req, resp):
        
        multi = req.get_param_as_int("multi")
        
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.addSchemeDetailsForSku(result_json, multi)
        resp.body = json.dumps(result, encoding='utf-8')
        
class SkuDiscountInfo():
    
    def on_get(self, req, resp):
        
        offset = req.get_param_as_int("offset")
        limit = req.get_param_as_int("limit")
        result = Mongo.getallSkuDiscountInfo(offset,limit)
        json_docs = [json.dumps(doc, default=json_util.default) for doc in result]
        resp.body = json.dumps(json_docs, encoding='utf-8')

    
    def on_post(self, req, resp):
        
        multi = req.get_param_as_int("multi")
        
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.addSkuDiscountInfo(result_json, multi)
        resp.body = json.dumps(result, encoding='utf-8')
        
    def on_put(self, req, resp, _id):
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.updateSkuDiscount(result_json, _id)
        resp.body = json.dumps(result, encoding='utf-8')

class ExceptionalNlc():
    
    def on_get(self, req, resp):
        
        offset = req.get_param_as_int("offset")
        limit = req.get_param_as_int("limit")
        
        result = Mongo.getAllExceptionlNlcItems(offset, limit)
        json_docs = [json.dumps(doc, default=json_util.default) for doc in result]
        resp.body = json.dumps(json_docs, encoding='utf-8')
    
    def on_post(self, req, resp):
        
        multi = req.get_param_as_int("multi")
        
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.addExceptionalNlc(result_json, multi)
        resp.body = json.dumps(result, encoding='utf-8')
    
    def on_put(self, req, resp, _id):
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.updateExceptionalNlc(result_json, _id)
        resp.body = json.dumps(result, encoding='utf-8')
        
class Deals():
    def on_get(self,req, resp, userId):
        categoryId = req.get_param_as_int("categoryId")
        offset = req.get_param_as_int("offset")
        limit = req.get_param_as_int("limit")
        sort = req.get_param("sort")
        direction = req.get_param_as_int("direction")
        filterData = req.get_param('filterData')
        result = Mongo.getNewDeals(int(userId), categoryId, offset, limit, sort, direction, filterData)
        json_docs = [json.dumps(doc, default=json_util.default) for doc in result]
        resp.body = json.dumps(json_docs, encoding='utf-8')

class MasterData():
    def on_get(self,req, resp, skuId):
        result = Mongo.getItem(skuId)
        try:
            json_docs = [json.dumps(doc, default=json_util.default) for doc in result]
            resp.body = json.dumps(json_docs, encoding='utf-8')
        except:
            json_docs = [json.dumps(doc, default=json_util.default) for doc in result]
            resp.body = json.dumps(json_docs, encoding='utf-8')
    
    def on_post(self,req, resp):
        
        addNew = req.get_param_as_int("addNew")
        update = req.get_param_as_int("update")
        addToExisting = req.get_param_as_int("addToExisting")
        multi = req.get_param_as_int("multi")
        
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        if addNew == 1:
            result = Mongo.addNewItem(result_json)
        elif update == 1:
            result = Mongo.updateMaster(result_json, multi)
        elif addToExisting == 1:
            result = Mongo.addItemToExistingBundle(result_json)
        else:
            raise
        resp.body = dumps(result)
    
class LiveData():
    def on_get(self,req, resp):
        if req.get_param_as_int("id") is not None:
            print "****getting only for id"
            id = req.get_param_as_int("id")
            try:
                result = FetchLivePrices.getLatestPriceById(id)
                json_docs = json.dumps(result, default=json_util.default)
                resp.body = json.dumps(json_docs, encoding='utf-8')
            except:
                json_docs = json.dumps({}, default=json_util.default)
                resp.body = json.dumps(json_docs, encoding='utf-8')
            
        else:
            print "****getting only for skuId"
            skuBundleId = req.get_param_as_int("skuBundleId")
            source_id = req.get_param_as_int("source_id")
            try:
                result = FetchLivePrices.getLatestPrice(skuBundleId, source_id)
                json_docs = [json.dumps(doc, default=json_util.default) for doc in result]
                resp.body = json.dumps(json_docs, encoding='utf-8')
            except:
                json_docs = [json.dumps(doc, default=json_util.default) for doc in [{}]]
                resp.body = json.dumps(json_docs, encoding='utf-8')
                
class CashBack():
    def on_get(self,req, resp):
        identifier = req.get_param("identifier")
        source_id = req.get_param_as_int("source_id")
        try:
            result = Mongo.getCashBackDetails(identifier, source_id)
            json_docs = json.dumps(result, default=json_util.default)
            resp.body = json_docs
        except:
            json_docs = json.dumps({}, default=json_util.default)
            resp.body = json_docs

class ImgSrc():
    def on_get(self,req, resp):
        identifier = req.get_param("identifier")
        source_id = req.get_param_as_int("source_id")
        try:
            result = Mongo.getImgSrc(identifier, source_id)
            json_docs = json.dumps(result, default=json_util.default)
            resp.body = json_docs
        except:
            json_docs = json.dumps({}, default=json_util.default)
            resp.body = json_docs

class DealSheet():
    def on_get(self,req, resp):
        X_DealSheet.sendMail()
        json_docs = json.dumps({'True':'Sheet generated, mail sent.'}, default=json_util.default)
        resp.body = json.dumps(json_docs, encoding='utf-8')
    
class DealerPrice():
    
    def on_get(self, req, resp):
        
        offset = req.get_param_as_int("offset")
        limit = req.get_param_as_int("limit")
        result = Mongo.getAllDealerPrices(offset,limit)
        json_docs = [json.dumps(doc, default=json_util.default) for doc in result]
        resp.body = json.dumps(json_docs, encoding='utf-8')
    
    def on_post(self, req, resp):
        
        multi = req.get_param_as_int("multi")
        
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.addSkuDealerPrice(result_json, multi)
        resp.body = json.dumps(result, encoding='utf-8')
    
    def on_put(self, req, resp, _id):
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.updateSkuDealerPrice(result_json, _id)
        resp.body = json.dumps(result, encoding='utf-8')

    
class ResetCache():
    
    def on_get(self,req, resp, userId):
        result = Mongo.resetCache(userId)
        resp.body = json.dumps(result, encoding='utf-8')
        
class UserDeals():
    def on_get(self,req,resp,userId):
        UserSpecificDeals.generateSheet(userId)
        json_docs = json.dumps({'True':'Sheet generated, mail sent.'}, default=json_util.default)
        resp.body = json.dumps(json_docs, encoding='utf-8')

class CommonUpdate():
    
    def on_post(self,req,resp):
        
        multi = req.get_param_as_int("multi")
        
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.updateCollection(result_json, multi)
        resp.body = json.dumps(result, encoding='utf-8')
        resp.content_type = "application/json; charset=utf-8"

class NegativeDeals():
    
    def on_get(self, req, resp):
        
        offset = req.get_param_as_int("offset")
        limit = req.get_param_as_int("limit")
        
        result = Mongo.getAllNegativeDeals(offset, limit)
        resp.body = dumps(result) 

    
    def on_post(self, req, resp):
        
        multi = req.get_param_as_int("multi")
        
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.addNegativeDeals(result_json, multi)
        resp.body = json.dumps(result, encoding='utf-8')

class ManualDeals():
    
    def on_get(self, req, resp):
        
        offset = req.get_param_as_int("offset")
        limit = req.get_param_as_int("limit")
        
        result = Mongo.getAllManualDeals(offset, limit)
        resp.body = dumps(result)

    
    def on_post(self, req, resp):
        
        multi = req.get_param_as_int("multi")
        
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.addManualDeal(result_json, multi)
        resp.body = json.dumps(result, encoding='utf-8')
        
class CommonDelete():
    
    def on_post(self,req,resp):
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.deleteDocument(result_json)
        resp.body = json.dumps(result, encoding='utf-8')
        resp.content_type = "application/json; charset=utf-8"

class SearchProduct():
    
    def on_get(self,req,resp):
        offset = req.get_param_as_int("offset")
        limit = req.get_param_as_int("limit")
        search_term = req.get_param("search")
        
        result = Mongo.searchMaster(offset, limit, search_term)
        resp.body = dumps(result) 

        
class FeaturedDeals():
    
    def on_get(self, req, resp):
        
        offset = req.get_param_as_int("offset")
        limit = req.get_param_as_int("limit")
        
        result = Mongo.getAllFeaturedDeals(offset, limit)
        resp.body = dumps(result)

    
    def on_post(self, req, resp):
        
        multi = req.get_param_as_int("multi")
        
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.addFeaturedDeal(result_json, multi)
        resp.body = json.dumps(result, encoding='utf-8')


class CommonSearch():
    
    def on_get(self,req,resp):
        class_name = req.get_param("class")
        sku = req.get_param_as_int("sku")
        skuBundleId = req.get_param_as_int("skuBundleId")

        result = Mongo.searchCollection(class_name, sku, skuBundleId)
        resp.body = dumps(result)

class CricScore():
    
    def on_get(self,req,resp):

        result = Mongo.getLiveCricScore()
        resp.body = dumps(result)

class Notification():
    
    def on_post(self, req, resp):
        
        try:
            result_json = json.loads(req.stream.read(), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')
            
        result = Mongo.addBundleToNotification(result_json)
        resp.body = json.dumps(result, encoding='utf-8')
    
    def on_get(self, req, resp):

        offset = req.get_param_as_int("offset")
        limit = req.get_param_as_int("limit")
        
        result = Mongo.getAllNotifications(offset, limit)
        resp.body = dumps(result)

class DealBrands():
    
    def on_get(self, req, resp):
        
        category_id = req.get_param_as_int("category_id")
        result = Mongo.getBrandsForFilter(category_id)
        resp.body = dumps(result)

class DealRank():
    
    def on_get(self, req, resp):
        identifier = req.get_param("identifier")
        source_id = req.get_param_as_int("source_id")
        user_id = req.get_param_as_int("user_id")
        result = Mongo.getDealRank(identifier, source_id, user_id)
        json_docs = json.dumps(result, default=json_util.default)
        resp.body = json_docs
        
    

class RetailerDetail():
    global RETAILER_DETAIL_CALL_COUNTER
    def getRetryRetailer(self,failback=True):
        retailer = None
        status = 'fretry' if self.callType == 'followup' else 'retry'
        try:
            retailer = session.query(Retailers).filter_by(status=status).filter(Retailers.next_call_time<=datetime.now()).order_by(Retailers.call_priority).order_by(Retailers.next_call_time).with_lockmode("update").first()
            if retailer is not None:
                lgr.info( "getRetryRetailer " + str(retailer.id))
            else:
                if failback:
                    retailer = self.getNewRetailer(False)
                    return retailer
            if status=='retry':
                retailer.status = 'assigned'
            else:
                retailer.status = 'fassigned'
            session.commit()
            lgr.info( "getRetryRetailer ", str(retailer.id))
        finally:
            session.close()
        return retailer
            
    def getNewRetailer(self,failback=True):
        retry = True
        retailer = None 
        try:
            while(retry):
                lgr.info( "Calltype " + self.callType)
                status=self.callType
                query = session.query(Retailers).filter(Retailers.status==status)
                if status=='fresh':
                    query = query.filter_by(is_or=False, is_std=False).filter(or_(Retailers.agent_id==self.agentId, Retailers.agent_id==None)).order_by(Retailers.is_elavated.desc(), -Retailers.agent_id)
                else:
                    query = query.filter(Retailers.next_call_time<=datetime.now())
                retailer = query.with_lockmode("update").first()
                if retailer is not None:
                    lgr.info( "retailer " +str(retailer.id))
                    if status=="fresh":
                        userquery = session.query(Users)
                        if retailer.contact2 is not None:
                            userquery = userquery.filter(Users.mobile_number.in_([retailer.contact1,retailer.contact2]))
                        else:
                            userquery = userquery.filter_by(mobile_number=retailer.contact1)
                        user = userquery.first()
                        if user is not None:
                            retailer.status = 'alreadyuser'
                            lgr.info( "retailer.status " + retailer.status)
                            session.commit()
                            continue
                        retailer.status = 'assigned'
                    else:
                        retailer.status = 'fassigned'
                    retailer.retry_count = 0
                    retailer.invalid_retry_count = 0
                    session.commit()
                    lgr.info( "Found Retailer " +  str(retailer.id) + " with status " + status + " assigned to " + str(self.agentId))
                        
                else:
                    lgr.info( "No fresh/followup retailers found")
                    if failback:
                        retailer = self.getRetryRetailer(False)
                        return retailer
                retry=False
        except:
            print traceback.print_exc()
        finally:
            session.close()
        return retailer
    
    def on_get(self, req, resp, agentId, callType=None, retailerId=None):
        global RETAILER_DETAIL_CALL_COUNTER
        RETAILER_DETAIL_CALL_COUNTER += 1
        lgr.info( "RETAILER_DETAIL_CALL_COUNTER " +  str(RETAILER_DETAIL_CALL_COUNTER))
        self.agentId = int(agentId)
        self.callType = callType
        if retailerId is not None:
            self.retailerId = int(retailerId)
            retailerLink = session.query(RetailerLinks).filter_by(retailer_id=self.retailerId).first()
            if retailerLink is not None:
                code = retailerLink.code
            else: 
                code = self.getCode()
                retailerLink = RetailerLinks()
                retailerLink.code = code
                retailerLink.is_activated = False
                retailerLink.agent_id = self.agentId
                retailerLink.retailer_id = self.retailerId
                
                activationCode=Activation_Codes()
                activationCode.code = code
                session.commit()
            session.close()
            resp.body =  json.dumps({"result":{"code":code,"link":make_tiny(code)}}, encoding='utf-8')
            return 
        retryFlag = False 
        agentId = int(agentId)
        if RETAILER_DETAIL_CALL_COUNTER % DEALER_RETRY_FACTOR ==0:
            retryFlag=True
        
        if retryFlag:
            retailer = self.getRetryRetailer()
        else:
            retailer = self.getNewRetailer()
        
        if retailer is None:
            resp.body = "{}"
        else:
            resp.body = json.dumps(todict(getRetailerObj(retailer)), encoding='utf-8')
        
    def on_post(self, req, resp, agentId, callType):
        returned = False
        self.agentId = int(agentId)
        self.callType = callType
        jsonReq = json.loads(req.stream.read(), encoding='utf-8')
        lgr.info( "Request ----\n"  + str(jsonReq))
        self.jsonReq = jsonReq
        invalidNumber = self.invalidNumber
        callLater = self.callLater
        alreadyUser = self.alReadyUser
        verifiedLinkSent = self.verifiedLinkSent
        
        self.retailerId = int(jsonReq.get('retailerid'))
        try:
            self.retailer = session.query(Retailers).filter_by(id=self.retailerId).first()
            self.callDisposition = jsonReq.get('calldispositiontype')
            self.callHistory = CallHistory()
            self.callHistory.agent_id=self.agentId
            self.callHistory.call_disposition = self.callDisposition
            self.callHistory.retailer_id=self.retailerId
            self.callHistory.call_type=self.callType
            self.callHistory.duration_sec = int(jsonReq.get("callduration"))
            self.callHistory.disposition_description = jsonReq.get('calldispositiondescritption')
            self.callHistory.disposition_comments = jsonReq.get('calldispositioncomments')
            lgr.info(self.callHistory.disposition_comments)
            self.callHistory.call_time = datetime.strptime(jsonReq.get("calltime"), '%d/%m/%Y %H:%M:%S')
            self.callHistory.mobile_number = jsonReq.get('number')
            self.callHistory.sms_verified = int(jsonReq.get("verified"))
            
            dispositionMap = {  'call_later':callLater,
                        'ringing_no_answer':callLater,
                        'not_reachable':callLater,
                        'switch_off':callLater,
                        'not_retailer':invalidNumber,
                        'invalid_no':invalidNumber,
                        'wrong_no':invalidNumber,
                        'hang_up':invalidNumber,
                        'retailer_not_interested':invalidNumber,
                        'recharge_retailer':invalidNumber,
                        'accessory_retailer':invalidNumber,
                        'service_center_retailer':invalidNumber,
                        'alreadyuser':alreadyUser,
                        'verified_link_sent':verifiedLinkSent
                      }
            returned = dispositionMap[jsonReq.get('calldispositiontype')]()
        finally:
            session.close()
        
        if returned:
            resp.body = "{\"result\":\"success\"}"
        else:
            resp.body = "{\"result\":\"failed\"}"

    def invalidNumber(self,):
        #self.retailer.status = 'retry' if self.callType == 'fresh' else 'fretry'
        if self.callDisposition == 'invalid_no':
            self.retailer.status='failed'
            self.callHistory.disposition_description = 'Invalid Number'
        elif self.callDisposition == 'wrong_no':
            self.retailer.status='failed'
            self.callHistory.disposition_description = 'Wrong Number'
        elif self.callDisposition == 'hang_up':
            self.retailer.status='failed'
            self.callHistory.disposition_description = 'Hang Up'
        elif self.callDisposition == 'retailer_not_interested':
            self.retailer.status='failed'
            if self.callHistory.disposition_description is None:
                self.callHistory.disposition_description = 'NA'
            self.callHistory.disposition_description = 'Reason Retailer Not Interested ' + self.callHistory.disposition_description
        elif self.callDisposition == 'recharge_retailer':
            self.retailer.status='failed'
            self.callHistory.disposition_description = 'Recharge related. Not a retailer '
        elif self.callDisposition == 'accessory_retailer':
            self.retailer.status='failed'
            self.callHistory.disposition_description = 'Accessory related. Not a retailer'
        elif self.callDisposition == 'service_center_retailer':
            self.retailer.status='failed'
            self.callHistory.disposition_description = 'Service Center related. Not a retailer'
        elif self.callDisposition == 'not_retailer':
            self.retailer.status='failed'
            self.callHistory.disposition_description = 'Not a retailer'    
        session.commit()
        return True   
        
    def getCode(self,):
        newCode = None
        lastLink = session.query(RetailerLinks).order_by(RetailerLinks.id.desc()).with_lockmode("update").first()
        if lastLink is not None:
            if len(lastLink.code)==len(codesys):
                newCode=lastLink.code
        return getNextCode(codesys, newCode)
    
    def callLater(self,):
        self.retailer.status = 'retry' if self.callType == 'fresh' else 'fretry'
        self.retailer.call_priority = None
        if self.callDisposition == 'call_later':
            if self.callHistory.disposition_description is not None:
                self.retailer.call_priority = 'user_initiated'
                self.retailer.next_call_time = datetime.strptime(self.callHistory.disposition_description, '%d/%m/%Y %H:%M:%S')
                self.callHistory.disposition_description = 'User requested to call on ' + self.callHistory.disposition_description
            else:
                self.retailer.call_priority = 'system_initiated'
                self.retailer.next_call_time = self.callHistory.call_time + timedelta(days=1)
                self.callHistory.disposition_description = 'Call scheduled on ' + datetime.strftime(self.retailer.next_call_time, '%d/%m/%Y %H:%M:%S')
        else: 
            if self.callDisposition == 'ringing_no_answer':
                if self.retailer.disposition == 'ringing_no_answer':
                    self.retailer.retry_count += 1
                else:
                    self.retailer.disposition = 'ringing_no_answer'
                    self.retailer.retry_count = 1
            else:
                if self.retailer.disposition == 'ringing_no_answer':
                    pass
                else:
                    self.retailer.disposition = 'not_reachable'
                self.retailer.retry_count += 1
                self.retailer.invalid_retry_count += 1
                    
            retryConfig = session.query(RetryConfig).filter_by(call_type=self.callType, disposition_type=self.retailer.disposition, retry_count=self.retailer.retry_count).first()
            if retryConfig is not None:
                self.retailer.next_call_time = self.callHistory.call_time + timedelta(minutes = retryConfig.minutes_ahead)
                self.callHistory.disposition_description = 'Call scheduled on ' + datetime.strftime(self.retailer.next_call_time, '%d/%m/%Y %H:%M:%S')
            else:
                self.retailer.status = 'failed'
                self.callHistory.disposition_description = 'Call failed as all attempts exhausted'
            
        session.commit()
        return True
            
            
    def alReadyUser(self,):
        self.retailer.status = self.callDisposition
        if self.callHistory.disposition_description is None:
            self.callHistory.disposition_description = 'Retailer already user' 
        session.commit()
        return True
    def verifiedLinkSent(self,):
        if self.callType == 'fresh':
            self.retailer.status = 'followup'
            self.retailer.next_call_time = self.callHistory.call_time + timedelta(days=1)
            self.callHistory.disposition_description = 'App link sent via ' + self.callHistory.disposition_description+ '. followup on' + datetime.strftime(self.retailer.next_call_time, '%d/%m/%Y %H:%M:%S') 
        else:
            self.retailer.next_call_time = self.callHistory.call_time + timedelta(days=7)
            self.callHistory.disposition_description = 'App link sent via' + self.callHistory.disposition_description + '. Followup again on ' + datetime.strftime(self.retailer.next_call_time, '%d/%m/%Y %H:%M:%S') 
        session.commit()
        return True

class Login():
    
    def on_get(self, req, resp, agentId, role):
        try:
            self.agentId = int(agentId)
            self.role = role
            print str(self.agentId) + self.role;
            agents=AgentLoginTimings()
            lastLoginTime = session.query(Agents).filter(Agents.id==self.agentId).first()
            print 'lastLogintime' + str(lastLoginTime)
            agents.loginTime=lastLoginTime.last_login
            agents.logoutTime=datetime.now()
            agents.role =self.role
            agents.agent_id = 2
            session.add(agents)    
            session.commit()
            resp.body =  json.dumps({"result":{"success":"true","message":"Success"}}, encoding='utf-8')
        finally:
            session.close()        
        
    def on_post(self,req,resp):
        try:
            jsonReq = json.loads(req.stream.read(), encoding='utf-8')
            lgr.info( "Request ----\n"  + str(jsonReq))
            email=jsonReq.get('email')
            password = jsonReq.get('password')
            role=jsonReq.get('role')    
            checkUser = session.query(Agents.id).filter(and_(Agents.email==email,Agents.password==password)).first()
            if checkUser is None:
                print checkUser
                resp.body =  json.dumps({"result":{"success":"false","message":"Invalid User"}}, encoding='utf-8')
            else:
                print checkUser[0]
                checkRole = session.query(Agent_Roles.id).filter(and_(Agent_Roles.agent_id==checkUser[0],Agent_Roles.role==role)).first()
                if checkRole is None:
                    resp.body =  json.dumps({"result":{"success":"false","message":"Invalid Role"}}, encoding='utf-8')
                else:
                    session.query(Agents).filter_by(id = checkUser[0]).update({"last_login":datetime.now()})
                    resp.body =  json.dumps({"result":{"success":"true","message":"Valid User","id":checkUser[0]}}, encoding='utf-8')
                    #session.query(Agents).filter_by(id = checkUser[0]).    
                    session.commit()
        finally:
            session.close()    
            
    def test(self,email,password,role):
        checkUser = session.query(Agents.id).filter(and_(Agents.email==email,Agents.password==password)).first()
        if checkUser is None:
            print checkUser

        else:
            print checkUser[0]
            checkRole = session.query(Agent_Roles.id).filter(and_(Agent_Roles.agent_id==checkUser[0],Agent_Roles.role==role)).first()
            if checkRole is None:
                pass
            else:
                agents=AgentLoginTimings()
                agents.loginTime=datetime.now()
                agents.logoutTime=datetime.now()
                agents.role =role
                agents.agent_id = 2
                #session.query(AgentLoginTimings).filter_by(id = checkUser[0]).update({"last_login":datetime.now()}, synchronize_session=False)
                session.add(agents)    
                session.commit()
                session.close()
                
                #session.query(Agents).filter(Agents.id==checkUser[0]).update({"last_login":Agents.last_login})
            
def todict(obj, classkey=None):
    if isinstance(obj, dict):
        data = {}
        for (k, v) in obj.items():
            data[k] = todict(v, classkey)
        return data
    elif hasattr(obj, "_ast"):
        return todict(obj._ast())
    elif hasattr(obj, "__iter__"):
        return [todict(v, classkey) for v in obj]
    elif hasattr(obj, "__dict__"):
        data = dict([(key, todict(value, classkey)) 
            for key, value in obj.__dict__.iteritems() 
            if not callable(value) and not key.startswith('_')])
        if classkey is not None and hasattr(obj, "__class__"):
            data[classkey] = obj.__class__.__name__
        return data
    else:
        return obj
    
def getRetailerObj(retailer):
    obj = Mock()
    obj.title = retailer.title
    obj.contact1 = retailer.contact1
    obj.contact2 = retailer.contact2
    obj.address = retailer.address
    obj.id = retailer.id
    obj.scheduled = (retailer.call_priority is not None)
    return obj

def make_tiny(code):
    url = 'https://play.google.com/store/apps/details?id=com.saholic.profittill&referrer=utm_source%3D0%26utm_medium%3DCRM%26utm_term%3D001%26utm_campaign%3D' + code
    request_url = ('http://tinyurl.com/api-create.php?' + urlencode({'url':url}))
    filehandle = urllib2.Request(request_url)
    x= urllib2.urlopen(filehandle)
    return str(x.read())


#def update_pin():
    
    
class Mock(object):
    pass

def main():
    print getNextCode(codesys, 'ZZ999')
    
if __name__ == '__main__':
    main()