예제 #1
0
    def getTxnAggSummary(self, merchantId, durationKey):
        try:
            ssConst = SSConst()
            txnAggSummaryMap = {
                'pk': 'id',
                'visits': 'visits',
                'spend': 'spend',
                'reviews': 'reviews',
                'reviewsAverage': 'reviewsAverage',
            }

            txnAggSummary = ConsumerTxn.objects.raw(
                '''
                                    select 1 as id, count(*) as total, sum(amtSpentSS) as spend
                                    from ss_consumer_txn where merchant_id=%s
                                    and created > %s and ssApproval='Approve'
                                    ''',
                [merchantId, ssConst.getStartTime(durationKey)],
                translations=txnAggSummaryMap)
            txnAggSum = {
                'visits': 0,
                'spend': 0,
                'reviews': 0,
                'reviewsAverage': 0,
            }
            for x in txnAggSummary:
                txnAggSum['visits'] = x.total
                txnAggSum['spend'] = x.spend
            reviewSum = self.getReviewSummary(
                merchantId, ssConst.getStartTime(durationKey))
            txnAggSum['reviews'] = reviewSum['total']
            txnAggSum['reviewsAverage'] = reviewSum['average']
            return txnAggSum
        except TxnReview.DoesNotExist:
            return None
예제 #2
0
def reviews(request, merchantId):
    try:
        ms = MerchantService();
        ssConst = SSConst()
        data = ms.getReviewSummary(merchantId, ssConst.getStartTime("all_time"))
        return JSONResponse(SSUtil.success(data), status=status.HTTP_200_OK)
    except:
        return JSONResponse(SSUtil.err("No reviews available"),
                                status=status.HTTP_400_BAD_REQUEST)
예제 #3
0
 def getPrefsJson(self, consumerId, cardId):
     consumerCard = None
     cacheService = CacheService()
     ssConst = SSConst()
     periodKeysJson = ssConst.getJson(ssConst.PERIOD_KEYS)
     txnTypesJson = ssConst.getJson(ssConst.TXN_TYPES)
     approvalTypeJson = ssConst.getJson(ssConst.APPROVAL_TYPES)
     try:
         consumerCard = ConsumerCard.objects.get(id=cardId)
     except ConsumerCard.DoesNotExist:
         raise Exception(SSException.CARD_NOT_PRESENT)
     prefsJson = {
         "txTypes": {
             "Online": 1,
             "International": 1
         },
         "limits": {
             "Daily": {
                 "userLimit": consumerCard.limit,
                 "action": "Block",
                 "maxLimit": consumerCard.limit
             },
             "Monthly": {
                 "userLimit": consumerCard.limit,
                 "action": "Block",
                 "maxLimit": consumerCard.limit
             },
         },
         "customLimits": []
     }
     if SSUtil.isIdinList(consumerCard.blockedTxTypes, "Online"):
         prefsJson["txTypes"]["Online"] = 0
     if SSUtil.isIdinList(consumerCard.blockedTxTypes, "International"):
         prefsJson["txTypes"]["International"] = 0
     prefs = cacheService.getConsumerPrefs(consumerId)
     if prefs:
         for pref in prefs:
             if str(pref.cardId) == str(cardId):
                 if pref.categoryKey == 'Any':
                     prefsJson["limits"][
                         pref.periodKey]["userLimit"] = pref.limit
                     prefsJson["limits"][
                         pref.periodKey]["action"] = pref.ssApproval
                 else:
                     customLimit = {}
                     if not customLimit.get(pref.periodKey):
                         customLimit[pref.periodKey] = {}
                     customLimit[pref.periodKey]["userLimit"] = pref.limit
                     customLimit[pref.periodKey]["action"] = pref.ssApproval
                     customLimit[
                         pref.periodKey]["categoryKey"] = pref.categoryKey
                     customLimit[
                         pref.periodKey]["maxLimit"] = consumerCard.limit
                     prefsJson["customLimits"].append(customLimit)
     return prefsJson
