UNPKG

@magic.batua/points

Version:

The Points module powers the loyalty points features of the Magic Batua platform.

173 lines 7.01 kB
"use strict"; /** * @module @magic.batua/points * @overview Defines the `Ledger` class that manages loyalty points logic across the * application. * * @author Animesh Mishra <hello@animesh.ltd> * @copyright © 2018 Animesh Ltd. All Rights Reserved. */ Object.defineProperty(exports, "__esModule", { value: true }); const Points = require("./Source/Points"); exports.Points = Points; const error_1 = require("@magic.batua/error"); const error_2 = require("@magic.batua/error"); const Transaction_1 = require("./Source/Transaction"); exports.Transaction = Transaction_1.Transaction; /** * The Points Ledger keeps track of a user's Magic Points, their status, their availability * and other points related arithmetic. * * Magic Points are awarded to users as rewards for continued usage and word-of-mouth publicity. * The points are rewarded as following: * * - 600 points at signup. These points aren't redeemable until you've spent ₹1,000 or more on the * Magic Batua platform. * * - 400 points if somebody signs up using your referral code. These points become redeemable once * you've amassed 10 or more referrals, and each of those referrals have spent ₹1,000 or more. * * - 1 point for mobile recharge. Redeemable immediately. If were referred by someone, their account * is credited with a point too. * * - 20 points for tuition fee payments. Redeemable immediately. If were referred by someone, their * account is credited with 20 points too. * * To manage the points logic, we make use of three buckets: Signup, Referrals and Available. As points * earned through Signup and Referrals become redeemable they are emptied into the Available bucket. * Points earned through other activities such as mobile recharge or tuition fee payment are credited to * the Available bucket straightaway. */ class Ledger { constructor(transactions) { /** Number of points available for redemption */ this.available = 0; /** * Points earned at signup. Becomes redeemable once the account has spent * ₹1,000 or more on the Magic Batua platform. */ this.signup = 0; /** * Points earned through referrals. Becomes redeemable once the account has accrued * 10 or more referrals. */ this.referral = 0; /** Number of points accured since the creation of account */ this.redeemable = 0; /** Points that have expired. */ this.expired = 0; /** Points that have been redeemed since the creation of account */ this.redeemed = 0; /** Points that have been refunded */ this.refunded = 0; /** Points transactions listing all the issuance, redemption and refund transactions. */ this.transactions = new Array(); for (var entry of transactions) { this.transactions.push(new Transaction_1.Transaction(entry)); } // Count all points this.count(); } /** * Goes over all point transactions one by one and separates all the points * in their respective baskets. * * @param transactions An array of Points `Transaction` */ count() { this.signup = 0; this.referral = 0; this.expired = 0; this.redeemable = 0; this.refunded = 0; this.redeemed = 0; for (var transaction of this.transactions) { switch (transaction.type) { case "Issue": if (transaction.expiryDate.valueOf() <= Date.now()) { this.expired += transaction.points; break; } if (transaction.notes == "Signup") { this.signup += transaction.points; break; } if (transaction.notes == "Referral") { this.referral += transaction.points; break; } else { this.redeemable += transaction.points; break; } case "Redeem": this.redeemed += transaction.points; break; case "Refund": this.refunded += transaction.points; } } this.available = this.redeemable - this.redeemed; } /** Issues a Magic Point for the given `reason` */ Issue(points, reason) { let transaction = new Transaction_1.Transaction({ points: points, type: "Issue", notes: reason }); // Add this transaction to the transactions array and count // the points again this.transactions.push(transaction); this.count(); return transaction; } /** Redeems `points` from the balance */ Redeem(points, reason) { if (points > this.available) { throw new error_1.ClientError(error_2.Code.BadRequest, "Trying to redeem " + points + " points, but the account has " + this.redeemable + " redeemable points only."); } let transaction = new Transaction_1.Transaction({ points: points, type: "Redeem", notes: reason }); // Add this transaction to the transactions array and count // the points again this.transactions.push(transaction); this.count(); return transaction; } /** * This method will be called by the `Account` module when the condition for * unlocking signup bonus is met. * To move points from Signup bucket `this.signup` to Redeemable bucket `this.redeemable`, * we change the `notes` property of signup points issuance from "Signup" to * "Signup Points become active". */ MakeSignupRedeemable() { for (var transaction of this.transactions) { if (transaction.notes == "Signup" && transaction.expiryDate.valueOf() >= Date.now()) { transaction.notes = "Signup points can be redeemed now."; } } this.count(); } /** * This method will be called by the `Account` module when the condition for * unlocking signup bonus is met. * To move points from Referrals bucket `this.signup` to Redeemable bucket `this.redeemable`, * we change the `notes` property of signup points issuance from "Signup" to * "Referral points can be redeemed now.". */ MakeReferralsRedeemable() { for (var transaction of this.transactions) { if (transaction.notes == "Referral" && transaction.expiryDate.valueOf() >= Date.now()) { transaction.notes = "Referral points can now be redeemed."; } } this.count(); } } exports.Ledger = Ledger; //# sourceMappingURL=index.js.map