diff --git a/src/shared/rules.ts b/src/shared/rules.ts new file mode 100644 index 0000000..481e066 --- /dev/null +++ b/src/shared/rules.ts @@ -0,0 +1,11 @@ +import _ from 'lodash'; + +type RuleResult = number | false | undefined; + +export const getMinimumRuleOutput = async ( + rules: ((input: T) => RuleResult | Promise)[], + input: T, +) => { + const results = await Promise.all(rules.map((rule) => rule(input))); + return Math.min(..._.compact(results)); +}; diff --git a/src/transaction/transaction.controller.spec.ts b/src/transaction/transaction.controller.spec.ts index 91a424a..6849cb2 100644 --- a/src/transaction/transaction.controller.spec.ts +++ b/src/transaction/transaction.controller.spec.ts @@ -71,91 +71,55 @@ describe('TransactionController Unit Tests', () => { it('calling applyRules method minimum result of applied rules should be got', async () => { { - const result = await transactionController.applyRules( - [ - transactionController.discountRule, - transactionController.turnoverRule, - ], - { - base_amount: 1000, - client_id: 1, - }, - ); + const result = await transactionController.applyRules({ + base_amount: 1000, + client_id: 1, + }); expect(result).to.eql(5); } { - const result = await transactionController.applyRules( - [ - transactionController.discountRule, - transactionController.turnoverRule, - ], - { - base_amount: 1, - client_id: 1, - }, - ); + const result = await transactionController.applyRules({ + base_amount: 1, + client_id: 1, + }); expect(result).to.eql(0.05); } { - const result = await transactionController.applyRules( - [ - transactionController.discountRule, - transactionController.turnoverRule, - ], - { - base_amount: 1000, - client_id: 42, - }, - ); + const result = await transactionController.applyRules({ + base_amount: 1000, + client_id: 42, + }); expect(result).to.eql(0.03); } { - const result = await transactionController.applyRules( - [ - transactionController.discountRule, - transactionController.turnoverRule, - ], - { - base_amount: 1, - client_id: 42, - }, - ); + const result = await transactionController.applyRules({ + base_amount: 1, + client_id: 42, + }); expect(result).to.eql(0.03); } { - const result = await transactionController.applyRules( - [ - transactionController.discountRule, - transactionController.turnoverRule, - ], - { - base_amount: 1000, - client_id: 99, - }, - ); + const result = await transactionController.applyRules({ + base_amount: 1000, + client_id: 99, + }); expect(result).to.eql(0.03); } { - const result = await transactionController.applyRules( - [ - transactionController.discountRule, - transactionController.turnoverRule, - ], - { - base_amount: 1, - client_id: 99, - }, - ); + const result = await transactionController.applyRules({ + base_amount: 1, + client_id: 99, + }); expect(result).to.eql(0.03); } diff --git a/src/transaction/transaction.controller.ts b/src/transaction/transaction.controller.ts index 0a8c5ca..e044b34 100644 --- a/src/transaction/transaction.controller.ts +++ b/src/transaction/transaction.controller.ts @@ -1,5 +1,4 @@ import { Controller, Post, UsePipes, Body } from '@nestjs/common'; -import _ from 'lodash'; import { ExchangeRateInput, ExchangeRateResponse, @@ -17,6 +16,7 @@ import { HighTurnoverDiscount, } from './transaction.dto'; import { Transaction } from './transaction.entity'; +import { getMinimumRuleOutput } from 'src/shared/rules'; type TransactionRuleData = Pick; @@ -90,16 +90,11 @@ export class TransactionController { : commissionAmount; } - async applyRules( - rules: (( - transactionInput: TransactionRuleData, - ) => number | false | undefined | Promise)[], - transactionInput: TransactionRuleData, - ) { - const commissions = await Promise.all( - [...rules, this.defaultRule].map((rule) => rule(transactionInput)), + async applyRules(transactionInput: TransactionRuleData) { + return getMinimumRuleOutput( + [this.turnoverRule, this.discountRule, this.defaultRule], + transactionInput, ); - return Math.min(..._.compact(commissions)); } getExchangeRate(exchangeRateInput: ExchangeRateInput) { @@ -131,10 +126,7 @@ export class TransactionController { transactionAmount / exchangeRateResponse[transactionInput.currency], }; - const commissionAmount = this.applyRules( - [this.turnoverRule, this.discountRule], - transactionData, - ); + const commissionAmount = this.applyRules(transactionData); commissionAmount .then((commission) => @@ -158,10 +150,7 @@ export class TransactionController { base_amount: parseInt(transactionInput.amount), }; - const commissionAmount = await this.applyRules( - [this.turnoverRule, this.discountRule], - transactionData, - ); + const commissionAmount = await this.applyRules(transactionData); try { this.transactionService .insertOne({