예제 #4
0
    def recordTxn(self, cardNum, txType, amount, mccCode, merchantUuid,
                  merchantName, txnApprovalVO):
        currTimeMillis = SSUtil.getMillis()
        ssConst = SSConst()
        cacheService = CacheService()
        merchServ = MerchantService()
        merchant = None
        print "inside record txn " + merchantUuid
        try:
            consumerCard = cacheService.getCardByNum(cardNum)
            category = cacheService.getCategoryByMccCode(mccCode)
            approvalTypeJson = ssConst.getJson(ssConst.APPROVAL_TYPES)
            try:
                merchant = cacheService.getMerchantByUuid(str(merchantUuid))
            except:
                merchant = merchServ.createMerchant(merchantUuid, merchantName,
                                                    None, None, mccCode)
            # Record transaction
            txn = ConsumerTxn()
            txn.consumerId = consumerCard.consumerId
            txn.cardId = consumerCard.id
            txn.txType = txType
            txn.txDate = currTimeMillis
            txn.amtSpentSS = amount
            txn.category_id = category.id
            txn.merchant_id = merchant.id
            txn.reviewStatus = merchant.reviewStatus
            txn.ssApproval = txnApprovalVO.approval
            # decide over the status
            if (txnApprovalVO.approval == 'Approve'
                    or txnApprovalVO.approval == 'Warn'):
                txn.ssApprovalStatus = ssConst.APPROVAL_STATUSES[0][0]
            if (txnApprovalVO.approval == 'Block'):
                txn.ssApprovalStatus = ssConst.APPROVAL_STATUSES[1][0]
            if (txnApprovalVO.approval == 'AskMe'):
                txn.ssApprovalStatus = ssConst.APPROVAL_STATUSES[2][0]

            txn.created = currTimeMillis
            txn.updated = currTimeMillis
            txn.save()

            #Establish relation with consumer and merchant
            merchServ.addConsumerRelation(merchant.id, consumerCard.consumerId)
            searchServ = SearchService()
            txnSerializer = ConsumerTxnSerializer(txn, many=False)
            if (txnApprovalVO.approval == 'Approve'
                    or txnApprovalVO.approval == 'Warn'):
                searchServ.upload("txn", txn.id, txnSerializer.data)
            return txn

        except Exception as e:
            print "Exception while recording txn " + e.message
            # actually log the fact that it has gone wrong
            pass
예제 #5
0
파일: tasks.py 프로젝트: awanishkeshav/ss
def asyncRecordTransaction(cardNum, amount, merchantUuid, merchantName, txType,
                           mccCode, txnApprovalVO, client):
    ssConst = SSConst()
    txnServ = TxnService()
    offerServ = OffersService()
    print "transaction recorded " + txnApprovalVO.to_JSON()
    approvalTypeJson = ssConst.getJson(ssConst.APPROVAL_TYPES)
    txn = txnServ.recordTxn(cardNum, txType, Decimal(amount), int(mccCode),
                            merchantUuid, merchantName, txnApprovalVO)
    merchant = Merchant.objects.get(pk=txn.merchant_id)

    print txnApprovalVO.approval + " ---- " + str(txn.cardId)

    if txnApprovalVO.sendNotif:
        screenMessage = ''
        try:
            notificationType = ssConst.DEVICE_NOTIFICATION_TYPES["Info"]
            msg = ""
            if txnApprovalVO.approval == 'Warn' or txnApprovalVO.approval == 'Approve':
                msg = txnApprovalVO.remarks
                if merchant.reviewStatus == 'RR':
                    notificationType = ssConst.DEVICE_NOTIFICATION_TYPES[
                        "ReviewRequired"]
            elif txnApprovalVO.approval == 'Block':
                # msg = "We denied a transaction on your card for Rs. "+str(amount) +"."
                msg = txnApprovalVO.remarks
                notificationType = ssConst.DEVICE_NOTIFICATION_TYPES["Block"]
            else:
                msg = "Approval required for " + ssConst.CURRENCY_SYMBOL + str(
                    amount) + " charge from " + merchant.name + "."
                notificationType = ssConst.DEVICE_NOTIFICATION_TYPES[
                    "ApprovalRequired"]
                screenMessage = txnApprovalVO.remarks
            consumerServ = ConsumerService()
            consumerDevice = consumerServ.getConsumerDevice(txn.consumerId)
            android = Android()
            android.sendTxnNotification(consumerDevice.deviceRegistrationId,
                                        msg, "Alert from " + client.name,
                                        notificationType, txn.id, txn.cardId,
                                        txnApprovalVO.approval, screenMessage)
        except Exception as e:
            print "Exception while sending communication " + e.message + " " + ssConst.APPROVAL_TYPES[
                0][0]

    # Aggregate Txn if it was approved
    txnServ.recalculateAgg(txn.consumerId, Decimal(amount), txn)

    # Process post_swipe_offer
    if txnApprovalVO.approval == 'Warn' or txnApprovalVO.approval == 'Approve':
        time.sleep(20)
        offerServ.processOfferNotification(txn.id,
                                           ssConst.OFFER_TARGET_TYPES[1][0],
                                           consumerDevice.deviceRegistrationId)
예제 #6
0
def validate(data):
    if 'cardNum' not in data or data['cardNum'] is None:
        raise Exception(SSException.CARD_NUM_MISSING)
    elif 'txType' not in data or data['txType'] is None:
        raise Exception(SSException.TXN_TYPE_MISSING)
    elif 'merchantUuid' not in data or data['merchantUuid'] is None:
        raise Exception(SSException.MERCHANT_ID_MISSING)
    elif 'mccCode' not in data or data['mccCode'] is None:
        raise Exception(SSException.MCC_CODE_MISSING)
    elif 'amount' not in data or data['amount'] is None:
        raise Exception(SSException.AMOUNT_MISSING)
    ssConst = SSConst()
    if not ssConst.isValidTxType(data['txType']):
        raise Exception(SSException.INVALID_TXN_TYPE)
