|
|
|
@ -1,4 +1,5 @@ |
|
|
|
|
import { Controller, Post, UsePipes, Body } from '@nestjs/common'; |
|
|
|
|
import { ExchangeRateInput, ExchangeRateResponse } from 'src/exchange-rate/exchange-rate.dto'; |
|
|
|
|
import { ExchangeRateService } from 'src/exchange-rate/exchange-rate.service'; |
|
|
|
|
import { TransactionService } from './transaction.service'; |
|
|
|
|
import { transactionBodySchema } from './transaction.validation'; |
|
|
|
@ -11,6 +12,9 @@ import { |
|
|
|
|
DefaultCommissionAmount, |
|
|
|
|
HighTurnoverDiscount, |
|
|
|
|
} from './transaction.dto'; |
|
|
|
|
import { Transaction } from './transaction.entity'; |
|
|
|
|
|
|
|
|
|
type TransactionRuleData = Pick<Transaction, 'base_amount' | 'client_id'>; |
|
|
|
|
|
|
|
|
|
@Controller('transaction') |
|
|
|
|
export class TransactionController { |
|
|
|
@ -37,7 +41,7 @@ export class TransactionController { |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getClientDeposit = async (transactionInput: TransactionInput) => { |
|
|
|
|
getClientDeposit = async (transactionInput: TransactionRuleData) => { |
|
|
|
|
try { |
|
|
|
|
const deposit = |
|
|
|
|
await this.transactionService.findByClientIdWithinActualMonth( |
|
|
|
@ -60,7 +64,7 @@ export class TransactionController { |
|
|
|
|
return 0; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
turnoverRule = async (transactionInput: TransactionInput) => { |
|
|
|
|
turnoverRule = async (transactionInput: TransactionRuleData) => { |
|
|
|
|
try { |
|
|
|
|
const clientDeposit = await this.getClientDeposit(transactionInput); |
|
|
|
|
if (clientDeposit) { |
|
|
|
@ -71,24 +75,26 @@ export class TransactionController { |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
discountRule(transactionInput: TransactionInput) { |
|
|
|
|
discountRule(transactionInput: TransactionRuleData) { |
|
|
|
|
return transactionInput.client_id === 42 |
|
|
|
|
? DiscountRuleForClientById.client_42 |
|
|
|
|
: false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
defaultRule(transactionInput: TransactionInput) { |
|
|
|
|
defaultRule(transactionInput: TransactionRuleData) { |
|
|
|
|
const commissionAmount = |
|
|
|
|
(parseInt(transactionInput.amount) / 100) * |
|
|
|
|
DefaultCommissionPercentage.percentage; |
|
|
|
|
(transactionInput.base_amount * DefaultCommissionPercentage.percentage) / |
|
|
|
|
100; |
|
|
|
|
return commissionAmount < DefaultCommissionAmount.amount |
|
|
|
|
? DefaultCommissionAmount.amount |
|
|
|
|
: commissionAmount; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async applyRules( |
|
|
|
|
rules: ((transactionInput: TransactionInput) => any)[], |
|
|
|
|
transactionInput: TransactionInput, |
|
|
|
|
rules: (( |
|
|
|
|
transactionInput: TransactionRuleData, |
|
|
|
|
) => number | false | undefined | Promise<number | false | undefined>)[], |
|
|
|
|
transactionInput: TransactionRuleData, |
|
|
|
|
) { |
|
|
|
|
let commissionAmount; |
|
|
|
|
for (let i = 0; i < rules.length; i++) { |
|
|
|
@ -105,60 +111,71 @@ export class TransactionController { |
|
|
|
|
: this.defaultRule(transactionInput); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getAmountWithExchange(transactionInput: TransactionInput) { |
|
|
|
|
const commissionAmount = this.applyRules( |
|
|
|
|
[this.turnoverRule, this.discountRule], |
|
|
|
|
transactionInput, |
|
|
|
|
); |
|
|
|
|
getExchangeRate(exchangeRateInput: ExchangeRateInput) { |
|
|
|
|
return new Promise<ExchangeRateResponse>((resolve, reject) => { |
|
|
|
|
try { |
|
|
|
|
this.exchangeRateService.convertCurrency(exchangeRateInput).subscribe({ |
|
|
|
|
next: resolve, |
|
|
|
|
error: reject, |
|
|
|
|
}); |
|
|
|
|
} catch (error) { |
|
|
|
|
reject(error); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const exhangeRateInput = { |
|
|
|
|
async getAmountWithExchange(transactionInput: TransactionInput) { |
|
|
|
|
const exchangeRateResponse = await this.getExchangeRate({ |
|
|
|
|
date: transactionInput.date, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const transactionAmount = parseInt(transactionInput.amount); |
|
|
|
|
const transactionData = { |
|
|
|
|
date: transactionInput.date, |
|
|
|
|
amount: transactionAmount, |
|
|
|
|
currency: transactionInput.currency, |
|
|
|
|
client_id: transactionInput.client_id, |
|
|
|
|
base_currency: Currency.EUR, |
|
|
|
|
base_amount: |
|
|
|
|
transactionAmount / exchangeRateResponse[transactionInput.currency], |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
this.exchangeRateService.convertCurrency(exhangeRateInput).subscribe({ |
|
|
|
|
next: (exchangeRateResponse) => |
|
|
|
|
commissionAmount |
|
|
|
|
.then((commission) => |
|
|
|
|
this.transactionService.insertOne({ |
|
|
|
|
date: transactionInput.date, |
|
|
|
|
amount: parseInt(transactionInput.amount), |
|
|
|
|
currency: transactionInput.currency, |
|
|
|
|
client_id: transactionInput.client_id, |
|
|
|
|
commission, |
|
|
|
|
base_currency: Currency.EUR, |
|
|
|
|
base_amount: |
|
|
|
|
parseInt(transactionInput.amount) * |
|
|
|
|
exchangeRateResponse[transactionInput.currency], |
|
|
|
|
}), |
|
|
|
|
) |
|
|
|
|
.catch((error) => console.log(error)), |
|
|
|
|
error: (error) => { |
|
|
|
|
console.log(error); |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
} catch (error) { |
|
|
|
|
console.log(error); |
|
|
|
|
} |
|
|
|
|
const commissionAmount = this.applyRules( |
|
|
|
|
[this.turnoverRule, this.discountRule], |
|
|
|
|
transactionData, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
commissionAmount |
|
|
|
|
.then((commission) => |
|
|
|
|
this.transactionService.insertOne({ |
|
|
|
|
...transactionData, |
|
|
|
|
commission, |
|
|
|
|
}), |
|
|
|
|
) |
|
|
|
|
.catch((error) => console.log(error)); |
|
|
|
|
|
|
|
|
|
return commissionAmount; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async getAmountWithoutExchange(transactionInput: TransactionInput) { |
|
|
|
|
const transactionData = { |
|
|
|
|
date: transactionInput.date, |
|
|
|
|
amount: parseInt(transactionInput.amount), |
|
|
|
|
currency: transactionInput.currency, |
|
|
|
|
client_id: transactionInput.client_id, |
|
|
|
|
base_currency: Currency.EUR, |
|
|
|
|
base_amount: parseInt(transactionInput.amount), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const commissionAmount = await this.applyRules( |
|
|
|
|
[this.turnoverRule, this.discountRule], |
|
|
|
|
transactionInput, |
|
|
|
|
transactionData, |
|
|
|
|
); |
|
|
|
|
try { |
|
|
|
|
this.transactionService |
|
|
|
|
.insertOne({ |
|
|
|
|
date: transactionInput.date, |
|
|
|
|
amount: parseInt(transactionInput.amount), |
|
|
|
|
currency: transactionInput.currency, |
|
|
|
|
client_id: transactionInput.client_id, |
|
|
|
|
...transactionData, |
|
|
|
|
commission: commissionAmount, |
|
|
|
|
base_currency: Currency.EUR, |
|
|
|
|
base_amount: parseInt(transactionInput.amount), |
|
|
|
|
}) |
|
|
|
|
.catch((error) => console.log(error)); |
|
|
|
|
} catch (error) { |
|
|
|
|