Untitled
unknown
plain_text
a year ago
2.8 kB
1
Indexable
import * as Dinero from "dinero.js"; import * as B from "fp-ts/boolean"; import { pipe } from "fp-ts/lib/function"; import * as TE from "fp-ts/TaskEither"; import { fromCode } from "@lambdas/shared/money"; import { ValidateQuoteResponsePayload } from "@lambdas/shared/services/fx/validate-quote-by-fx-id/ValidateQuoteResponseParser"; import * as DepositAccount from "@lambdas/shared/services/mambu/depositAccount"; import { NoAccountError, noAccountError, } from "@lambdas/shared/services/mambu/error"; import { ExchangedAmountNotMatchError } from "./ExchangedAmountNotMatchError"; import { RequestPayload } from "./parser"; const CHOC_EXCHANGE_FEES = 0.005; export type ExchangeInfo = { fromWithdrawalAccount: DepositAccount.DepositAccount; toDepositAccount: DepositAccount.DepositAccount; depositAmount: Dinero.Dinero<number>; }; const getAccountByName = ( depositAccounts: DepositAccount.DepositAccount[], accountName: DepositAccount.DepositAccountName, userId: string ) => pipe( depositAccounts, DepositAccount.findByAccountName(accountName), TE.fromOption(() => noAccountError(userId, accountName)) ); export const getExchangeInfo = ( depositAccounts: DepositAccount.DepositAccount[], validateQuote: ValidateQuoteResponsePayload, userId: string, payload: RequestPayload ): TE.TaskEither<NoAccountError | ExchangedAmountNotMatchError, ExchangeInfo> => pipe( getAccountByName(depositAccounts, payload.fromAccountName, userId), TE.bindTo("fromWithdrawalAccount"), TE.bindW("toDepositAccount", () => getAccountByName(depositAccounts, payload.toAccountName, userId) ), TE.bindW("depositAmount", () => TE.of( calculateDepositAmount( payload.amount, validateQuote.exchangeRate, payload ) ) ), TE.chainFirstW(({ depositAmount }) => validateExchangedAmount(payload.exchangedAmount, depositAmount) ), TE.map((depositAccount) => depositAccount) ); const calculateDepositAmount = ( amount: Dinero.Dinero<number>, rate: number, payload: RequestPayload ) => { const fees = Dinero.toUnit(amount) * CHOC_EXCHANGE_FEES; const exchangedAmount = (Dinero.toUnit(amount) - fees) * rate; return fromCode(payload.toCurrency).amount(exchangedAmount); }; const validateExchangedAmount = ( exchangedAmount: Dinero.Dinero<number>, depositAmount: Dinero.Dinero<number> ) => pipe( Dinero.equal(exchangedAmount, depositAmount), B.fold( () => TE.of(undefined), // TODO: uncomment - Waiting for validateQuoteFx // TE.left( // exchangedAmountNotMatchError( // Dinero.toUnit(exchangedAmount), // Dinero.toUnit(depositAmount) // ) // ), () => TE.of(undefined) ) );
Editor is loading...
Leave a Comment