예제 #7
0
 def countNewOffers(self, consumerId):
     ssConst = SSConst()
     cnt = ConsumerOffer.objects \
                        .filter(status=ssConst.CONSUMER_OFFER_STATUSES[0][0],
                                consumerId=consumerId)\
                        .count()
     return cnt
예제 #8
0
    def createMerchant(self, merchantUuid, merchantName, accessCode,
                       deviceRegistrationId, mccCode):
        currTimeMillis = SSUtil.getMillis()
        ssConst = SSConst()
        merchant = Merchant()
        if merchantName is None:
            merchantName = ''
        merchant.name = merchantName
        merchant.uuid = merchantUuid
        merchant.phone = ssConst.MERCHANT_DEFAULT_CONTACT_NUM
        merchant.address = ssConst.MERCHANT_DEFAULT_ADDRESS
        merchant.reviewStatus = ssConst.TXN_REVIEW_STATUSES[0][0]
        merchant.status = 1
        merchant.created = currTimeMillis
        merchant.updated = currTimeMillis
        merchant.installed = 1
        merchant.mccCode = mccCode
        if not accessCode is None:
            merchant.accessCode = accessCode
        if not deviceRegistrationId is None:
            merchant.deviceRegistrationId = deviceRegistrationId
            merchant.deviceType = 1
            merchant.deviceSubType = 1
        merchant.save()

        reviewTemplate = ReviewTemplate()
        reviewTemplate.criteria1 = "Overall Rating"
        reviewTemplate.merchant_id = merchant.id
        reviewTemplate.commentRequired = 1
        reviewTemplate.version = 1
        reviewTemplate.created = currTimeMillis
        reviewTemplate.updated = currTimeMillis
        reviewTemplate.save()

        return merchant
예제 #9
0
    def saveReviewResponse(self, reviewId, merchantComment, offerId):
        try:
            txnReview = TxnReview.objects.get(id=reviewId)
            txnReview.response = merchantComment
            if not offerId is None:
                txnReview.offerId = offerId
            txnReview.save()
            # Send notification to consumer
            try:
                ssConst = SSConst()
                txn = ConsumerTxn.objects.get(id=txnReview.txnId)
                consumerDevice = ConsumerDevice.objects.get(
                    consumerId=txn.consumerId)
                android = Android()
                merchant = Merchant.objects.get(id=txnReview.merchant_id)
                offer = None
                if not offerId is None:
                    offer = MerchantOffer.objects.get(id=offerId)
                android.sendMerchantResponse(
                    consumerDevice.deviceRegistrationId, merchantComment,
                    "Response from " + merchant.name,
                    ssConst.DEVICE_NOTIFICATION_TYPES["Offer"], offerId,
                    txnReview.merchant_id)
            except Exception as e:
                print e.message
                pass

            return txnReview
        except:
            return False
예제 #10
0
    def getOnDemandConsumerOffersByMerchant(self, consumerId, merchantId):
        ssConst = SSConst()
        txnService = TxnService()
        currTimeMillis = SSUtil.getMillis()
        merchantOffers = MerchantOffer.objects.filter(
            status=ssConst.OFFER_STATUSES[0][0], merchant_id=merchantId)
        miscDetails = txnService.getConsumerMerchantMiscDetails(
            consumerId, merchantId)
        for offer in merchantOffers:
            targettings = MerchantOfferTargetting.objects\
                                                 .all()\
                                                 .filter(offer_id=offer.id,
                                                         targetType = ssConst.OFFER_TARGET_TYPES[4][0])
            for targetting in targettings:
                if (int(miscDetails["totalOnMerchant"]) >= int(
                        targetting.minTotalSpend)
                        or int(miscDetails["visitsOnMerchant"]) >= int(
                            targetting.minVisits)):
                    self.addConsumerOfferIfRequired(consumerId, offer,
                                                    offer.merchant_id)


        consumerOffers = ConsumerOffer.objects \
                                     .filter(Q(status=ssConst.CONSUMER_OFFER_STATUSES[0][0])
                                      | Q(status=ssConst.CONSUMER_OFFER_STATUSES[1][0]),
                                      consumerId=consumerId, merchantId = merchantId
                                      , endDate__gt=currTimeMillis
                                      ).order_by("-updated")
        return consumerOffers
예제 #11
0
 def markConsumerOffersRead(self, consumerId):
     millis = SSUtil.getMillis()
     ssConst = SSConst()
     consumerOffer = ConsumerOffer.objects \
                                  .filter(status = ssConst.CONSUMER_OFFER_STATUSES[0][0],
                                   consumerId=consumerId) \
                                   .update(status = ssConst.CONSUMER_OFFER_STATUSES[1][0])
     return True
