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 0b3cb7873..4a5139885 100644 --- a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala +++ b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala @@ -530,7 +530,8 @@ object ErrorMessages { val AgentsNotFound = "OBP-30326: Agents not found." val CreateAgentAccountLinkError = "OBP-30327: Could not create the agent account link." val AgentNumberAlreadyExists = "OBP-30328: Agent Number already exists. Please specify a different value for BANK_ID or AGENT_NUMBER." - val GetAgentAccountLinksError = "OBP-30226: Could not get the agent account links." + val GetAgentAccountLinksError = "OBP-30329: Could not get the agent account links." + val AgentBeneficiaryPermit = "OBP-30330: The account can not send money to the Agent. Please set the Agent 'is_confirmed_agent' true and `is_pending_agent` false." // Branch related messages val BranchesNotFoundLicense = "OBP-32001: No branches available. License may not be set." 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 1ef1fe12c..3b1feb758 100644 --- a/obp-api/src/main/scala/code/api/util/NewStyle.scala +++ b/obp-api/src/main/scala/code/api/util/NewStyle.scala @@ -2844,14 +2844,14 @@ object NewStyle extends MdcLoggable{ bankId: String, legalName : String, mobileNumber : String, - number : String, + agentNumber : String, callContext: Option[CallContext] ): OBPReturnType[Agent] = Connector.connector.vend.createAgent( bankId: String, legalName : String, mobileNumber : String, - number : String, + agentNumber : String, callContext: Option[CallContext] ) map { i => (unboxFullOrFail(i._1, callContext, CreateAgentError), i._2) 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 19ee121b2..5321d8b66 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 @@ -12632,11 +12632,15 @@ object APIMethods400 extends RestHelper with APIMethods400 { json.extract[TransactionRequestBodyAgentJsonV400] } (agent, callContext) <- NewStyle.function.getAgentByAgentNumber(BankId(transactionRequestBodyAgent.to.bank_id),transactionRequestBodyAgent.to.agent_number, callContext) - (customerAccountLinks, callContext) <- NewStyle.function.getCustomerAccountLinksByCustomerId(agent.agentId, callContext) - customerAccountLink <- NewStyle.function.tryons(AgentAccountLinkNotFound, 400, callContext) { - customerAccountLinks.head + (agentAccountLinks, callContext) <- NewStyle.function.getAgentAccountLinksByAgentId(agent.agentId, callContext) + agentAccountLink <- NewStyle.function.tryons(AgentAccountLinkNotFound, 400, callContext) { + agentAccountLinks.head } - (toAccount, callContext) <- NewStyle.function.getBankAccount(BankId(customerAccountLink.bankId), AccountId(customerAccountLink.accountId), callContext) + // Check we can send money to it. + _ <- Helper.booleanToFuture(s"$AgentBeneficiaryPermit", cc=callContext) { + !agent.isPendingAgent && agent.isConfirmedAgent + } + (toAccount, callContext) <- NewStyle.function.getBankAccount(BankId(agentAccountLink.bankId), AccountId(agentAccountLink.accountId), callContext) chargePolicy = transactionRequestBodyAgent.charge_policy _ <- Helper.booleanToFuture(s"$InvalidChargePolicy", cc=callContext) { ChargePolicy.values.contains(ChargePolicy.withName(chargePolicy)) 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 e123717a0..d2db48041 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 @@ -1,13 +1,12 @@ package code.api.v5_0_0 -import java.util.concurrent.ThreadLocalRandom import code.accountattribute.AccountAttributeX -import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ import code.api.util.APIUtil._ import code.api.util.ApiRole._ import code.api.util.ApiTag._ import code.api.util.ErrorMessages._ +import code.api.util.FutureUtil.EndpointContext import code.api.util.NewStyle.HttpCode import code.api.util.NewStyle.function.extractQueryParams import code.api.util._ @@ -15,26 +14,25 @@ import code.api.v2_1_0.JSONFactory210 import code.api.v3_0_0.JSONFactory300 import code.api.v3_1_0._ import code.api.v4_0_0.JSONFactory400.createCustomersMinimalJson -import code.api.v4_0_0.{JSONFactory400, OBPAPI4_0_0, PostCounterpartyJson400, PutProductJsonV400} +import code.api.v4_0_0.{JSONFactory400, PostCounterpartyJson400} import code.api.v5_0_0.JSONFactory500.{createPhysicalCardJson, createViewJsonV500, createViewsIdsJsonV500, createViewsJsonV500} +import code.api.v5_1_0.{CreateCustomViewJson, PostCounterpartyLimitV510, PostVRPConsentRequestJsonV510} import code.bankconnectors.Connector -import code.consent.{ConsentRequest, ConsentRequests, Consents} +import code.consent.{ConsentRequests, Consents} +import code.consumer.Consumers import code.entitlement.Entitlement +import code.metadata.counterparties.MappedCounterparty import code.metrics.APIMetrics -import code.model._ import code.model.dataAccess.BankAccountCreation -import com.openbankproject.commons.model.enums.TransactionRequestTypes._ -import com.openbankproject.commons.model.enums.TransactionRequestTypes import code.util.Helper import code.util.Helper.{SILENCE_IS_GOLDEN, booleanToFuture} import code.views.Views +import code.views.system.ViewDefinition import com.github.dwickern.macros.NameOf.nameOf import com.openbankproject.commons.ExecutionContext.Implicits.global -import com.openbankproject.commons.model.enums.StrongCustomerAuthentication import com.openbankproject.commons.model._ +import com.openbankproject.commons.model.enums.StrongCustomerAuthentication import com.openbankproject.commons.util.ApiVersion -import com.openbankproject.commons.model.enums.TransactionRequestTypes._ -import com.openbankproject.commons.model.enums.PaymentServiceTypes._ import net.liftweb.common.{Empty, Full} import net.liftweb.http.Req import net.liftweb.http.rest.RestHelper @@ -42,18 +40,9 @@ import net.liftweb.json import net.liftweb.json.{Extraction, compactRender, prettyRender} import net.liftweb.util.Helpers.tryo import net.liftweb.util.{Helpers, Props, StringHelpers} -import java.util.concurrent.ThreadLocalRandom - -import code.accountattribute.AccountAttributeX -import code.api.Constant.SYSTEM_OWNER_VIEW_ID -import code.api.util.FutureUtil.EndpointContext -import code.api.v5_1_0.{CreateCustomViewJson, PostVRPConsentRequestJsonV510, PostCounterpartyLimitV510} -import code.consumer.Consumers -import code.metadata.counterparties.MappedCounterparty -import code.util.Helper.booleanToFuture -import code.views.system.{AccountAccess, ViewDefinition} import java.util.UUID +import java.util.concurrent.ThreadLocalRandom import scala.collection.immutable.{List, Nil} import scala.collection.mutable.ArrayBuffer import scala.concurrent.Future 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 46fa5d219..070307a93 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 @@ -19,9 +19,8 @@ import code.api.util.newstyle.RegulatedEntityNewStyle.{createRegulatedEntityNewS import code.api.v2_1_0.ConsumerRedirectUrlJSON import code.api.v3_0_0.JSONFactory300 import code.api.v3_0_0.JSONFactory300.createAggregateMetricJson -import code.api.v3_1_0.{ConsentJsonV310, JSONFactory310} +import code.api.v3_1_0.ConsentJsonV310 import code.api.v3_1_0.JSONFactory310.createBadLoginStatusJson -import code.api.v4_0_0.APIMethods400.{createTransactionRequest, transactionRequestGeneralText} import code.api.v4_0_0.JSONFactory400.{createAccountBalancesJson, createBalancesJson, createNewCoreBankAccountJson} import code.api.v4_0_0.{JSONFactory400, PostAccountAccessJsonV400, PostApiCollectionJson400, RevokedJsonV400} import code.api.v5_0_0.JSONFactory500 @@ -381,7 +380,7 @@ trait APIMethods510 { bankId = bankId.value, legalName = putData.legal_name, mobileNumber = putData.mobile_phone_number, - number = putData.agent_number, + agentNumber = putData.agent_number, callContext, ) (bankAccount, callContext) <- NewStyle.function.createBankAccount( diff --git a/obp-api/src/main/scala/code/bankconnectors/Connector.scala b/obp-api/src/main/scala/code/bankconnectors/Connector.scala index ed98ede63..48c6c8bd0 100644 --- a/obp-api/src/main/scala/code/bankconnectors/Connector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/Connector.scala @@ -1150,7 +1150,7 @@ trait Connector extends MdcLoggable { bankId: String, legalName : String, mobileNumber : String, - number : String, + agentNumber : String, callContext: Option[CallContext] ): OBPReturnType[Box[Agent]] = Future{(Failure(setUnimplementedError(nameOf(createAgent _))), callContext)} diff --git a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala index 56eb8ed43..086858bb8 100644 --- a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -1629,14 +1629,14 @@ object LocalMappedConnector extends Connector with MdcLoggable { bankId: String, legalName : String, mobileNumber : String, - number : String, + agentNumber : String, callContext: Option[CallContext] ): OBPReturnType[Box[Agent]] = { AgentX.agentProvider.vend.createAgent( bankId: String, legalName : String, mobileNumber : String, - number : String, + agentNumber : String, callContext: Option[CallContext] ).map((_, callContext)) } @@ -4757,11 +4757,11 @@ object LocalMappedConnector extends Connector with MdcLoggable { body.to_agent.get } (agent, callContext) <- NewStyle.function.getAgentByAgentNumber(BankId(bodyToAgent.bank_id), bodyToAgent.agent_number, callContext) - (customerAccountLinks, callContext) <- NewStyle.function.getCustomerAccountLinksByCustomerId(agent.agentId, callContext) - customerAccountLink <- NewStyle.function.tryons(AgentAccountLinkNotFound, 400, callContext) { - customerAccountLinks.head + (agentAccountLinks, callContext) <- NewStyle.function.getAgentAccountLinksByAgentId(agent.agentId, callContext) + agentAccountLink <- NewStyle.function.tryons(AgentAccountLinkNotFound, 400, callContext) { + agentAccountLinks.head } - (toAccount, callContext) <- NewStyle.function.getBankAccount(BankId(customerAccountLink.bankId), AccountId(customerAccountLink.accountId), callContext) + (toAccount, callContext) <- NewStyle.function.getBankAccount(BankId(agentAccountLink.bankId), AccountId(agentAccountLink.accountId), callContext) agentRequestJsonBody = TransactionRequestBodyAgentJsonV400( to = AgentCashWithdrawalJson(bodyToAgent.bank_id, bodyToAgent.agent_number), diff --git a/obp-api/src/main/scala/code/customer/agent/AgentProvider.scala b/obp-api/src/main/scala/code/customer/agent/AgentProvider.scala index b4737d51d..e78aebf7c 100644 --- a/obp-api/src/main/scala/code/customer/agent/AgentProvider.scala +++ b/obp-api/src/main/scala/code/customer/agent/AgentProvider.scala @@ -41,7 +41,7 @@ trait AgentProvider { bankId: String, legalName : String, mobileNumber : String, - number : String, + agentNumber : String, callContext: Option[CallContext] ): Future[Box[Agent]] diff --git a/obp-api/src/main/scala/code/customer/agent/MappedAgentProvider.scala b/obp-api/src/main/scala/code/customer/agent/MappedAgentProvider.scala index c69b8afae..3a9e877d0 100644 --- a/obp-api/src/main/scala/code/customer/agent/MappedAgentProvider.scala +++ b/obp-api/src/main/scala/code/customer/agent/MappedAgentProvider.scala @@ -42,10 +42,10 @@ object MappedAgentProvider extends AgentProvider with MdcLoggable { } - override def checkAgentNumberAvailable(bankId: BankId, customerNumber: String): Boolean = { + override def checkAgentNumberAvailable(bankId: BankId, agentNumber: String): Boolean = { val customers = MappedCustomer.findAll( By(MappedCustomer.mBank, bankId.value), - By(MappedCustomer.mNumber, customerNumber) + By(MappedCustomer.mNumber, agentNumber) ) val available: Boolean = customers.size match { @@ -87,7 +87,7 @@ object MappedAgentProvider extends AgentProvider with MdcLoggable { bankId: String, legalName: String, mobileNumber: String, - number: String, + agentNumber: String, callContext: Option[CallContext] ): Future[Box[Agent]] = Future { tryo { @@ -96,7 +96,7 @@ object MappedAgentProvider extends AgentProvider with MdcLoggable { .mBank(bankId) .mLegalName(legalName) .mMobileNumber(mobileNumber) - .mNumber(number) + .mNumber(agentNumber) .mIsPendingAgent(true) //default value .mIsConfirmedAgent(false) // default value .saveMe() diff --git a/obp-api/src/test/scala/code/api/v4_0_0/TransactionRequestsTest.scala b/obp-api/src/test/scala/code/api/v4_0_0/TransactionRequestsTest.scala index 77f8890c5..1da1d41d8 100644 --- a/obp-api/src/test/scala/code/api/v4_0_0/TransactionRequestsTest.scala +++ b/obp-api/src/test/scala/code/api/v4_0_0/TransactionRequestsTest.scala @@ -1,6 +1,7 @@ package code.api.v4_0_0 import code.api.Constant + import java.util.{Date, UUID} import code.api.ChargePolicy import code.api.Constant._ @@ -8,7 +9,7 @@ import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.{createPhysicalCardJsonV500, postAgentJsonV510} import code.api.util.APIUtil.OAuth._ import code.api.util.APIUtil.extractErrorMessageCode -import code.api.util.ApiRole.{CanCreateAnyTransactionRequest, CanCreateCardsForBank} +import code.api.util.ApiRole.{CanCreateAnyTransactionRequest, CanCreateCardsForBank, canUpdateAgentStatusAtAnyBank} import code.api.util.ErrorMessages._ import code.api.util.{APIUtil, ErrorMessages} import code.api.v1_4_0.JSONFactory1_4_0.{ChallengeAnswerJSON, TransactionRequestAccountJsonV140} @@ -16,7 +17,7 @@ import code.api.v2_0_0.TransactionRequestBodyJsonV200 import code.api.v2_1_0._ import code.api.v4_0_0.APIMethods400.Implementations4_0_0 import code.api.v5_0_0.PhysicalCardJsonV500 -import code.api.v5_1_0.AgentJsonV510 +import code.api.v5_1_0.{AgentJsonV510, PutAgentJsonV510} import code.bankconnectors.Connector import code.entitlement.Entitlement import code.fx.fx @@ -134,6 +135,19 @@ class TransactionRequestsTest extends V400ServerSetup with DefaultUsers { val request = (v5_1_0_Request / "banks" / bankId.value / "agents").POST <@ (user1) val response = makePostRequest(request, write(postAgentJsonV510.copy(currency=fromAccount.currency))) val agentCashWithdrawalAgent = response.body.extract[AgentJsonV510] + + { + val putAgentJsonV510 = PutAgentJsonV510( + is_pending_agent = false, + is_confirmed_agent = true + ) + Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, canUpdateAgentStatusAtAnyBank.toString) + val request = (v5_1_0_Request / "banks" / bankId.value / "agents"/ agentCashWithdrawalAgent.agent_id).PUT <@ user1 + val response = makePutRequest(request, write(putAgentJsonV510)) + response.code should equal(200) + response.body.extract[AgentJsonV510].is_pending_agent should equal(putAgentJsonV510.is_pending_agent) + response.body.extract[AgentJsonV510].is_confirmed_agent should equal(putAgentJsonV510.is_confirmed_agent) + } var transactionRequestBodySEPA = TransactionRequestBodySEPAJSON(bodyValue, IbanJson(counterpartySEPA.otherAccountSecondaryRoutingAddress), description, sharedChargePolicy)