From a871f79794a97978ef2c76ad9d225fdd762efb11 Mon Sep 17 00:00:00 2001 From: hongwei Date: Tue, 19 Nov 2024 11:16:01 +0100 Subject: [PATCH] feature/OBPv510 added updateAgentstatus and V400 added createTransactionRequestAgent --- .../SwaggerDefinitionsJSON.scala | 18 ++- .../main/scala/code/api/util/APIUtil.scala | 9 +- .../main/scala/code/api/util/ApiRole.scala | 6 + .../main/scala/code/api/util/NewStyle.scala | 14 ++ .../scala/code/api/v4_0_0/APIMethods400.scala | 61 +++++++- .../code/api/v4_0_0/JSONFactory4.0.0.scala | 12 ++ .../scala/code/api/v5_1_0/APIMethods510.scala | 141 +++++++++++------- .../code/api/v5_1_0/JSONFactory5.1.0.scala | 34 +++-- .../scala/code/bankconnectors/Connector.scala | 7 + .../bankconnectors/LocalMappedConnector.scala | 46 +++++- .../KafkaMappedConnector_vSept2018.scala | 11 +- .../customer/MappedCustomerProvider.scala | 12 +- .../MappedTransactionRequestProvider.scala | 16 ++ .../commons/model/CommonModel.scala | 28 +--- .../commons/model/CustomerDataModel.scala | 3 + 15 files changed, 310 insertions(+), 108 deletions(-) diff --git a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala index 8297bb1f7..89f43a279 100644 --- a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala +++ b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala @@ -5516,9 +5516,9 @@ object SwaggerDefinitionsJSON { List(consumerJsonV510) ) - val agentIdJson = AgentIdJson("") + val agentIdJson = AgentIdJson(agentIdExample.value) - val transactionRequestBodyAgentJsonV510 = TransactionRequestBodyAgentJsonV510( + val transactionRequestBodyAgentJsonV400 = TransactionRequestBodyAgentJsonV400( to = agentIdJson, value = amountOfMoneyJsonV121, description = descriptionExample.value, @@ -5533,6 +5533,11 @@ object SwaggerDefinitionsJSON { currency = currencyExample.value ) + val putAgentJsonV510 = PutAgentJsonV510( + is_pending_agent = true, + is_confirmed_agent = true + ) + val agentJsonV510 = AgentJsonV510( agent_id = agentIdExample.value, legal_name = legalNameExample.value, @@ -5541,6 +5546,15 @@ object SwaggerDefinitionsJSON { currency = currencyExample.value ) + val agentMinimalJsonV510 = AgentMinimalJsonV510( + agent_id = agentIdExample.value, + legal_name = legalNameExample.value, + ) + + val agentMinimalsJsonV510 = AgentMinimalsJsonV510( + agents = List(agentMinimalJsonV510) + ) + //The common error or success format. //Just some helper format to use in Json case class NotSupportedYet() diff --git a/obp-api/src/main/scala/code/api/util/APIUtil.scala b/obp-api/src/main/scala/code/api/util/APIUtil.scala index 855a4d0bb..66b9d5aee 100644 --- a/obp-api/src/main/scala/code/api/util/APIUtil.scala +++ b/obp-api/src/main/scala/code/api/util/APIUtil.scala @@ -938,7 +938,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ case _ => null } - //started -- Filtering and Paging revelent methods//////////////////////////// + //started -- Filtering and Paging relevant methods//////////////////////////// def parseObpStandardDate(date: String): Box[Date] = { val parsedDate = tryo{DateWithMsFormat.parse(date)} @@ -1280,7 +1280,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ val queryStrings = urlAndQueryString.split("&").map(_.split("=")).flatten //Full(from_date, $DateWithMsExampleString, to_date, $DateWithMsExampleString) if (queryStrings.contains(name)&& queryStrings.length > queryStrings.indexOf(name)+1) queryStrings(queryStrings.indexOf(name)+1) else ""//Full($DateWithMsExampleString) } - //ended -- Filtering and Paging revelent methods //////////////////////////// + //ended -- Filtering and Paging relevant methods //////////////////////////// /** Import this object's methods to add signing operators to dispatch.Request */ @@ -2117,7 +2117,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ |eg1:?limit=100&offset=0 |""". stripMargin - val sortDirectionParameters = + val sortDirectionParameters = if (containsSortDirection) { s""" | |* sort_direction=ASC/DESC ==> default value: DESC. @@ -2125,6 +2125,9 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ |eg2:?limit=100&offset=0&sort_direction=ASC | |""". stripMargin + }else{ + "" + } val dateParameter = if(containsDate){ s""" diff --git a/obp-api/src/main/scala/code/api/util/ApiRole.scala b/obp-api/src/main/scala/code/api/util/ApiRole.scala index 91defb78f..137b2712a 100644 --- a/obp-api/src/main/scala/code/api/util/ApiRole.scala +++ b/obp-api/src/main/scala/code/api/util/ApiRole.scala @@ -109,6 +109,12 @@ object ApiRole extends MdcLoggable{ case class CanGetAgent(requiresBankId: Boolean = true) extends ApiRole lazy val canGetAgent = CanGetAgent() + + case class CanUpdateAgentStatusAtAnyBank(requiresBankId: Boolean = false) extends ApiRole + lazy val canUpdateAgentStatusAtAnyBank = CanUpdateAgentStatusAtAnyBank() + + case class CanUpdateAgentStatusAtOneBank(requiresBankId: Boolean = true) extends ApiRole + lazy val canUpdateAgentStatusAtOneBank = CanUpdateAgentStatusAtOneBank() case class CanUpdateCustomerEmail(requiresBankId: Boolean = true) extends ApiRole lazy val canUpdateCustomerEmail = CanUpdateCustomerEmail() 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 80342ac23..feb909f77 100644 --- a/obp-api/src/main/scala/code/api/util/NewStyle.scala +++ b/obp-api/src/main/scala/code/api/util/NewStyle.scala @@ -2838,6 +2838,20 @@ object NewStyle extends MdcLoggable{ callContext) map { i => (unboxFullOrFail(i._1, callContext, UpdateCustomerError), i._2) } + + def updateAgentStatus( + agentId: String, + is_pending_agent: Boolean, + is_confirmed_agent: Boolean, + callContext: Option[CallContext]): OBPReturnType[Customer] = + Connector.connector.vend.updateAgentStatus( + agentId: String, + is_pending_agent: Boolean, + is_confirmed_agent: Boolean, + callContext: Option[CallContext] + ) map { + i => (unboxFullOrFail(i._1, callContext, UpdateCustomerError), i._2) + } def updateCustomerCreditData(customerId: String, creditRating: Option[String], creditSource: Option[String], 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 d8eee9ed1..5924f92bf 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 @@ -45,8 +45,7 @@ import code.api.dynamic.endpoint.helper.practise.PractiseEndpoint import code.api.dynamic.entity.helper.{DynamicEntityHelper, DynamicEntityInfo} import code.api.util.FutureUtil.EndpointContext import code.api.v4_0_0.APIMethods400.{createTransactionRequest, exchangeRates, lowAmount, sharedChargePolicy, transactionRequestGeneralText} -import code.api.v5_0_0.OBPAPI5_0_0 -import code.api.v5_1_0.TransactionRequestBodyAgentJsonV510 +import code.api.v4_0_0.TransactionRequestBodyAgentJsonV400 import code.api.{ChargePolicy, Constant, JsonResponseException} import code.apicollection.MappedApiCollectionsProvider import code.apicollectionendpoint.MappedApiCollectionEndpointsProvider @@ -858,6 +857,61 @@ trait APIMethods400 extends MdcLoggable { ), List(apiTagTransactionRequest, apiTagPSD2PIS), Some(List(canCreateAnyTransactionRequest))) + + + staticResourceDocs += ResourceDoc( + createTransactionRequestAgentCashWithDrawal, + implementedInApiVersion, + nameOf(createTransactionRequestAgentCashWithDrawal), + "POST", + "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transaction-request-types/AGENT_CASH_WITHDRAWAL/transaction-requests", + "Create Transaction Request (AGENT_CASH_WITHDRAWAL)", + s""" + | + |Either the `from` or the `to` field must be filled. Those fields refers to the information about the party that will be refunded. + | + |In case the `from` object is used, it means that the refund comes from the part that sent you a transaction. + |In the `from` object, you have two choices : + |- Use `bank_id` and `account_id` fields if the other account is registered on the OBP-API + |- Use the `counterparty_id` field in case the counterparty account is out of the OBP-API + | + |In case the `to` object is used, it means you send a request to a counterparty to ask for a refund on a previous transaction you sent. + |(This case is not managed by the OBP-API and require an external adapter) + | + | + |$transactionRequestGeneralText + | + """.stripMargin, + transactionRequestBodyAgentJsonV400, + transactionRequestWithChargeJSON400, + List( + $UserNotLoggedIn, + InvalidBankIdFormat, + InvalidAccountIdFormat, + InvalidJsonFormat, + $BankNotFound, + AccountNotFound, + $BankAccountNotFound, + InsufficientAuthorisationToCreateTransactionRequest, + InvalidTransactionRequestType, + InvalidJsonFormat, + InvalidNumber, + NotPositiveAmount, + InvalidTransactionRequestCurrency, + TransactionDisabled, + UnknownError + ), + List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2) + ) + + lazy val createTransactionRequestAgentCashWithDrawal: OBPEndpoint = { + case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transaction-request-types" :: + "AGENT_CASH_WITHDRAWAL" :: "transaction-requests" :: Nil JsonPost json -> _ => + cc => + implicit val ec = EndpointContext(Some(cc)) + val transactionRequestType = TransactionRequestType("AGENT_CASH_WITHDRAWAL") + createTransactionRequest(bankId, accountId, viewId, transactionRequestType, json) + } lazy val createTransactionRequestAccount: OBPEndpoint = { case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transaction-request-types" :: @@ -12575,9 +12629,10 @@ object APIMethods400 extends RestHelper with APIMethods400 { for { //For Agent, Use the agentId to find the agent and set up the toAccount transactionRequestBodyAgent <- NewStyle.function.tryons(s"${InvalidJsonFormat}, it should be $AGENT_CASH_WITHDRAWAL json format", 400, callContext) { - json.extract[TransactionRequestBodyAgentJsonV510] + json.extract[TransactionRequestBodyAgentJsonV400] } toAgentId = transactionRequestBodyAgent.to.agent_id + (agent, callContext) <- NewStyle.function.getAgentByAgentId(toAgentId, callContext) (customerAccountLinks, callContext) <- NewStyle.function.getCustomerAccountLinksByCustomerId(toAgentId, callContext) customerAccountLink <- NewStyle.function.tryons(AgentAccountLinkNotFound, 400, callContext) { customerAccountLinks.head diff --git a/obp-api/src/main/scala/code/api/v4_0_0/JSONFactory4.0.0.scala b/obp-api/src/main/scala/code/api/v4_0_0/JSONFactory4.0.0.scala index dd9645c16..fec521ac8 100644 --- a/obp-api/src/main/scala/code/api/v4_0_0/JSONFactory4.0.0.scala +++ b/obp-api/src/main/scala/code/api/v4_0_0/JSONFactory4.0.0.scala @@ -391,6 +391,18 @@ case class ConsentInfoJsonV400(consent_id: String, api_version: String) case class ConsentInfosJsonV400(consents: List[ConsentInfoJsonV400]) +case class AgentIdJson( + agent_id: String +) + +case class TransactionRequestBodyAgentJsonV400( + to: AgentIdJson, + value: AmountOfMoneyJsonV121, + description: String, + charge_policy: String, + future_date: Option[String] = None +) extends TransactionRequestCommonBodyJSON + case class TransactionRequestBodySEPAJsonV400( value: AmountOfMoneyJsonV121, to: IbanJson, diff --git a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala index a3024f616..eab0e6b8f 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala @@ -10,6 +10,7 @@ import code.api.util.ErrorMessages.{$UserNotLoggedIn, BankNotFound, ConsentNotFo import code.api.util.FutureUtil.{EndpointContext, EndpointTimeout} import code.api.util.JwtUtil.{getSignedPayloadAsJson, verifyJwt} import code.api.util.NewStyle.HttpCode +import code.api.util.NewStyle.function.extractQueryParams import code.api.util.X509.{getCommonName, getEmailAddress, getOrganization} import code.api.util._ import code.api.util.newstyle.BalanceNewStyle @@ -422,6 +423,57 @@ trait APIMethods510 { } } } + + staticResourceDocs += ResourceDoc( + updateAgentstatus, + implementedInApiVersion, + nameOf(updateAgentstatus), + "PUT", + "/banks/BANK_ID/agents/AGENT_ID", + "Update Agent status", + s""" + |${authenticationRequiredMessage(true)} + |""", + putAgentJsonV510, + agentJsonV510, + List( + $UserNotLoggedIn, + $BankNotFound, + InvalidJsonFormat, + CustomerNumberAlreadyExists, + UserNotFoundById, + CustomerAlreadyExistsForUser, + CreateConsumerError, + UnknownError + ), + List(apiTagCustomer, apiTagPerson), + Some(canUpdateAgentStatusAtAnyBank :: canUpdateAgentStatusAtOneBank :: Nil) + ) + + lazy val updateAgentstatus : OBPEndpoint = { + case "banks" :: BankId(bankId) :: "agents" :: agentId :: Nil JsonPost json -> _ => { + cc => implicit val ec = EndpointContext(Some(cc)) + for { + postedData <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the $PostAgentJsonV510 ", 400, cc.callContext) { + json.extract[PutAgentJsonV510] + } + (agent, callContext) <- NewStyle.function.getAgentByAgentId(agentId, cc.callContext) + (customerAccountLinks, callContext) <- NewStyle.function.getCustomerAccountLinksByCustomerId(agentId, callContext) + customerAccountLink <- NewStyle.function.tryons(AgentAccountLinkNotFound, 400, callContext) { + customerAccountLinks.head + } + (bankAccount, callContext) <- NewStyle.function.getBankAccount(BankId(customerAccountLink.bankId), AccountId(customerAccountLink.accountId), callContext) + (customer, callContext) <- NewStyle.function.updateCustomerScaData( + agentId, + Some(postedData.is_pending_agent.toString), + None, + None, + callContext) + } yield { + (JSONFactory510.createAgentJson(agent, bankAccount), HttpCode.`201`(callContext)) + } + } + } staticResourceDocs += ResourceDoc( getAgent, @@ -451,7 +503,7 @@ trait APIMethods510 { (Full(u), callContext) <- SS.user (agent, callContext) <- NewStyle.function.getAgentByAgentId(agentId, callContext) (customerAccountLinks, callContext) <- NewStyle.function.getCustomerAccountLinksByCustomerId(agentId, callContext) - customerAccountLink <- NewStyle.function.tryons(AgentAccountLinkNotFound, 400, cc.callContext) { + customerAccountLink <- NewStyle.function.tryons(AgentAccountLinkNotFound, 400, callContext) { customerAccountLinks.head } (bankAccount, callContext) <- NewStyle.function.getBankAccount(BankId(customerAccountLink.bankId), AccountId(customerAccountLink.accountId), callContext) @@ -460,60 +512,6 @@ trait APIMethods510 { } } } - - staticResourceDocs += ResourceDoc( - createTransactionRequestAgent, - implementedInApiVersion, - nameOf(createTransactionRequestAgent), - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transaction-request-types/AGENT/transaction-requests", - "Create Transaction Request (AGENT)", - s""" - | - |Either the `from` or the `to` field must be filled. Those fields refers to the information about the party that will be refunded. - | - |In case the `from` object is used, it means that the refund comes from the part that sent you a transaction. - |In the `from` object, you have two choices : - |- Use `bank_id` and `account_id` fields if the other account is registered on the OBP-API - |- Use the `counterparty_id` field in case the counterparty account is out of the OBP-API - | - |In case the `to` object is used, it means you send a request to a counterparty to ask for a refund on a previous transaction you sent. - |(This case is not managed by the OBP-API and require an external adapter) - | - | - |$transactionRequestGeneralText - | - """.stripMargin, - transactionRequestBodyAgentJsonV510, - transactionRequestWithChargeJSON400, - List( - $UserNotLoggedIn, - InvalidBankIdFormat, - InvalidAccountIdFormat, - InvalidJsonFormat, - $BankNotFound, - AccountNotFound, - $BankAccountNotFound, - InsufficientAuthorisationToCreateTransactionRequest, - InvalidTransactionRequestType, - InvalidJsonFormat, - InvalidNumber, - NotPositiveAmount, - InvalidTransactionRequestCurrency, - TransactionDisabled, - UnknownError - ), - List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2) - ) - - lazy val createTransactionRequestAgent: OBPEndpoint = { - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transaction-request-types" :: - "AGENT-CASH-WITHDRAWAL" :: "transaction-requests" :: Nil JsonPost json -> _ => - cc => - implicit val ec = EndpointContext(Some(cc)) - val transactionRequestType = TransactionRequestType("ACCOUNT") - createTransactionRequest(bankId, accountId, viewId, transactionRequestType, json) - } staticResourceDocs += ResourceDoc( createNonPersonalUserAttribute, @@ -972,6 +970,39 @@ trait APIMethods510 { } } } + staticResourceDocs += ResourceDoc( + getAgents, + implementedInApiVersion, + nameOf(getAgents), + "GET", + "/banks/BANK_ID/agents", + "Get Agents at Bank", + s"""Get Agents at Bank. + | + |${authenticationRequiredMessage(false)} + | + |${urlParametersDocument(true, true)} + |""".stripMargin, + EmptyBody, + agentMinimalsJsonV510, + List( + $BankNotFound, + UnknownError + ), + List(apiTagAccount) + ) + + lazy val getAgents: OBPEndpoint = { + case "banks" :: BankId(bankId) :: "agents" :: Nil JsonGet _ => { + cc => implicit val ec = EndpointContext(Some(cc)) + for { + (requestParams, callContext) <- extractQueryParams(cc.url, List("limit","offset","sort_direction"), cc.callContext) + customers <- NewStyle.function.getCustomers(bankId, callContext, requestParams) + } yield { + (JSONFactory510.createAgentMinimalsJson(customers), HttpCode.`200`(callContext)) + } + } + } staticResourceDocs += ResourceDoc( getAtmAttributes, diff --git a/obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala b/obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala index 8e7146921..823290b63 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala @@ -322,18 +322,6 @@ case class AgentJson( name:String ) -case class AgentIdJson( - agent_id: String -) - -case class TransactionRequestBodyAgentJsonV510( - to: AgentIdJson, - value: AmountOfMoneyJsonV121, - description: String, - charge_policy: String, - future_date: Option[String] = None -) extends TransactionRequestCommonBodyJSON - case class PostAgentJsonV510( legal_name: String, mobile_phone_number: String, @@ -341,6 +329,11 @@ case class PostAgentJsonV510( currency: String ) +case class PutAgentJsonV510( + is_pending_agent: Boolean, + is_confirmed_agent: Boolean +) + case class AgentJsonV510( agent_id: String, legal_name: String, @@ -349,6 +342,14 @@ case class AgentJsonV510( currency: String ) +case class AgentMinimalJsonV510( + agent_id: String, + legal_name: String, +) +case class AgentMinimalsJsonV510( + agents: List[AgentMinimalJsonV510] +) + case class CustomersIdsJsonV510(customers: List[CustomerIdJson]) case class PostCustomerLegalNameJsonV510(legal_name: String) @@ -953,6 +954,15 @@ object JSONFactory510 extends CustomJsonFormats { currency = bankAccount.currency ) } + def createAgentMinimalsJson(customers: List[Customer]): AgentMinimalsJsonV510 = { + AgentMinimalsJsonV510( + customers + .filter(_.isConfirmedAgent == Some(true)) + .map(customer => AgentMinimalJsonV510( + agent_id = customer.customerId, + legal_name = customer.legalName + ))) + } } diff --git a/obp-api/src/main/scala/code/bankconnectors/Connector.scala b/obp-api/src/main/scala/code/bankconnectors/Connector.scala index 6a0f210fd..647454e43 100644 --- a/obp-api/src/main/scala/code/bankconnectors/Connector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/Connector.scala @@ -1112,6 +1112,13 @@ trait Connector extends MdcLoggable { customerNumber: Option[String], callContext: Option[CallContext]): OBPReturnType[Box[Customer]] = Future{(Failure(setUnimplementedError(nameOf(updateCustomerScaData _))), callContext)} + + def updateAgentStatus( + agentId: String, + is_pending_agent: Boolean, + is_confirmed_agent: Boolean, + callContext: Option[CallContext] + ): OBPReturnType[Box[Customer]] = Future{(Failure(setUnimplementedError(nameOf(updateCustomerScaData _))), callContext)} def updateCustomerCreditData(customerId: String, creditRating: Option[String], diff --git a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala index 8b83ae3db..89f06f315 100644 --- a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -15,7 +15,7 @@ import code.api.util.ErrorMessages._ import code.api.util._ import code.api.v1_4_0.JSONFactory1_4_0.TransactionRequestAccountJsonV140 import code.api.v2_1_0._ -import code.api.v4_0_0.{PostSimpleCounterpartyJson400, TransactionRequestBodySimpleJsonV400} +import code.api.v4_0_0.{AgentIdJson, PostSimpleCounterpartyJson400, TransactionRequestBodyAgentJsonV400, TransactionRequestBodySimpleJsonV400} import code.atmattribute.{AtmAttribute, AtmAttributeX} import code.atms.{Atms, MappedAtm} import code.bankattribute.{BankAttribute, BankAttributeX} @@ -4679,6 +4679,42 @@ object LocalMappedConnector extends Connector with MdcLoggable { } yield { (transactionId, callContext) } + case AGENT_CASH_WITHDRAWAL => + for { + bodyToAgent <- NewStyle.function.tryons(s"$TransactionRequestDetailsExtractException It can not extract to $TransactionRequestBodyAgentJsonV400", 400, callContext) { + body.to_agent.get + } + + toAgentId = bodyToAgent.agent_id + (agent, callContext) <- NewStyle.function.getAgentByAgentId(toAgentId, callContext) + (customerAccountLinks, callContext) <- NewStyle.function.getCustomerAccountLinksByCustomerId(toAgentId, callContext) + customerAccountLink <- NewStyle.function.tryons(AgentAccountLinkNotFound, 400, callContext) { + customerAccountLinks.head + } + (toAccount, callContext) <- NewStyle.function.getBankAccount(BankId(customerAccountLink.bankId), AccountId(customerAccountLink.accountId), callContext) + + agentRequestJsonBody = TransactionRequestBodyAgentJsonV400( + to = AgentIdJson(toAgentId), + value = AmountOfMoneyJsonV121(body.value.currency, body.value.amount), + description = body.description, + charge_policy = transactionRequest.charge_policy, + future_date = transactionRequest.future_date + ) + + (transactionId, callContext) <- NewStyle.function.makePaymentv210( + fromAccount, + toAccount, + transactionRequest.id, + transactionRequestCommonBody = agentRequestJsonBody, + BigDecimal(agentRequestJsonBody.value.amount), + agentRequestJsonBody.description, + TransactionRequestType(transactionRequestType), + transactionRequest.charge_policy, + callContext + ) + } yield { + (transactionId, callContext) + } case SIMPLE => for { bodyToSimple <- NewStyle.function.tryons(s"$TransactionRequestDetailsExtractException It can not extract to $TransactionRequestBodyCounterpartyJSON", 400, callContext) { @@ -4844,11 +4880,11 @@ object LocalMappedConnector extends Connector with MdcLoggable { case transactionRequestType => Future((throw new Exception(s"${InvalidTransactionRequestType}: '${transactionRequestType}'. Not supported in this version.")), callContext) } - _ = saveTransactionRequestTransaction(transactionRequestId, transactionId, callContext) + didSaveTransId <- saveTransactionRequestTransaction(transactionRequestId, transactionId, callContext) + + didSaveStatus <- NewStyle.function.saveTransactionRequestStatusImpl(transactionRequestId, TransactionRequestStatus.COMPLETED.toString, callContext) - _ <- NewStyle.function.saveTransactionRequestStatusImpl(transactionRequestId, TransactionRequestStatus.COMPLETED.toString, callContext) - - //After `makePaymentv200` and update data for request, we get the new requqest from database again. + //After `makePaymentv210` and update data for request, we get the new request from database . (transactionRequest, callContext) <- NewStyle.function.getTransactionRequestImpl(transactionRequestId, callContext) } yield { diff --git a/obp-api/src/main/scala/code/bankconnectors/vSept2018/KafkaMappedConnector_vSept2018.scala b/obp-api/src/main/scala/code/bankconnectors/vSept2018/KafkaMappedConnector_vSept2018.scala index a0686a1eb..d0960d832 100644 --- a/obp-api/src/main/scala/code/bankconnectors/vSept2018/KafkaMappedConnector_vSept2018.scala +++ b/obp-api/src/main/scala/code/bankconnectors/vSept2018/KafkaMappedConnector_vSept2018.scala @@ -3076,24 +3076,27 @@ object KafkaMappedConnector_vSept2018 extends KafkaMappedConnector_vSept2018{ ) } def createObpCustomer(customer : InternalCustomer) : Customer = { - ObpCustomer( + CustomerCommons( customerId = customer.customerId, bankId = customer.bankId, number = customer.number, legalName = customer.legalName, mobileNumber = customer.mobileNumber, email = customer.email, - faceImage = customer.faceImage, + faceImage = CustomerFaceImage(customer.faceImage.date,customer.faceImage.url), dateOfBirth = customer.dateOfBirth, relationshipStatus = customer.relationshipStatus, dependents = customer.dependents, dobOfDependents = customer.dobOfDependents, highestEducationAttained = customer.highestEducationAttained, employmentStatus = customer.employmentStatus, - creditRating = customer.creditRating, - creditLimit = customer.creditLimit, + creditRating = CreditRating(customer.creditRating.rating, customer.creditRating.source), + creditLimit = CreditLimit(customer.creditLimit.amount,customer.creditLimit.currency), kycStatus = customer.kycStatus, lastOkDate = customer.lastOkDate, + title = "", + branchId = "", + nameSuffix = "" ) } diff --git a/obp-api/src/main/scala/code/customer/MappedCustomerProvider.scala b/obp-api/src/main/scala/code/customer/MappedCustomerProvider.scala index 630b2f66e..1d290fbb9 100644 --- a/obp-api/src/main/scala/code/customer/MappedCustomerProvider.scala +++ b/obp-api/src/main/scala/code/customer/MappedCustomerProvider.scala @@ -196,6 +196,8 @@ object MappedCustomerProvider extends CustomerProvider with MdcLoggable { .mTitle(title) .mBranchId(branchId) .mNameSuffix(nameSuffix) + .mIsPendingAgent(true) + .mIsConfirmedAgent(false) .saveMe() // This is especially for OneToMany table, to save a List to database. @@ -361,7 +363,12 @@ class MappedCustomer extends Customer with LongKeyedMapper[MappedCustomer] with object mTitle extends MappedString(this, 255) object mBranchId extends MappedString(this, 255) object mNameSuffix extends MappedString(this, 255) - + object mIsPendingAgent extends MappedBoolean(this){ + override def defaultValue = true + } + object mIsConfirmedAgent extends MappedBoolean(this){ + override def defaultValue = false + } override def customerId: String = mCustomerId.get // id.toString override def bankId: String = mBank.get override def number: String = mNumber.get @@ -395,6 +402,9 @@ class MappedCustomer extends Customer with LongKeyedMapper[MappedCustomer] with override def title: String = mTitle.get override def branchId: String = mBranchId.get override def nameSuffix: String = mNameSuffix.get + + override def isConfirmedAgent = Some(mIsConfirmedAgent.get) + override def isPendingAgent = Some(mIsPendingAgent.get) } object MappedCustomer extends MappedCustomer with LongKeyedMetaMapper[MappedCustomer] { diff --git a/obp-api/src/main/scala/code/transactionrequests/MappedTransactionRequestProvider.scala b/obp-api/src/main/scala/code/transactionrequests/MappedTransactionRequestProvider.scala index cbc4b7aa4..aaf9f0b50 100644 --- a/obp-api/src/main/scala/code/transactionrequests/MappedTransactionRequestProvider.scala +++ b/obp-api/src/main/scala/code/transactionrequests/MappedTransactionRequestProvider.scala @@ -3,6 +3,7 @@ package code.transactionrequests import code.api.util.APIUtil.DateWithMsFormat import code.api.util.CustomJsonFormats import code.api.util.ErrorMessages._ +import code.api.v4_0_0.TransactionRequestBodyAgentJsonV400 import code.bankconnectors.LocalMappedConnectorInternal import code.model._ import code.util.{AccountIdString, UUIDString} @@ -365,6 +366,20 @@ class MappedTransactionRequest extends LongKeyedMapper[MappedTransactionRequest] Some(parsedDetails.extract[TransactionRequestTransferToAccount]) else None + + val t_to_agent = if (TransactionRequestTypes.withName(transactionType) == TransactionRequestTypes.AGENT_CASH_WITHDRAWAL && details.nonEmpty) { + val agentIdList: List[String] = for { + JObject(child) <- parsedDetails + JField("agent_id", JString(agentId)) <- child + } yield + agentId + val agentIdValue = if (agentIdList.isEmpty) "" else agentIdList.head + Some(TransactionRequestAgentId(agent_id = agentIdValue)) + } + else + None + + //This is Berlin Group Types: val t_to_sepa_credit_transfers = if (TransactionRequestTypes.withName(transactionType) == TransactionRequestTypes.SEPA_CREDIT_TRANSFERS && details.nonEmpty) Some(parsedDetails.extract[SepaCreditTransfers]) //TODO, here may need a internal case class, but for now, we used it from request json body. @@ -380,6 +395,7 @@ class MappedTransactionRequest extends LongKeyedMapper[MappedTransactionRequest] to_transfer_to_atm = t_to_transfer_to_atm, to_transfer_to_account = t_to_transfer_to_account, to_sepa_credit_transfers = t_to_sepa_credit_transfers, + to_agent = t_to_agent, value = t_amount, description = mBody_Description.get ) 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 12e208057..f1d9b0384 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 @@ -840,6 +840,9 @@ case class TransactionRequestTransferToAtm( //For COUNTERPARTY, it needs the counterparty_id to find the toCounterparty--> toBankAccount case class TransactionRequestCounterpartyId (counterparty_id : String) +//For AGENT_CASH_WITHDRAWAL, it needs the agent_id to find the toAgent--> toBankAccount +case class TransactionRequestAgentId (agent_id : String) + case class TransactionRequestSimple ( otherBankRoutingScheme: String, otherBankRoutingAddress: String, @@ -951,6 +954,8 @@ case class TransactionRequestBodyAllTypes ( to_transfer_to_account: Option[TransactionRequestTransferToAccount]= None,//TODO not stable @optional to_sepa_credit_transfers: Option[SepaCreditTransfers]= None,//TODO not stable, from berlin Group + @optional + to_agent: Option[TransactionRequestAgentId]= None, value: AmountOfMoney, description: String @@ -1161,29 +1166,6 @@ case class AuthInfo( authViews: List[AuthView] = Nil, ) -case class ObpCustomer( - customerId: String, - bankId: String, - number: String, - legalName: String, - mobileNumber: String, - email: String, - faceImage: CustomerFaceImage, - dateOfBirth: Date, - relationshipStatus: String, - dependents: Integer, - dobOfDependents: List[Date], - highestEducationAttained: String, - employmentStatus: String, - creditRating: CreditRating, - creditLimit: CreditLimit, - kycStatus: lang.Boolean, - lastOkDate: Date, - title: String = "", //These new fields for V310, not from Connector for now. - branchId: String = "", //These new fields for V310, not from Connector for now. - nameSuffix: String = "", //These new fields for V310, not from Connector for now. -) extends Customer - case class InternalCustomer( customerId: String, bankId: String, diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/model/CustomerDataModel.scala b/obp-commons/src/main/scala/com/openbankproject/commons/model/CustomerDataModel.scala index 3611e2cb5..c6757c651 100644 --- a/obp-commons/src/main/scala/com/openbankproject/commons/model/CustomerDataModel.scala +++ b/obp-commons/src/main/scala/com/openbankproject/commons/model/CustomerDataModel.scala @@ -53,6 +53,9 @@ trait Customer { def title: String def branchId: String def nameSuffix: String + + def isConfirmedAgent: Option[Boolean] = None //this is for agent + def isPendingAgent: Option[Boolean]= None // this is for agent } trait CustomerFaceImageTrait {