예제 #12
0
 def getConsumerOffers(self, consumerId):
     currTimeMillis = SSUtil.getMillis()
     ssConst = SSConst()
     consumerOffers = ConsumerOffer.objects \
                                   .filter(Q(status=ssConst.CONSUMER_OFFER_STATUSES[0][0])
                                    | Q(status=ssConst.CONSUMER_OFFER_STATUSES[1][0]),
                                    consumerId=consumerId, endDate__gt=currTimeMillis
                                    ).order_by("-updated")
     return consumerOffers
예제 #13
0
def getReviews(request):
    limit = 100
    start = 0
    duration = "all_time"
    if 'duration' in request.GET and not request.GET["duration"] is None and request.GET["duration"] != '':
        duration = request.GET["duration"]
    if 'limit' in request.GET and not request.GET["limit"] is None and request.GET["limit"] != '':
        limit = int(request.GET["limit"])
    if 'start' in request.GET and not request.GET["start"] is None and request.GET["start"] != '':
        start = int(request.GET["start"])
    try:
        ms = MerchantService();
        ssConst = SSConst()
        res = ms.getMerchantReviews(request.user.id, ssConst.getStartTime(duration), limit, start)
        serializer = TxnReviewSerializer(res, many=True)
        return JSONResponse(SSUtil.success(serializer.data), status=status.HTTP_200_OK)
    except:
        return JSONResponse(SSUtil.err("No reviews available"),
                                status=status.HTTP_400_BAD_REQUEST)
예제 #14
0
 def addOfferTargetting(self, offerId, targetType, minVisits,
                        minTotalSpend):
     currTimeMillis = SSUtil.getMillis()
     ssConst = SSConst()
     merchantOfferTargetting = None
     mot = MerchantOfferTargetting()
     mot.offer_id = offerId
     mot.targetType = targetType
     mot.minVisits = minVisits
     mot.minTotalSpend = minTotalSpend
     mot.created = currTimeMillis
     mot.updated = currTimeMillis
     mot.save()
     return mot
예제 #15
0
 def getOffers(self, merchantId, status):
     try:
         ssConst = SSConst()
         if status is None:
             offers = MerchantOffer.objects \
                                   .all() \
                                   .order_by('status','-updated') \
                                   .filter(~Q(status = ssConst.OFFER_STATUSES[2][0]),
                                    merchant_id=merchantId)
             print str(offers.query)
         else:
             offers = MerchantOffer.objects.all().order_by(
                 'status', '-updated').filter(merchant_id=merchantId,
                                              status=status)
         return offers
     except MerchantOffer.DoesNotExist:
         return []
예제 #16
0
 def registerMerchant(self, merchantUuid, accessCode):
     currTimeMillis = SSUtil.getMillis()
     ssConst = SSConst()
     merchant = None
     try:
         merchant = Merchant.objects.get(uuid=merchantUuid,
                                         accessCode=accessCode)
         if merchant is None:
             raise Exception("Invalid combination of ID and Access Code")
         elif merchant.installed is 0:
             merchant.installed = 1
             merchant.save()
         else:
             pass
     except Merchant.DoesNotExist:
         raise Exception("Invalid combination of ID and Access Code")
     return merchant
예제 #17
0
 def updateMerchant(self, merchantId, name, description, businessHours):
     currTimeMillis = SSUtil.getMillis()
     ssConst = SSConst()
     merchant = None
     try:
         merchant = Merchant.objects.get(id=merchantId)
         if not name is None:
             merchant.name = name
         if not description is None:
             merchant.description = description
         if not businessHours is None:
             merchant.businessHours = businessHours
         merchant.uodated = currTimeMillis
         merchant.save()
     except Merchant.DoesNotExist:
         raise Exception("Invalid merchant")
     return merchant
예제 #18
0
 def updateOffer(self, offerId, title, description, code, codeType,
                 endDate):
     currTimeMillis = SSUtil.getMillis()
     ssConst = SSConst()
     merchantOffer = None
     try:
         merchantOffer = MerchantOffer.objects.get(id=offerId)
     except:
         msg = "Offer does not exist for id " + offerId
         raise Exception(msg)
     merchantOffer.title = title
     merchantOffer.description = description
     merchantOffer.endDate = endDate
     merchantOffer.codeType = codeType
     merchantOffer.code = code
     merchantOffer.updated = currTimeMillis
     merchantOffer.save()
     return merchantOffer
