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
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)
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
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
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)
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)
def countNewOffers(self, consumerId): ssConst = SSConst() cnt = ConsumerOffer.objects \ .filter(status=ssConst.CONSUMER_OFFER_STATUSES[0][0], consumerId=consumerId)\ .count() return cnt
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
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
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
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
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
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)
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
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 []
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
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
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
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
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()
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
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)
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)
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)
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
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)
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
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
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)
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)