feature/added counterparty logic in payments

This commit is contained in:
hongwei 2024-12-06 00:47:35 +01:00
parent aa5268fbfb
commit cb8901c7a2
4 changed files with 147 additions and 1 deletions

View File

@ -510,6 +510,7 @@ object ErrorMessages {
val DeleteCounterpartyLimitError = "OBP-30265: Could not delete the counterparty limit."
val CustomViewAlreadyExistsError = "OBP-30266: The custom view is already exists."
val UserDoesNotHavePermission = "OBP-30267: The user does not have the permission:"
val CounterpartyLimitValidationError = "OBP-30268: Counterparty Limit Validation Error."
val TaxResidenceNotFound = "OBP-30300: Tax Residence not found by TAX_RESIDENCE_ID. "
val CustomerAddressNotFound = "OBP-30310: Customer's Address not found by CUSTOMER_ADDRESS_ID. "

View File

@ -4267,6 +4267,46 @@ object NewStyle extends MdcLoggable{
i => (unboxFullOrFail(i._1, callContext, s"$GetCounterpartyLimitError Current BANK_ID($bankId), " +
s"ACCOUNT_ID($accountId), VIEW_ID($viewId),COUNTERPARTY_ID($counterpartyId)"), i._2)
}
def getCountOfTransactionsFromAccountToCounterparty(
fromBankId: BankId,
fromAccountId: AccountId,
counterpartyId: CounterpartyId,
fromDate: Date,
toDate: Date,
callContext: Option[CallContext]
): OBPReturnType[Int] =
Connector.connector.vend.getCountOfTransactionsFromAccountToCounterparty(
fromBankId: BankId,
fromAccountId: AccountId,
counterpartyId: CounterpartyId,
fromDate: Date,
toDate: Date,
callContext: Option[CallContext]
) map {
i =>
(unboxFullOrFail(i._1, callContext, s"$InvalidConnectorResponse ${nameOf(getCountOfTransactionsFromAccountToCounterparty _)}"), i._2)
}
def getSumOfTransactionsFromAccountToCounterparty(
fromBankId: BankId,
fromAccountId: AccountId,
counterpartyId: CounterpartyId,
fromDate: Date,
toDate:Date,
callContext: Option[CallContext]
):OBPReturnType[AmountOfMoney] =
Connector.connector.vend.getSumOfTransactionsFromAccountToCounterparty(
fromBankId: BankId,
fromAccountId: AccountId,
counterpartyId: CounterpartyId,
fromDate: Date,
toDate:Date,
callContext: Option[CallContext]
) map {
i =>
(unboxFullOrFail(i._1, callContext, s"$InvalidConnectorResponse ${nameOf(getCountOfTransactionsFromAccountToCounterparty _)}"), i._2)
}
def deleteCounterpartyLimit(
bankId: String,

View File

@ -40,6 +40,7 @@ import code.api.v2_1_0._
import code.api.v3_0_0.{CreateScopeJson, JSONFactory300}
import code.api.v3_1_0._
import code.api.v4_0_0.JSONFactory400._
import code.fx.{MappedFXRate, fx}
import code.api.dynamic.endpoint.helper._
import code.api.dynamic.endpoint.helper.practise.PractiseEndpoint
import code.api.dynamic.entity.helper.{DynamicEntityHelper, DynamicEntityInfo}
@ -58,6 +59,7 @@ import code.dynamicMessageDoc.JsonDynamicMessageDoc
import code.dynamicResourceDoc.JsonDynamicResourceDoc
import code.endpointMapping.EndpointMappingCommons
import code.entitlement.Entitlement
import code.fx.fx
import code.loginattempts.LoginAttempt
import code.metadata.counterparties.{Counterparties, MappedCounterparty}
import code.metadata.tags.Tags
@ -103,6 +105,8 @@ import net.liftweb.util.Mailer.{From, PlainMailBodyType, Subject, To, XHTMLMailB
import net.liftweb.util.{Helpers, Mailer, StringHelpers}
import org.apache.commons.lang3.StringUtils
import java.time.{LocalDate, ZoneId, ZonedDateTime}
import java.util.Date
import scala.collection.immutable.{List, Nil}
import scala.collection.mutable.ArrayBuffer
import scala.concurrent.Future
@ -12599,6 +12603,107 @@ object APIMethods400 extends RestHelper with APIMethods400 {
}
toCounterpartyId = transactionRequestBodyCounterparty.to.counterparty_id
(toCounterparty, callContext) <- NewStyle.function.getCounterpartyByCounterpartyId(CounterpartyId(toCounterpartyId), callContext)
(counterpartyLimit, callContext) <- NewStyle.function.getCounterpartyLimit(
bankId.value,
accountId.value,
viewId.value,
toCounterpartyId,
callContext
)
maxSingleAmount = counterpartyLimit.maxSingleAmount
maxMonthlyAmount = counterpartyLimit.maxMonthlyAmount
maxNumberOfMonthlyTransactions = counterpartyLimit.maxNumberOfMonthlyTransactions
maxYearlyAmount = counterpartyLimit.maxYearlyAmount
maxNumberOfYearlyTransactions = counterpartyLimit.maxNumberOfYearlyTransactions
// Get the first day of the current month
firstDayOfMonth: LocalDate = LocalDate.now().withDayOfMonth(1)
// Get the last day of the current month
lastDayOfMonth: LocalDate = LocalDate.now().withDayOfMonth(
LocalDate.now().lengthOfMonth()
)
// Get the first day of the current year
firstDayOfYear: LocalDate = LocalDate.now().withDayOfYear(1)
// Get the last day of the current year
lastDayOfYear: LocalDate = LocalDate.now().withDayOfYear(
LocalDate.now().lengthOfYear()
)
// Convert LocalDate to Date
zoneId: ZoneId = ZoneId.systemDefault()
firstCurrentMonthDate: Date = Date.from(firstDayOfMonth.atStartOfDay(zoneId).toInstant)
lastCurrentMonthDate: Date = Date.from(lastDayOfMonth.atStartOfDay(zoneId).toInstant)
firstCurrentYearDate: Date = Date.from(firstDayOfYear.atStartOfDay(zoneId).toInstant)
lastCurrentYearDate: Date = Date.from(lastDayOfYear.atStartOfDay(zoneId).toInstant)
(sumOfTransactionsFromAccountToCounterpartyMonthly, callContext) <- NewStyle.function.getSumOfTransactionsFromAccountToCounterparty(
fromAccount.bankId: BankId,
fromAccount.accountId: AccountId,
CounterpartyId(toCounterpartyId): CounterpartyId,
firstCurrentMonthDate: Date,
lastCurrentMonthDate: Date,
callContext: Option[CallContext]
)
(countOfTransactionsFromAccountToCounterpartyMonthly, callContext) <- NewStyle.function.getCountOfTransactionsFromAccountToCounterparty(
fromAccount.bankId: BankId,
fromAccount.accountId: AccountId,
CounterpartyId(toCounterpartyId): CounterpartyId,
firstCurrentMonthDate: Date,
lastCurrentMonthDate: Date,
callContext: Option[CallContext]
)
(sumOfTransactionsFromAccountToCounterpartyYearly, callContext) <- NewStyle.function.getSumOfTransactionsFromAccountToCounterparty(
fromAccount.bankId: BankId,
fromAccount.accountId: AccountId,
CounterpartyId(toCounterpartyId): CounterpartyId,
firstCurrentYearDate: Date,
lastCurrentYearDate: Date,
callContext: Option[CallContext]
)
(countOfTransactionsFromAccountToCounterpartyYearly, callContext) <- NewStyle.function.getCountOfTransactionsFromAccountToCounterparty(
fromAccount.bankId: BankId,
fromAccount.accountId: AccountId,
CounterpartyId(toCounterpartyId): CounterpartyId,
firstCurrentYearDate: Date,
lastCurrentYearDate: Date,
callContext: Option[CallContext]
)
currentTransactionAmountWithFxApplied <- NewStyle.function.tryons(s"${InvalidJsonFormat}, it should be $COUNTERPARTY json format", 400, callContext) {
val fromAccountCurrency = fromAccount.currency //eg: if from account currency is EUR
val transferCurrency = transactionRequestBodyCounterparty.value.currency //eg: if the payment json body currency is GBP.
val transferAmount= BigDecimal(transactionRequestBodyCounterparty.value.amount) //eg: if the payment json body amount is 1.
val debitRate = fx.exchangeRate(transferCurrency, fromAccountCurrency, Some(fromAccount.bankId.value), callContext) //eg: the rate here is 1.16278.
fx.convert(transferAmount, debitRate) // 1.16278 Euro
}
_ <- Helper.booleanToFuture(s"$CounterpartyLimitValidationError maxSingleAmount is $maxSingleAmount ${fromAccount.currency}, " +
s"but current transaction body amount is ${transactionRequestBodyCounterparty.value.amount} ${transactionRequestBodyCounterparty.value.currency}, " +
s"which is $currentTransactionAmountWithFxApplied ${fromAccount.currency}. ", cc=callContext) {
BigDecimal(maxSingleAmount) >= currentTransactionAmountWithFxApplied
}
_ <- Helper.booleanToFuture(s"$CounterpartyLimitValidationError maxMonthlyAmount is $maxSingleAmount, but current monthly amount is ${sumOfTransactionsFromAccountToCounterpartyMonthly.amount}", cc=callContext) {
BigDecimal(maxMonthlyAmount) >= BigDecimal(sumOfTransactionsFromAccountToCounterpartyMonthly.amount)
}
_ <- Helper.booleanToFuture(s"$CounterpartyLimitValidationError maxNumberOfMonthlyTransactions is $maxSingleAmount, but current count of monthly transactions is ${countOfTransactionsFromAccountToCounterpartyMonthly}", cc=callContext) {
maxNumberOfMonthlyTransactions >= countOfTransactionsFromAccountToCounterpartyMonthly
}
_ <- Helper.booleanToFuture(s"$CounterpartyLimitValidationError maxYearlyAmount is $maxYearlyAmount, but current yearly amount is ${sumOfTransactionsFromAccountToCounterpartyYearly.amount}", cc=callContext) {
BigDecimal(maxYearlyAmount) >= BigDecimal(sumOfTransactionsFromAccountToCounterpartyYearly.amount)
}
_ <- Helper.booleanToFuture(s"$CounterpartyLimitValidationError maxNumberOfYearlyTransactions is $maxNumberOfYearlyTransactions, but current count of yearly transaction is ${countOfTransactionsFromAccountToCounterpartyYearly}", cc=callContext) {
maxNumberOfYearlyTransactions >= countOfTransactionsFromAccountToCounterpartyYearly
}
toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext)
// Check we can send money to it.
_ <- Helper.booleanToFuture(s"$CounterpartyBeneficiaryPermit", cc=callContext) {

View File

@ -943,7 +943,7 @@ trait APIMethods500 {
// TODO Add routing scheme as well. In case IBAN is provided this will not work.
val fromBankIdAccountId = BankIdAccountId(BankId(postConsentRequestJsonV510.from_account.bank_routing.address), AccountId(postConsentRequestJsonV510.from_account.account_routing.address))
val vrpViewId = s"_VRP-${UUID.randomUUID.toString}".dropRight(5)// to make sure the length of the viewId is 36.
val vrpViewId = s"_vrp-${UUID.randomUUID.toString}".dropRight(5)// to make sure the length of the viewId is 36.
val targetPermissions = List(//may need getTransactionRequest .. so far only this payments.
"can_add_transaction_request_to_beneficiary",
"can_get_counterparty"