예제 #19
0
    def processOfferNotification(self, txnId, targetType,
                                 deviceRegistrationId):
        millis = SSUtil.getMillis()
        ssConst = SSConst()
        txnService = TxnService()
        android = Android()
        consumerServ = ConsumerService()

        txn = ConsumerTxn.objects.get(id=txnId)
        if deviceRegistrationId is None:
            consumerDevice = consumerServ.getConsumerDevice(txn.consumerId)
            deviceRegistrationId = consumerDevice.deviceRegistrationId
        miscDetails = txnService.getTxnMiscDetails(txn.consumerId, txn.cardId,
                                                   txn.id)
        # Get the merchant
        merchant = Merchant.objects.get(id=txn.merchant_id)

        # Get the offers for that merchant
        offers = MerchantOffer.objects.all().filter(
            merchant_id=txn.merchant_id, status=ssConst.OFFER_STATUSES[0][0])

        # Check targetting for these offers
        notificationSent = False
        for offer in offers:
            targettings = MerchantOfferTargetting.objects.all().filter(
                offer_id=offer.id)
            for targetting in targettings:
                if targetting.targetType == targetType:
                    # check if consumer qualifies for the offer
                    if (int(miscDetails["totalOnMerchant"]) >= int(
                            targetting.minTotalSpend)
                            or int(miscDetails["visitsOnMerchant"]) >= int(
                                targetting.minVisits)):
                        self.addConsumerOfferIfRequired(
                            txn.consumerId, offer, merchant.id)
                        # Send only one notification
                        if not notificationSent:
                            android.sendOfferNotification(
                                deviceRegistrationId, offer.title,
                                "Offer from " + merchant.name,
                                ssConst.DEVICE_NOTIFICATION_TYPES["Offer"],
                                offer.id, merchant.id)
                            notificationSent = True
예제 #20
0
 def addConsumerOfferIfRequired(self, consumerId, offer, merchantId):
     millis = SSUtil.getMillis()
     ssConst = SSConst()
     consumerOffer = None
     try:
         consumerOffer = ConsumerOffer.objects.get(consumerId=consumerId,
                                                   offer_id=offer.id)
     except ConsumerOffer.DoesNotExist:
         if consumerOffer is None:
             consumerOffer = ConsumerOffer()
             consumerOffer.created = millis
             consumerOffer.updated = millis
             consumerOffer.offer_id = offer.id
             consumerOffer.merchantId = merchantId
             consumerOffer.consumerId = consumerId
             consumerOffer.status = ssConst.CONSUMER_OFFER_STATUSES[0][0]
             consumerOffer.startDate = offer.startDate
             consumerOffer.endDate = offer.endDate
             consumerOffer.save()
예제 #21
0
 def markOfferStatus(self, offerId, status):
     currTimeMillis = SSUtil.getMillis()
     ssConst = SSConst()
     merchantOffer = None
     try:
         merchantOffer = MerchantOffer.objects.get(id=offerId)
     except:
         msg = "Offer does not exist for id " + offerId
         raise Exception(msg)
     merchantOffer.status = status
     merchantOffer.updated = currTimeMillis
     merchantOffer.save()
     # if status is archived or suspended then mark them so
     # in consumer offer
     if status != ssConst.OFFER_STATUSES[0][0]:
         ConsumerOffer.objects\
                      .filter(offer_id=offerId)\
                      .update(status=ssConst.CONSUMER_OFFER_STATUSES[2][0])
     return merchantOffer
예제 #22
0
def saveApproval(request, txnId):
    ssConst = SSConst()
    millis = SSUtil.getMillis()
    data = json.loads(request.body)
    try:
        if data['approval'] is None:
            raise Exception()
    except Exception as e:
        return JSONResponse(SSUtil.err(e.message),
                            status=status.HTTP_412_PRECONDITION_FAILED)
    try:
        txn = ConsumerTxn.objects.get(pk=txnId)
        if data['approval'] == str(1):
            txn.ssApprovalStatus = ssConst.APPROVAL_STATUSES[3][0]
        else:
            txn.ssApprovalStatus = ssConst.APPROVAL_STATUSES[4][0]
        txn.updated = millis
        txn.save()
        return Response(SSUtil.success(1), status=status.HTTP_200_OK)
    except:
        return JSONResponse(SSUtil.err(SSException.INVALID_INPUT),
                            status=status.HTTP_400_BAD_REQUEST)
예제 #23
0
 def processOffersForExistingConsumers(self):
     ssConst = SSConst()
     txnService = TxnService()
     merchantOffers = MerchantOffer.objects.filter(
         status=ssConst.OFFER_STATUSES[0][0])
     for offer in merchantOffers:
         consumerMerchants = ConsumerMerchant.objects.filter(
             merchant_id=offer.merchant_id)
         for cm in consumerMerchants:
             miscDetails = txnService.getConsumerMerchantMiscDetails(
                 cm.consumerId, offer.merchant_id)
             targettings = MerchantOfferTargetting.objects\
                                              .all()\
                                              .filter(offer_id=offer.id,
                                                      targetType = ssConst.OFFER_TARGET_TYPES[3][0])
             for targetting in targettings:
                 if (int(miscDetails["totalOnMerchant"]) >= int(
                         targetting.minTotalSpend)
                         or int(miscDetails["visitsOnMerchant"]) >= int(
                             targetting.minVisits)):
                     self.addConsumerOfferIfRequired(
                         cm.consumerId, offer, offer.merchant_id)
