diff --git a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala index 8bd95d77a..cb18f71ee 100644 --- a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala +++ b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala @@ -511,6 +511,9 @@ object ErrorMessages { 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 AccountNumberNotUniqueError = "OBP-30269: Finding an account by the accountNumber is ambiguous." + val InvalidAccountNumber = "OBP-30270: Account not found. Please specify a valid value for ACCOUNT_NUMBER." + val BankAccountNotFoundByRoutings = "OBP-30073: Bank Account not found. Please specify valid values for routing schemes and addresses." 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. " diff --git a/obp-api/src/main/scala/code/api/util/NewStyle.scala b/obp-api/src/main/scala/code/api/util/NewStyle.scala index 9ee4e7e4f..8b21df9c5 100644 --- a/obp-api/src/main/scala/code/api/util/NewStyle.scala +++ b/obp-api/src/main/scala/code/api/util/NewStyle.scala @@ -403,6 +403,24 @@ object NewStyle extends MdcLoggable{ } } + def getBankAccountByRoutings( + bankAccountRoutings: BankAccountRoutings, + callContext: Option[CallContext] + ): OBPReturnType[BankAccount] = { + Connector.connector.vend.getBankAccountByRoutings( + bankAccountRoutings: BankAccountRoutings, + callContext: Option[CallContext] + ) map { i => + ( + unboxFullOrFail(i._1, callContext,s"$BankAccountNotFoundByRoutings " + + s"Current bank scheme is ${bankAccountRoutings.bank.scheme}, current bank address is ${bankAccountRoutings.bank.address}," + + s"Current account scheme is ${bankAccountRoutings.account.scheme}, current account address is ${bankAccountRoutings.account.scheme}," + + s"Current branch scheme is ${bankAccountRoutings.branch.scheme}, current branch address is ${bankAccountRoutings.branch.scheme}", + 404 + ), i._2) + } + } + def getAccountRoutingsByScheme(bankId: Option[BankId], scheme: String, callContext: Option[CallContext]) : OBPReturnType[List[BankAccountRouting]] = { Connector.connector.vend.getAccountRoutingsByScheme(bankId: Option[BankId], scheme: String, callContext: Option[CallContext]) map { i => (unboxFullOrFail(i._1, callContext,s"$AccountRoutingNotFound Current scheme is $scheme, current bankId is $bankId", 404 ), i._2) @@ -447,6 +465,11 @@ object NewStyle extends MdcLoggable{ (unboxFullOrFail(i._1, callContext, s"$BankAccountNotFound Current BankId is $bankId and Current AccountId is $accountId", 404), i._2) } + def getBankAccountByNumber(bankId : Option[BankId], accountNumber : String, callContext: Option[CallContext]) : OBPReturnType[(BankAccount)] = { + Connector.connector.vend.getBankAccountByNumber(bankId, accountNumber, callContext) } map { i => + (unboxFullOrFail(i._1, callContext, s"$BankAccountNotFound Current BankId is $bankId and Current AccountNumber is $accountNumber", 404), i._2) + } + def getBankSettlementAccounts(bankId: BankId, callContext: Option[CallContext]): OBPReturnType[List[BankAccount]] = { Connector.connector.vend.getBankSettlementAccounts(bankId: BankId, callContext: Option[CallContext]) map { i => (unboxFullOrFail(i._1, callContext,s"$BankNotFound Current BankId is $bankId", 404 ), i._2) @@ -1230,10 +1253,11 @@ object NewStyle extends MdcLoggable{ i._2) } } - def getBankAccountFromCounterparty(counterparty: CounterpartyTrait, isOutgoingAccount: Boolean, callContext: Option[CallContext]) : Future[BankAccount] = + def getBankAccountFromCounterparty(counterparty: CounterpartyTrait, isOutgoingAccount: Boolean, callContext: Option[CallContext]) : OBPReturnType[BankAccount] = { - Future{BankAccountX.getBankAccountFromCounterparty(counterparty, isOutgoingAccount)} map { - unboxFullOrFail(_, callContext, s"$UnknownError ") + Connector.connector.vend.getBankAccountFromCounterparty(counterparty: CounterpartyTrait, isOutgoingAccount: Boolean, callContext: Option[CallContext]) map { i => + (unboxFullOrFail(i._1, callContext, s"$InvalidConnectorResponse ${nameOf(getBankAccountFromCounterparty _)}", 400), + i._2) } } diff --git a/obp-api/src/main/scala/code/api/v2_1_0/APIMethods210.scala b/obp-api/src/main/scala/code/api/v2_1_0/APIMethods210.scala index e94b40687..631dedb01 100644 --- a/obp-api/src/main/scala/code/api/v2_1_0/APIMethods210.scala +++ b/obp-api/src/main/scala/code/api/v2_1_0/APIMethods210.scala @@ -506,7 +506,7 @@ trait APIMethods210 { } toCounterpartyId = transactionRequestBodyCounterparty.to.counterparty_id (toCounterparty, callContext) <- NewStyle.function.getCounterpartyByCounterpartyId(CounterpartyId(toCounterpartyId), callContext) - toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) // Check we can send money to it. _ <- Helper.booleanToFuture(s"$CounterpartyBeneficiaryPermit", cc=callContext) { toCounterparty.isBeneficiary == true @@ -538,7 +538,7 @@ trait APIMethods210 { } toIban = transDetailsSEPAJson.to.iban (toCounterparty, callContext) <- NewStyle.function.getCounterpartyByIban(toIban, callContext) - toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) _ <- Helper.booleanToFuture(s"$CounterpartyBeneficiaryPermit", cc=callContext) { toCounterparty.isBeneficiary == true } diff --git a/obp-api/src/main/scala/code/api/v3_1_0/APIMethods310.scala b/obp-api/src/main/scala/code/api/v3_1_0/APIMethods310.scala index caa5c9421..7daacf7bb 100644 --- a/obp-api/src/main/scala/code/api/v3_1_0/APIMethods310.scala +++ b/obp-api/src/main/scala/code/api/v3_1_0/APIMethods310.scala @@ -5654,7 +5654,7 @@ trait APIMethods310 { } else if (fromAccountPost.bank_id.isEmpty && fromAccountPost.account_id.isEmpty && fromAccountPost.counterparty_id.isDefined){ for { (fromCounterparty, callContext) <- NewStyle.function.getCounterpartyByCounterpartyId(CounterpartyId(fromAccountPost.counterparty_id.get), cc.callContext) - fromAccount <- NewStyle.function.getBankAccountFromCounterparty(fromCounterparty, false, callContext) + (fromAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(fromCounterparty, false, callContext) }yield{ (fromAccount, callContext) } @@ -5674,7 +5674,7 @@ trait APIMethods310 { } else if (toAccountPost.bank_id.isEmpty && toAccountPost.account_id.isEmpty && toAccountPost.counterparty_id.isDefined){ for { (toCounterparty, callContext) <- NewStyle.function.getCounterpartyByCounterpartyId(CounterpartyId(toAccountPost.counterparty_id.get), cc.callContext) - toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) }yield{ (toAccount, callContext) } diff --git a/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala b/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala index 4d307c52b..d85981833 100644 --- a/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala +++ b/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala @@ -1144,7 +1144,7 @@ trait APIMethods400 extends MdcLoggable { val toCounterpartyIban = transactionRequest.other_account_routing_address for { (toCounterparty, callContext) <- NewStyle.function.getCounterpartyByIbanAndBankAccountId(toCounterpartyIban, fromAccount.bankId, fromAccount.accountId, callContext) - toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) } yield (fromAccount, toAccount, callContext) } else { // Else, the transaction request debit a counterparty (Iban) @@ -1153,7 +1153,7 @@ trait APIMethods400 extends MdcLoggable { val toAccount = fromAccount for { (fromCounterparty, callContext) <- NewStyle.function.getCounterpartyByIbanAndBankAccountId(fromCounterpartyIban, toAccount.bankId, toAccount.accountId, callContext) - fromAccount <- NewStyle.function.getBankAccountFromCounterparty(fromCounterparty, false, callContext) + (fromAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(fromCounterparty, false, callContext) } yield (fromAccount, toAccount, callContext) } } @@ -12269,7 +12269,7 @@ object APIMethods400 extends RestHelper with APIMethods400 { val toCounterpartyId = CounterpartyId(refundRequestTo.counterparty_id.get) for { (toCounterparty, callContext) <- NewStyle.function.getCounterpartyByCounterpartyId(toCounterpartyId, callContext) - toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, isOutgoingAccount = true, callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, isOutgoingAccount = true, callContext) _ <- Helper.booleanToFuture(s"$CounterpartyBeneficiaryPermit", cc=callContext) { toCounterparty.isBeneficiary } @@ -12281,7 +12281,7 @@ object APIMethods400 extends RestHelper with APIMethods400 { val toAccount = fromAccount for { (fromCounterparty, callContext) <- NewStyle.function.getCounterpartyByCounterpartyId(fromCounterpartyId, callContext) - fromAccount <- NewStyle.function.getBankAccountFromCounterparty(fromCounterparty, isOutgoingAccount = false, callContext) + (fromAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(fromCounterparty, isOutgoingAccount = false, callContext) _ <- Helper.booleanToFuture(s"$CounterpartyBeneficiaryPermit", cc=callContext) { fromCounterparty.isBeneficiary } @@ -12575,7 +12575,7 @@ object APIMethods400 extends RestHelper with APIMethods400 { Future.successful(true) } - toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) // Check we can send money to it. _ <- Helper.booleanToFuture(s"$CounterpartyBeneficiaryPermit", cc=callContext) { toCounterparty.isBeneficiary @@ -12654,7 +12654,7 @@ object APIMethods400 extends RestHelper with APIMethods400 { } toCounterpartyId = transactionRequestBodyCard.to.counterparty_id (toCounterparty, callContext) <- NewStyle.function.getCounterpartyByCounterpartyId(CounterpartyId(toCounterpartyId), callContext) - toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) // Check we can send money to it. _ <- Helper.booleanToFuture(s"$CounterpartyBeneficiaryPermit", cc=callContext) { toCounterparty.isBeneficiary @@ -12702,7 +12702,7 @@ object APIMethods400 extends RestHelper with APIMethods400 { otherAccountSecondaryRoutingAddress = transactionRequestBodySimple.to.other_account_secondary_routing_address, callContext: Option[CallContext], ) - toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) // Check we can send money to it. _ <- Helper.booleanToFuture(s"$CounterpartyBeneficiaryPermit", cc=callContext) { toCounterparty.isBeneficiary @@ -12737,7 +12737,7 @@ object APIMethods400 extends RestHelper with APIMethods400 { } toIban = transDetailsSEPAJson.to.iban (toCounterparty, callContext) <- NewStyle.function.getCounterpartyByIbanAndBankAccountId(toIban, fromAccount.bankId, fromAccount.accountId, callContext) - toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) _ <- Helper.booleanToFuture(s"$CounterpartyBeneficiaryPermit", cc=callContext) { toCounterparty.isBeneficiary } diff --git a/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala b/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala index ac36f758e..24e01ff80 100644 --- a/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala +++ b/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala @@ -947,9 +947,6 @@ trait APIMethods500 { (bankId, accountId, viewId, counterpartyId) <- if (isVRPConsentRequest) { val postConsentRequestJsonV510 = json.parse(createdConsentRequest.payload).extract[code.api.v5_1_0.PostVRPConsentRequestJsonV510] - // 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 targetPermissions = List(//may need getTransactionRequest . so far only these payments. "can_add_transaction_request_to_beneficiary", @@ -966,14 +963,21 @@ trait APIMethods500 { hide_metadata_if_alias_used = true, allowed_permissions = targetPermissions ) + + val fromBankAccountRoutings = BankAccountRoutings( + bank = BankRoutingJson(postConsentRequestJsonV510.from_account.bank_routing.scheme, postConsentRequestJsonV510.from_account.bank_routing.address), + account = BranchRoutingJsonV141(postConsentRequestJsonV510.from_account.account_routing.scheme, postConsentRequestJsonV510.from_account.account_routing.address), + branch = AccountRoutingJsonV121(postConsentRequestJsonV510.from_account.branch_routing.scheme, postConsentRequestJsonV510.from_account.branch_routing.address) + ) for { - //1st: create the Custom View for the fromAccount. - (fromAccount, callContext) <- NewStyle.function.checkBankAccountExists(fromBankIdAccountId.bankId, fromBankIdAccountId.accountId, callContext) + //1st: get the fromAccount by routings: + (fromAccount, callContext) <- NewStyle.function.getBankAccountByRoutings(fromBankAccountRoutings, callContext) + fromBankIdAccountId = BankIdAccountId(fromAccount.bankId, fromAccount.accountId) + + //2rd: create the Custom View for the fromAccount. //we do not need sourceViewId so far, we need to get all the view access for the login user, and - permission <- NewStyle.function.permission(fromAccount.bankId, fromAccount.accountId, user, callContext) - permissionsFromSource = permission.views.map(view =>APIUtil.getViewPermissions(view.asInstanceOf[ViewDefinition]).toList).flatten.toSet permissionsFromTarget = targetCreateCustomViewJson.allowed_permissions @@ -989,7 +993,7 @@ trait APIMethods500 { _ <-NewStyle.function.grantAccessToCustomView(vrpView, user, callContext) - //2rd: Create a new counterparty on that view (_VRP-9d429899-24f5-42c8-8565-943ffa6a7945) + //3rd: Create a new counterparty on that view (_VRP-9d429899-24f5-42c8-8565-943ffa6a7945) postJson = PostCounterpartyJson400( name = postConsentRequestJsonV510.to_account.counterparty_name, description = postConsentRequestJsonV510.to_account.counterparty_name, @@ -1053,7 +1057,7 @@ trait APIMethods500 { max_number_of_transactions = postConsentRequestJsonV510.to_account.limit.max_number_of_transactions ) - //3rd: create the counterparty limit + //4th: create the counterparty limit (counterpartyLimitBox, callContext) <- Connector.connector.vend.getCounterpartyLimit( fromBankIdAccountId.bankId.value, fromBankIdAccountId.accountId.value, diff --git a/obp-api/src/main/scala/code/bankconnectors/Connector.scala b/obp-api/src/main/scala/code/bankconnectors/Connector.scala index 79118a0d2..036a4fb97 100644 --- a/obp-api/src/main/scala/code/bankconnectors/Connector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/Connector.scala @@ -519,6 +519,11 @@ trait Connector extends MdcLoggable { def checkBankAccountExistsLegacy(bankId : BankId, accountId : AccountId, callContext: Option[CallContext] = None) : Box[(BankAccount, Option[CallContext])]= Failure(setUnimplementedError(nameOf(checkBankAccountExistsLegacy _))) def checkBankAccountExists(bankId : BankId, accountId : AccountId, callContext: Option[CallContext] = None) : OBPReturnType[Box[(BankAccount)]] = Future {(Failure(setUnimplementedError(nameOf(checkBankAccountExists _))), callContext)} + def getBankAccountFromCounterparty(counterparty: CounterpartyTrait, isOutgoingAccount: Boolean, callContext: Option[CallContext]) : OBPReturnType[Box[(BankAccount)]] = Future {(Failure(setUnimplementedError(nameOf(getBankAccountFromCounterparty _))), callContext)} + + def getBankAccountByNumber(bankId : Option[BankId], accountNumber : String, callContext: Option[CallContext]) : OBPReturnType[Box[(BankAccount)]] = Future {(Failure(setUnimplementedError(nameOf(getBankAccountByNumber _))), callContext)} + + def getBankAccountByRoutings(bankAccountRoutings: BankAccountRoutings, callContext: Option[CallContext]) : OBPReturnType[Box[(BankAccount)]] = Future {(Failure(setUnimplementedError(nameOf(getBankAccountByRoutings _))), callContext)} def getCounterpartyFromTransaction(bankId: BankId, accountId: AccountId, counterpartyId: String, callContext: Option[CallContext]): OBPReturnType[Box[Counterparty]] = Future {(Failure(setUnimplementedError(nameOf(checkBankAccountExists _))), callContext)} diff --git a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala index 93c8d2341..f2025edc5 100644 --- a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -986,6 +986,77 @@ object LocalMappedConnector extends Connector with MdcLoggable { (getBankAccountLegacy(bankId: BankId, accountId: AccountId, callContext).map(_._1), callContext) } + override def getBankAccountByNumber(bankId : Option[BankId], accountNumber : String, callContext: Option[CallContext]) : OBPReturnType[Box[(BankAccount)]] = + Future { + val bankAccounts: Seq[MappedBankAccount] = if (bankId.isDefined){ + MappedBankAccount + .findAll( + By(MappedBankAccount.bank, bankId.head.value), + By(MappedBankAccount.accountNumber, accountNumber)) + }else{ + MappedBankAccount + .findAll(By(MappedBankAccount.accountNumber, accountNumber)) + } + + val errorMessage = + if(bankId.isEmpty) + s"$AccountNumberNotUniqueError, current AccountNumber is $accountNumber" + else + s"$AccountNumberNotUniqueError, current BankId is ${bankId.head.value}, AccountNumber is $accountNumber" + + if(bankAccounts.length > 1){ + (Failure(errorMessage), callContext) + }else if (bankAccounts.length == 1){ + (Full(bankAccounts.head), callContext) + }else{ + (Failure(errorMessage), callContext) + } + } + + override def getBankAccountByRoutings( + bankAccountRoutings: BankAccountRoutings, + callContext: Option[CallContext] + ): OBPReturnType[Box[(BankAccount)]]= { + val res: Future[(BankAccount, Option[CallContext])] = for{ + (fromAccount, callContext) <- if ((bankAccountRoutings.bank.scheme.equalsIgnoreCase("OBP")|| (bankAccountRoutings.bank.scheme.equalsIgnoreCase("OBP_BANK_ID"))) + && (bankAccountRoutings.account.scheme.equalsIgnoreCase("OBP") || bankAccountRoutings.account.scheme.equalsIgnoreCase("OBP_ACCOUNT_ID"))){ + for{ + (_, callContext) <- NewStyle.function.getBank(BankId(bankAccountRoutings.bank.address), callContext) + (account, callContext) <- NewStyle.function.checkBankAccountExists( + BankId(bankAccountRoutings.bank.address), + AccountId(bankAccountRoutings.account.address), + callContext) + } yield { + (account, callContext) + } + } else if (bankAccountRoutings.account.scheme.equalsIgnoreCase("ACCOUNT_NUMBER")){ + for{ + bankIdOption <- Future.successful(if (bankAccountRoutings.bank.address.isEmpty) None else Some(bankAccountRoutings.bank.address)) + (account, callContext) <- NewStyle.function.getBankAccountByNumber( + bankIdOption.map(BankId(_)), + bankAccountRoutings.account.address, + callContext) + } yield { + (account, callContext) + } + }else if (bankAccountRoutings.account.scheme.equalsIgnoreCase("IBAN")){ + for{ + (account, callContext) <- NewStyle.function.getBankAccountByIban( + bankAccountRoutings.account.address, + callContext) + } yield { + (account, callContext) + } + } else { + throw new RuntimeException(s"$BankAccountNotFoundByRoutings. Only support scheme = OBP or scheme IBAN or scheme = ACCOUNT_NUMBER. Current value is: ${bankAccountRoutings} ") + }}yield{ + (fromAccount, callContext) + } + res.map(i=>(Full(i._1),i._2)) + + } + + override def getCoreBankAccountsLegacy(bankIdAccountIds: List[BankIdAccountId], callContext: Option[CallContext]): Box[(List[CoreAccount], Option[CallContext])] = { Full( bankIdAccountIds @@ -1890,16 +1961,16 @@ object LocalMappedConnector extends Connector with MdcLoggable { val toAccountRoutingAddress = transactionRequest.other_account_routing_address for { - toAccount <- + (toAccount, callContext) <- Connector.connector.vend.getBankAccountByRoutingLegacy(None, toAccountRoutingScheme, toAccountRoutingAddress, None) match { - case Full(bankAccount) => Future.successful(bankAccount._1) + case Full(bankAccount) => Future.successful(bankAccount) case _: EmptyBox => NewStyle.function.getCounterpartyByIban(toAccountRoutingAddress, callContext).flatMap(counterparty => NewStyle.function.getBankAccountFromCounterparty(counterparty._1, isOutgoingAccount = true, callContext) ) } (debitTransactionId, callContext) <- savePayment( - fromAccount, toAccount, transactionRequest.id, transactionRequestCommonBody, amount, description, transactionRequestType, chargePolicy, callContext) + fromAccount, toAccount, transactionRequest.id, transactionRequestCommonBody, amount, description, transactionRequestType, chargePolicy, callContext) } yield (debitTransactionId, callContext) } @@ -2177,6 +2248,10 @@ object LocalMappedConnector extends Connector with MdcLoggable { override def saveTransactionRequestStatusImpl(transactionRequestId: TransactionRequestId, status: String, callContext: Option[CallContext]): OBPReturnType[Box[Boolean]] = Future{(TransactionRequests.transactionRequestProvider.vend.saveTransactionRequestStatusImpl(transactionRequestId, status), callContext)} + + override def getBankAccountFromCounterparty(counterparty: CounterpartyTrait, isOutgoingAccount: Boolean, callContext: Option[CallContext]): OBPReturnType[Box[BankAccount]] = + BankAccountX.getBankAccountFromCounterparty(counterparty, isOutgoingAccount, callContext) + override def updateBankAccount( bankId: BankId, accountId: AccountId, @@ -4793,7 +4868,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { } counterpartyId = CounterpartyId(bodyToCounterparty.counterparty_id) (toCounterparty, callContext) <- NewStyle.function.getCounterpartyByCounterpartyId(counterpartyId, callContext) - toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) counterpartyBody = TransactionRequestBodyCounterpartyJSON( to = CounterpartyIdJson(counterpartyId.value), value = AmountOfMoneyJsonV121(body.value.currency, body.value.amount), @@ -4866,7 +4941,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { bodyToSimple.otherAccountSecondaryRoutingAddress, callContext ) - toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) counterpartyBody = TransactionRequestBodySimpleJsonV400( to = PostSimpleCounterpartyJson400( name = toCounterparty.name, @@ -4907,7 +4982,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { val toCounterpartyIban = transactionRequest.other_account_routing_address for { (toCounterparty, callContext) <- NewStyle.function.getCounterpartyByIbanAndBankAccountId(toCounterpartyIban, fromAccount.bankId, fromAccount.accountId, callContext) - toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) } yield (fromAccount, toAccount, callContext) } else { // Warning here, we need to use the accountId here to store the counterparty IBAN. @@ -4916,7 +4991,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { val toAccount = fromAccount for { (fromCounterparty, callContext) <- NewStyle.function.getCounterpartyByIbanAndBankAccountId(fromCounterpartyIban, toAccount.bankId, toAccount.accountId, callContext) - fromAccount <- NewStyle.function.getBankAccountFromCounterparty(fromCounterparty, false, callContext) + (fromAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(fromCounterparty, false, callContext) } yield (fromAccount, toAccount, callContext) } } @@ -4945,7 +5020,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { } toCounterpartyIBan = bodyToCounterpartyIBan.iban (toCounterparty, callContext) <- NewStyle.function.getCounterpartyByIban(toCounterpartyIBan, callContext) - toAccount <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccountFromCounterparty(toCounterparty, true, callContext) sepaBody = TransactionRequestBodySEPAJSON( to = IbanJson(toCounterpartyIBan), value = AmountOfMoneyJsonV121(body.value.currency, body.value.amount), diff --git a/obp-api/src/main/scala/code/model/BankingData.scala b/obp-api/src/main/scala/code/model/BankingData.scala index 103684fd0..7880ddd8f 100644 --- a/obp-api/src/main/scala/code/model/BankingData.scala +++ b/obp-api/src/main/scala/code/model/BankingData.scala @@ -452,29 +452,48 @@ object BankAccountX { * incoming: counterparty send money to obp account. * @return BankAccount */ - def getBankAccountFromCounterparty(counterparty: CounterpartyTrait, isOutgoingAccount: Boolean) : Box[BankAccount] = { - if ( - (counterparty.otherBankRoutingScheme.equalsIgnoreCase("OBP") || counterparty.otherBankRoutingScheme.equalsIgnoreCase("OBP_BANK_ID" ) + def getBankAccountFromCounterparty(counterparty: CounterpartyTrait, isOutgoingAccount: Boolean, callContext: Option[CallContext]) : Future[(Box[BankAccount], Option[CallContext])] = { + if (counterparty.otherBankRoutingScheme.equalsIgnoreCase("OBP") || counterparty.otherBankRoutingScheme.equalsIgnoreCase("OBP_BANK_ID" ) && (counterparty.otherAccountRoutingScheme.equalsIgnoreCase("OBP") || counterparty.otherAccountRoutingScheme.equalsIgnoreCase("OBP_ACCOUNT_ID"))) - ) for{ - toBankId <- Full(BankId(counterparty.otherBankRoutingAddress)) - toAccountId <- Full(AccountId(counterparty.otherAccountRoutingAddress)) - toAccount <- BankAccountX(toBankId, toAccountId) ?~! s"${ErrorMessages.BankNotFound} Current Value: BANK_ID(counterparty.otherBankRoutingAddress=$toBankId) and ACCOUNT_ID(counterparty.otherAccountRoutingAddress=$toAccountId), please use correct OBP BankAccount to create the Counterparty.!!!!! " - } yield{ - toAccount + (_, callContext) <- NewStyle.function.getBank(BankId(counterparty.otherBankRoutingAddress), callContext) + (account, callContext) <- NewStyle.function.checkBankAccountExists( + BankId(counterparty.otherBankRoutingAddress), + AccountId(counterparty.otherAccountRoutingAddress), + callContext) + } yield { + (Full(account), callContext) } - else if ( - (counterparty.otherBankRoutingScheme.equalsIgnoreCase("OBP") || counterparty.otherBankRoutingScheme.equalsIgnoreCase("OBP_BANK_ID" ) - && (counterparty.otherAccountSecondaryRoutingScheme.equalsIgnoreCase("OBP") || counterparty.otherAccountSecondaryRoutingScheme.equalsIgnoreCase("OBP_ACCOUNT_ID")))) + else if (counterparty.otherBankRoutingScheme.equalsIgnoreCase("OBP") || counterparty.otherBankRoutingScheme.equalsIgnoreCase("OBP_BANK_ID" ) + && (counterparty.otherAccountSecondaryRoutingScheme.equalsIgnoreCase("OBP") || counterparty.otherAccountSecondaryRoutingScheme.equalsIgnoreCase("OBP_ACCOUNT_ID"))) for{ - toBankId <- Full(BankId(counterparty.otherBankRoutingAddress)) - toAccountId <- Full(AccountId(counterparty.otherAccountSecondaryRoutingAddress)) - toAccount <- BankAccountX(toBankId, toAccountId) ?~! s"${ErrorMessages.BankNotFound} Current Value: BANK_ID(counterparty.otherBankRoutingAddress=$toBankId) and ACCOUNT_ID(counterparty.otherAccountRoutingAddress=$toAccountId), please use correct OBP BankAccount to create the Counterparty.!!!!! " + (_, callContext) <- NewStyle.function.getBank(BankId(counterparty.otherBankRoutingAddress), callContext) + (account, callContext) <- NewStyle.function.checkBankAccountExists( + BankId(counterparty.otherBankRoutingAddress), + AccountId(counterparty.otherAccountSecondaryRoutingAddress), + callContext) } yield{ - toAccount + (Full(account), callContext) } - else { + else if (counterparty.otherAccountRoutingScheme.equalsIgnoreCase("ACCOUNT_NUMBER")){ + for{ + bankIdOption <- Future.successful(if(counterparty.otherBankRoutingAddress.isEmpty) None else Some(counterparty.otherBankRoutingAddress)) + (account, callContext) <- NewStyle.function.getBankAccountByNumber( + bankIdOption.map(BankId(_)), + counterparty.otherAccountRoutingAddress, + callContext) + } yield { + (Full(account), callContext) + } + }else if (counterparty.otherAccountRoutingScheme.equalsIgnoreCase("IBAN")){ + for{ + (account, callContext) <- NewStyle.function.getBankAccountByIban( + counterparty.otherAccountRoutingAddress, + callContext) + } yield { + (Full(account), callContext) + } + } else { //in obp we are creating a fake account with the counterparty information in this case: //These are just the obp mapped mode, if connector to the bank, bank will decide it. @@ -488,7 +507,7 @@ object BankAccountX { // Due to the new field in the database, old counterparty have void currency, so by default, we set it to EUR val counterpartyCurrency = if (counterparty.currency.nonEmpty) counterparty.currency else "EUR" - Full(BankAccountCommons( + Future{(Full(BankAccountCommons( AccountId(counterparty.otherAccountSecondaryRoutingAddress), "", 0, currency = counterpartyCurrency, name = counterparty.name, @@ -506,7 +525,7 @@ object BankAccountX { value = counterparty.otherBankRoutingAddress ), )) - )) + )), callContext)} } } diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/model/CommonModel.scala b/obp-commons/src/main/scala/com/openbankproject/commons/model/CommonModel.scala index ceda33a15..071c84bd2 100644 --- a/obp-commons/src/main/scala/com/openbankproject/commons/model/CommonModel.scala +++ b/obp-commons/src/main/scala/com/openbankproject/commons/model/CommonModel.scala @@ -765,6 +765,10 @@ object CardAttributeCommons extends Converter[CardAttribute, CardAttributeCommon //----------------obp-api moved to here case classes +case class BankRoutingJson( + scheme: String, + address: String +) case class BranchRoutingJsonV141( scheme: String, address: String @@ -775,6 +779,12 @@ case class AccountRoutingJsonV121( address: String ) +case class BankAccountRoutings( + bank:BankRoutingJson, + account:BranchRoutingJsonV141, + branch:AccountRoutingJsonV121 +) + case class AccountV310Json( bank_id: String , account_id: String ,