예제 #24
0
def addOfferTargetting(request, offerId):
    ssConst = SSConst()
    ms = MerchantService()
    data = json.loads(request.body)
    targetType = None
    minVisits = 0
    minTotalSpend = 0
    if 'targetType' in data and not data['targetType'] is None:
        targetType = data['targetType']
    else:
        targetType = ssConst.OFFER_TARGET_TYPES[3][0]
    if 'minVisits' in data and not data['minVisits'] is None:
        minVisits = data['minVisits']
    if 'minTotalSpend' in data and not data['minTotalSpend'] is None:
        minTotalSpend = data['minTotalSpend']
    try:
        ser = MerchantOfferTargettingSerializer(ms.addOfferTargetting(offerId,targetType,
                        minVisits,minTotalSpend))
        return JSONResponse(SSUtil.success(ser.data), status=status.HTTP_200_OK)
    except:
        return JSONResponse(SSUtil.err(SSException.PROCESSING_FAILED),
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)
예제 #25
0
    def getConsumerMerchantSummary(self, merchantId, consumerId):
        try:
            ssConst = SSConst()
            consumerMerchantSummaryMap = {
                'pk': 'id',
                'visits': 'visits',
                'spend': 'spend',
            }

            consumerMerchantSummary = ConsumerTxn.objects.raw(
                '''
                                    select 1 as id, count(*) as total, sum(amtSpentSS) as spend
                                    from ss_consumer_txn where merchant_id=%s
                                    and consumerId = %s and ssApproval='Approve'
                                    ''', [merchantId, consumerId],
                translations=consumerMerchantSummaryMap)
            consumerMerchantSum = {'visits': 0, 'spend': 0}
            for x in consumerMerchantSummary:
                consumerMerchantSum['visits'] = x.total
                consumerMerchantSum['spend'] = x.spend
            return consumerMerchantSum
        except ConsumerTxn.DoesNotExist:
            return None
예제 #26
0
def review(request, txnId):
    if request.method == 'GET':
        try:
            ms = MerchantService();
            serializer = TxnReviewSerializer(ms.getReview(txnId), many=False)
            return JSONResponse(SSUtil.success(serializer.data), status=status.HTTP_200_OK)
        except:
            return JSONResponse(SSUtil.err("No reviews available"),
                                    status=status.HTTP_400_BAD_REQUEST)
    else:
        try:
            comment=None
            ms = MerchantService();
            data = json.loads(request.body)
            if not 'criteria1' in data or data['criteria1'] is None:
                return JSONResponse(SSUtil.err("Criteria1 is required"),
                                    status=status.HTTP_412_PRECONDITION_FAILED)
            if not 'criteria2' in data or data['criteria2'] is None:
                return JSONResponse(SSUtil.err("Criteria2 is required"),
                                    status=status.HTTP_412_PRECONDITION_FAILED)
            if not 'criteria3' in data or data['criteria3'] is None:
                return JSONResponse(SSUtil.err("Criteria3 is required"))
            if not 'comment' in data or data['comment'] is None:
                comment=None
            else:
                comment = data['comment']
            try:
                consumerTxn = ms.saveReview(txnId, data['criteria1'], data['criteria2'], data['criteria3'], comment)
                offersServ = OffersService()
                ssConst = SSConst()
                offersServ.processOfferNotification(consumerTxn.id, ssConst.OFFER_TARGET_TYPES[2][0], None)
                return JSONResponse(SSUtil.success(True), status=status.HTTP_200_OK)
            except:
                return JSONResponse(SSUtil.err(SSException.NO_REVIEW_TEMPLATE), status=status.HTTP_400_BAD_REQUEST)
        except:
            return JSONResponse(SSUtil.err(SSException.INVALID_INPUT),
                                status=status.HTTP_400_BAD_REQUEST)
예제 #27
0
    def saveReview(self, txnId, criteria1Value, criteria2Value, criteria3Value,
                   comment):
        millis = SSUtil.getMillis()
        ssConst = SSConst()
        consumerTxn = ConsumerTxn.objects.get(id=txnId)
        reviewTemplate = None

        try:
            reviewTemplate = ReviewTemplate.objects.get(
                merchant_id=consumerTxn.merchant_id)
        except reviewTemplate.DoesNotExist:
            raise Exception(SSException.NO_REVIEW_TEMPLATE)
        txnReview = TxnReview()
        try:
            txnReview = TxnReview.objects.get(txnId=txnId)
        except TxnReview.DoesNotExist:
            txnReview = TxnReview()
            txnReview.txnId = txnId
            txnReview.merchant_id = consumerTxn.merchant_id
            txnReview.criteria1 = reviewTemplate.criteria1
            txnReview.criteria2 = reviewTemplate.criteria2
            txnReview.criteria3 = reviewTemplate.criteria3
            txnReview.created = millis
            if comment is None:
                comment = 'No comments provided.'
        txnReview.criteria1Value = criteria1Value
        txnReview.criteria2Value = criteria2Value
        txnReview.criteria3Value = criteria3Value
        txnReview.updated = millis
        if not comment is None:
            txnReview.comment = comment
        txnReview.save()
        consumerTxn.review = round(
            (criteria1Value + criteria2Value + criteria3Value) / 3.0)
        consumerTxn.reviewStatus = ssConst.TXN_REVIEW_STATUSES[2][0]
        consumerTxn.save()
        return consumerTxn
예제 #28
0
 def addOffer(self, merchantId, title, description, code, codeType, endDate,
              categoryId, imgUrl):
     currTimeMillis = SSUtil.getMillis()
     ssConst = SSConst()
     merchantOffer = MerchantOffer()
     merchantOffer.title = title
     merchantOffer.description = description
     if not endDate is None:
         merchantOffer.endDate = int(endDate)
     merchantOffer.startDate = currTimeMillis
     merchantOffer.codeType = codeType
     merchantOffer.code = code
     merchantOffer.merchant_id = merchantId
     if categoryId is None:
         merchant = Merchant.objects.get(id=merchantId)
         category = TxnCategory.objects.get(mccCode=merchant.mccCode)
         categoryId = category.id
     merchantOffer.category_id = categoryId
     merchantOffer.status = ssConst.OFFER_STATUSES[0][0]
     merchantOffer.imgUrl = imgUrl
     merchantOffer.created = currTimeMillis
     merchantOffer.updated = currTimeMillis
     merchantOffer.save()
     return merchantOffer
예제 #29
0
    def recalculateAgg(self, consumerId, recentAmount, recentTxn):
        currTimeMillis = SSUtil.getMillis()
        ssConst = SSConst()
        cacheService = CacheService()
        prefs = cacheService.getConsumerPrefs(consumerId)
        name_map = {'total': 'total', 'pk': 'id'}
        periodKeysJson = ssConst.getJson(ssConst.PERIOD_KEYS)
        approvalTypeJson = ssConst.getJson(ssConst.APPROVAL_TYPES)
        if prefs:
            for pref in prefs:
                consumerAgg = ConsumerAgg()

                querySt = "select sum(amtSpentSS) as total, 1 as id from ss_consumer_txn where consumerId =" + str(
                    consumerId)
                querySt += " and ssApproval='" + ssConst.APPROVAL_TYPES[0][
                    0] + "'"
                if pref.periodKey != 'Any':
                    print "period key is " + pref.periodKey
                    print " value is " + periodKeysJson[pref.periodKey]
                    querySt += " and  FROM_UNIXTIME(created/1000) >= DATE_SUB(FROM_UNIXTIME(" + str(
                        currTimeMillis / 1000
                    ) + "), INTERVAL " + periodKeysJson[pref.periodKey] + ")"
                if pref.categoryKey != 'Any':
                    category = TxnCategory.objects.get(name=pref.categoryKey)
                    querySt += " and  category_id = " + str(category.id)
                if pref.txType != 'Any':
                    querySt += " and  txType = '" + pref.txType + "'"
                if pref.cardId != -1:
                    querySt += " and  cardId = " + str(pref.cardId)
                if pref.merchantId != -1:
                    querySt += " and  merchant_id = " + str(pref.merchantId)
                print querySt
                res = ConsumerTxn.objects.raw(querySt, translations=name_map)
                total = 0
                for x in res:
                    total = x.total
                if total == None:
                    total = 0
                print total
                # check if aggregate exists for this pref
                print str(consumerId) + str(
                    pref.cardId
                ) + pref.periodKey + " " + pref.categoryKey + " " + pref.txType + " " + str(
                    pref.merchantId)
                try:
                    consumerAgg = ConsumerAgg.objects.get(
                        consumerId=consumerId,
                        cardId=pref.cardId,
                        periodKey=pref.periodKey,
                        categoryKey=pref.categoryKey,
                        txType=pref.txType,
                        merchantId=pref.merchantId)
                    print "Got consumer agg " + str(total)
                except ConsumerAgg.DoesNotExist:
                    consumerAgg.periodKey = pref.periodKey
                    consumerAgg.categoryKey = pref.categoryKey
                    consumerAgg.txType = pref.txType
                    consumerAgg.cardId = pref.cardId
                    consumerAgg.merchantId = pref.merchantId
                    consumerAgg.consumerId = pref.consumerId
                    consumerAgg.created = currTimeMillis
                consumerAgg.amtSpentSS = total
                consumerAgg.updated = currTimeMillis
                consumerAgg.save()

        cacheService.setConsumerAggs(consumerId)
        #fix balance now
        if not recentTxn is None:
            if recentTxn.ssApproval == ssConst.APPROVAL_TYPES[0][0]:
                card = ConsumerCard.objects.get(id=recentTxn.cardId)
                card.amtSpentSS = card.amtSpentSS + recentAmount
                card.currOS = card.currOS + recentAmount
                card.avaialbleLimit = card.limit - card.currOS
                card.updated = currTimeMillis
                card.save()
                cacheService.setCard(card.id)
예제 #30
0
    def getApproval(self, cardNum, amount, merchantUuid, merchantName, txType,
                    mccCode):
        ssConst = SSConst()
        consumerCard = None
        consumer = None
        category = None
        prefs = None
        aggs = None
        merchant = None
        millis = SSUtil.getMillis()
        cacheService = CacheService()
        cardService = CardService()
        approvalTypeJson = ssConst.getJson(ssConst.APPROVAL_TYPES)
        print "1"
        # Check if card exists
        try:
            consumerCard = cacheService.getCardByNum(cardNum)
        except Exception as e:
            return TxnValidationVO(False, False, 'Block',
                                   SSException.INVALID_CARD, False)
        print "1.5 " + str(consumerCard.blockedTxTypes)

        if SSUtil.isIdinList(consumerCard.blockedTxTypes, txType):
            return TxnValidationVO(False, True, 'Block',
                                   txType + " transactions are disabled.",
                                   True)

        print "2"
        try:
            merchant = cacheService.getMerchantByUuid(merchantUuid)
        except Exception as e:
            pass
        print "3"

        # Check if card is blocked
        if consumerCard.status == 0:
            return TxnValidationVO(False, True, 'Block',
                                   "Your card is blocked.", True)

        print "4"

        # By any chance the category is not in our records, go back,
        # Also need this for previous txn
        try:
            category = cacheService.getCategoryByMccCode(mccCode)
        except TxnCategory.DoesNotExist:
            return TxnValidationVO(False, False, 'Block', "Unknown category.",
                                   False)
        print "5"

        # if it was tried in last 10 minutes and user approved it - go ahead
        try:
            if not merchant is None:
                maxAllowedCreatedTime = millis - ssConst.ALLOWED_MILLIS_FOR_RETRY
                qs = ConsumerTxn.objects.all().filter(
                    consumerId=consumerCard.consumerId,
                    cardId=consumerCard.id,
                    txType__endswith=txType,
                    category_id=category.id,
                    merchant_id=merchant.id,
                    amtSpentSS=amount,
                    created__gt=maxAllowedCreatedTime).order_by('-created')[:1]
                consumerTxn = qs[0]
                if not consumerTxn is None and consumerTxn.ssApprovalStatus == ssConst.APPROVAL_STATUSES[
                        3][0]:
                    return TxnValidationVO(
                        True, True, 'Approve',
                        "We approved a transaction on your card for " +
                        ssConst.CURRENCY_SYMBOL + str(amount) + ".", True)
        except Exception as e:
            print "Error while matching transaction " + e.message
            pass
        print "6"

        # No point in moving further if the consumer doesn't exist, but don't record it for now
        try:
            consumer = cacheService.getConsumerById(consumerCard.consumerId)
        except Consumer.DoesNotExist:
            return TxnValidationVO(False, False, 'Block',
                                   SSException.INVALID_USER, False)
        print "7"

        # Check if merchant is blocked
        print "blocked merchants are  " + consumer.blockedMerchants
        if not merchant is None:
            if SSUtil.isIdinList(consumer.blockedMerchants, merchant.id):
                return TxnValidationVO(
                    False, True, 'Block',
                    "You have blocked all transactions from Merchant \"" +
                    merchant.name + "\"", True)
        print "8"

        # Now check the aggregates and preferences
        prefs = cacheService.getConsumerPrefs(consumer.id)
        if not prefs:
            cardService.createDefaultPrefsAndAggs(consumerCard)
        print "9"

        aggs = cacheService.getConsumerAggs(consumer.id)
        if not aggs:
            #TODO:  If user has no aggregates then no point in holding it - we just tried creating
            return TxnValidationVO(
                True, True, 'Block',
                "Internal server error - No aggregates available for the user. ",
                False)
        for pref in prefs:
            #Ignore the preferences which are of no use for this transaction
            if pref.categoryKey != 'Any' and pref.categoryKey != category.name:
                continue
            if pref.txType != 'Any' and pref.txType != txType:
                continue
            if not merchant is None and pref.merchantId != -1 and pref.merchantId != merchant.id:
                continue
            if pref.cardId != -1 and pref.cardId != consumerCard.id:
                continue

            # Compare matching aggs for the rest of the preferences
            for agg in aggs:
                if pref.periodKey == agg.periodKey and pref.categoryKey == agg.categoryKey and pref.txType == agg.txType and agg.merchantId == pref.merchantId and agg.cardId == pref.cardId:
                    if pref.limit < (agg.amtSpentSS + Decimal(amount)):
                        if pref.ssApproval == 'Block' or pref.ssApproval == 'AskMe':
                            msgToUser = "******" + pref.periodKey.lower(
                            ) + " spend limit of  " + ssConst.CURRENCY_SYMBOL + str(
                                pref.limit)
                            if pref.categoryKey != 'Any':
                                msgToUser = msgToUser + " for " + pref.categoryKey
                            msgToUser = msgToUser + "."
                            return TxnValidationVO(False, True,
                                                   pref.ssApproval, msgToUser,
                                                   True)
        print "10"

        return TxnValidationVO(
            True, True, 'Approve', "We approved a " + ssConst.CURRENCY_SYMBOL +
            str(amount) + " charge from " + merchantName + ".", True)