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 995c8130b..9029dcb73 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 @@ -4832,6 +4832,26 @@ object SwaggerDefinitionsJSON { card_attributes = List(cardAttributeCommons), brand = brandExample.value ) + + val createCustomerAccountLinkJson = CreateCustomerAccountLinkJson( + customer_id = customerIdExample.value, + account_id = accountIdExample.value, + relationship_type= relationshipTypeExample.value + ) + val updateCustomerAccountLinkJson = UpdateCustomerAccountLinkJson( + relationship_type= relationshipTypeExample.value + ) + + val customerAccountLinkJson = CustomerAccountLinkJson( + customer_account_link_id = customerAccountLinkIdExample.value, + customer_id = customerIdExample.value, + account_id = accountIdExample.value, + relationship_type= relationshipTypeExample.value + ) + + val customerAccountLinksJson = CustomerAccountLinksJson( + List(customerAccountLinkJson) + ) //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/ApiRole.scala b/obp-api/src/main/scala/code/api/util/ApiRole.scala index 839f28d30..9c204c755 100644 --- a/obp-api/src/main/scala/code/api/util/ApiRole.scala +++ b/obp-api/src/main/scala/code/api/util/ApiRole.scala @@ -243,6 +243,21 @@ object ApiRole { case class CanGetCardsForBank(requiresBankId: Boolean = true) extends ApiRole lazy val canGetCardsForBank = CanGetCardsForBank() + + case class CanCreateCustomerAccountLink(requiresBankId: Boolean = true) extends ApiRole + lazy val canCreateCustomerAccountLink = CanCreateCustomerAccountLink() + + case class CanUpdateCustomerAccountLink(requiresBankId: Boolean = true) extends ApiRole + lazy val canUpdateCustomerAccountLink = CanUpdateCustomerAccountLink() + + case class CanDeleteCustomerAccountLink(requiresBankId: Boolean = true) extends ApiRole + lazy val canDeleteCustomerAccountLink = CanDeleteCustomerAccountLink() + + case class CanGetCustomerAccountLink(requiresBankId: Boolean = true) extends ApiRole + lazy val canGetCustomerAccountLink = CanGetCustomerAccountLink() + + case class CanGetCustomerAccountLinks(requiresBankId: Boolean = true) extends ApiRole + lazy val canGetCustomerAccountLinks = CanGetCustomerAccountLinks() case class CanCreateBranch(requiresBankId: Boolean = true) extends ApiRole lazy val canCreateBranch = CanCreateBranch() 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 6736ad631..a5dca7aaa 100644 --- a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala +++ b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala @@ -429,6 +429,12 @@ object ErrorMessages { val EntitlementCannotBeGrantedGrantorIssue = "OBP-30221: Entitlement cannot be granted due to the grantor's insufficient privileges." val CounterpartyNotFoundByRoutings = "OBP-30222: Counterparty not found. Please specify valid value for Routings." + val AccountAlreadyExistsForCustomer = "OBP-30223: The Account is already linked to a Customer at the bank specified by BANK_ID" + val CreateCustomerAccountLinkError = "OBP-30224: Could not create the customer account link." + val CustomerAccountLinkNotFoundById = "OBP-30225: Customer Account Link not found. Please specify valid values for CUSTOMER_ACCOUNT_LINK_ID." + val GetCustomerAccountLinksError = "OBP-30226: Could not get the customer account links." + val UpdateCustomerAccountLinkError = "OBP-30227: Could not update the customer account link." + val DeleteCustomerAccountLinkError = "OBP-30227: Could not delete the customer account link." val CreateSystemViewError = "OBP-30250: Could not create the system view" val DeleteSystemViewError = "OBP-30251: Could not delete the system view" diff --git a/obp-api/src/main/scala/code/api/util/ExampleValue.scala b/obp-api/src/main/scala/code/api/util/ExampleValue.scala index 6a9d623fb..72e471c31 100644 --- a/obp-api/src/main/scala/code/api/util/ExampleValue.scala +++ b/obp-api/src/main/scala/code/api/util/ExampleValue.scala @@ -40,7 +40,10 @@ object ExampleValue { lazy val sessionIdExample = ConnectorField("b4e0352a-9a0f-4bfa-b30b-9003aa467f50", s"A string that MUST uniquely identify the session on this OBP instance, can be used in all cache. ") lazy val userIdExample = ConnectorField("9ca9a7e4-6d02-40e3-a129-0b2bf89de9b1", s"A string that MUST uniquely identify the user on this OBP instance.") - glossaryItems += makeGlossaryItem("User.userId", userIdExample) + glossaryItems += makeGlossaryItem("User.userId", userIdExample) + + lazy val relationshipTypeExample = ConnectorField("Owner", s"Relationship between two parties.") + glossaryItems += makeGlossaryItem("Customer.relationshipType", relationshipTypeExample) lazy val usernameExample = ConnectorField("felixsmith", s"The username the user uses to authenticate.") @@ -59,6 +62,9 @@ object ExampleValue { lazy val customerIdExample = ConnectorField("7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", s"A non human friendly string that identifies the customer and is used in URLs. This SHOULD NOT be the customer number. The combination of customerId and bankId MUST be unique on an OBP instance. customerId SHOULD be unique on an OBP instance. Ideally customerId is a UUID. A mapping between customer number and customer id is kept in OBP.") glossaryItems += makeGlossaryItem("Customer.customerId", customerIdExample) + + lazy val customerAccountLinkIdExample = ConnectorField("xyz8a7e4-6d02-40e3-a129-0b2bf89de8uh", s"A non human friendly string that identifies the customer Account Link and is used in URLs. ") + glossaryItems += makeGlossaryItem("Customer.customerAccountLinkId", customerAccountLinkIdExample) lazy val customerAttributeId = ConnectorField("7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", s"A non human friendly string that identifies the customer attribute and is used in URLs.") glossaryItems += makeGlossaryItem("Customer.customerAttributeId", customerAttributeId) 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 97ac994d6..01dc87d70 100644 --- a/obp-api/src/main/scala/code/api/util/NewStyle.scala +++ b/obp-api/src/main/scala/code/api/util/NewStyle.scala @@ -3,7 +3,6 @@ package code.api.util import java.util.Date import java.util.UUID.randomUUID - import akka.http.scaladsl.model.HttpMethod import code.DynamicEndpoint.{DynamicEndpointProvider, DynamicEndpointT} import code.api.{APIFailureNewStyle, Constant, JsonResponseException} @@ -69,6 +68,7 @@ import code.api.v4_0_0.JSONFactory400 import code.api.dynamic.endpoint.helper.DynamicEndpointHelper import code.bankattribute.BankAttribute import code.connectormethod.{ConnectorMethodProvider, JsonConnectorMethod} +import code.customeraccountlinks.CustomerAccountLinkTrait import code.dynamicMessageDoc.{DynamicMessageDocProvider, JsonDynamicMessageDoc} import code.dynamicResourceDoc.{DynamicResourceDocProvider, JsonDynamicResourceDoc} import code.endpointMapping.{EndpointMappingProvider, EndpointMappingT} @@ -3740,5 +3740,36 @@ object NewStyle extends MdcLoggable{ i => (connectorEmptyResponse(i._1, callContext), i._2) } } + + def createCustomerAccountLink(customerId: String, accountId: String, relationshipType: String, callContext: Option[CallContext]): OBPReturnType[CustomerAccountLinkTrait] = + Connector.connector.vend.createCustomerAccountLink(customerId: String, accountId: String, relationshipType: String, callContext: Option[CallContext]) map { + i => (unboxFullOrFail(i._1, callContext, CreateCustomerAccountLinkError), i._2) + } + + def getCustomerAccountLinksByCustomerId(customerId: String, callContext: Option[CallContext]): OBPReturnType[List[CustomerAccountLinkTrait]] = + Connector.connector.vend.getCustomerAccountLinksByCustomerId(customerId: String, callContext: Option[CallContext]) map { + i => (unboxFullOrFail(i._1, callContext, GetCustomerAccountLinksError), i._2) + } + + def getCustomerAccountLinksByAccountId(accountId: String, callContext: Option[CallContext]): OBPReturnType[List[CustomerAccountLinkTrait]] = + Connector.connector.vend.getCustomerAccountLinksByAccountId(accountId: String, callContext: Option[CallContext]) map { + i => (unboxFullOrFail(i._1, callContext, GetCustomerAccountLinksError), i._2) + } + + def getCustomerAccountLinkById(customerAccountLinkId: String, callContext: Option[CallContext]): OBPReturnType[CustomerAccountLinkTrait] = + Connector.connector.vend.getCustomerAccountLinkById(customerAccountLinkId: String, callContext: Option[CallContext]) map { + i => (unboxFullOrFail(i._1, callContext, CustomerAccountLinkNotFoundById), i._2) + } + + def deleteCustomerAccountLinkById(customerAccountLinkId: String, callContext: Option[CallContext]): OBPReturnType[Boolean] = + Connector.connector.vend.deleteCustomerAccountLinkById(customerAccountLinkId: String, callContext: Option[CallContext]) map { + i => (unboxFullOrFail(i._1, callContext, DeleteCustomerAccountLinkError), i._2) + } + + def updateCustomerAccountLinkById(customerAccountLinkId: String, relationshipType: String, callContext: Option[CallContext]): OBPReturnType[CustomerAccountLinkTrait] = + Connector.connector.vend.updateCustomerAccountLinkById(customerAccountLinkId: String, relationshipType: String, callContext: Option[CallContext]) map { + i => (unboxFullOrFail(i._1, callContext, UpdateCustomerAccountLinkError), i._2) + } } + } 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 149e991ed..b6a78ff8e 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,7 +1,6 @@ package code.api.v5_0_0 import java.util.Date - import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ import code.api.util.APIUtil._ import code.api.util.ApiRole._ @@ -38,6 +37,7 @@ import net.liftweb.util.Props import java.util.concurrent.ThreadLocalRandom import code.accountattribute.AccountAttributeX +import code.util.Helper.booleanToFuture import scala.collection.immutable.{List, Nil} import scala.collection.mutable.ArrayBuffer @@ -1398,6 +1398,235 @@ trait APIMethods500 { } } + staticResourceDocs += ResourceDoc( + createCustomerAccountLink, + implementedInApiVersion, + nameOf(createCustomerAccountLink), + "POST", + "/banks/BANK_ID/customer_account_links", + "Create Customer Account Link", + s"""Link a Customer to a Account + | + |${authenticationRequiredMessage(true)} + | + |""", + createCustomerAccountLinkJson, + customerAccountLinkJson, + List( + $UserNotLoggedIn, + $BankNotFound, + BankAccountNotFound, + InvalidJsonFormat, + CustomerNotFoundByCustomerId, + UserHasMissingRoles, + AccountAlreadyExistsForCustomer, + CreateCustomerAccountLinkError, + UnknownError + ), + List(apiTagCustomer, apiTagAccount), + Some(List(canCreateCustomerAccountLink))) + lazy val createCustomerAccountLink : OBPEndpoint = { + case "banks" :: BankId(bankId):: "customer_account_links" :: Nil JsonPost json -> _ => { + cc => + for { + postedData <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the $CreateCustomerAccountLinkJson ", 400, cc.callContext) { + json.extract[CreateCustomerAccountLinkJson] + } + (customer, callContext) <- NewStyle.function.getCustomerByCustomerId(postedData.customer_id, cc.callContext) + _ <- booleanToFuture(s"Bank of the customer specified by the CUSTOMER_ID(${customer.bankId}) has to matches BANK_ID(${bankId.value}) in URL", 400, callContext) { + customer.bankId == bankId.value + } + (_, callContext) <- NewStyle.function.getBankAccount(bankId, AccountId(postedData.account_id), callContext) + _ <- booleanToFuture("Field customer_id is not defined in the posted json!", 400, callContext) { + postedData.customer_id.nonEmpty + } + (customerAccountLinkExists, callContext) <- Connector.connector.vend.getCustomerAccountLink(postedData.customer_id, postedData.account_id, callContext) + _ <- booleanToFuture(AccountAlreadyExistsForCustomer, 400, callContext) { + customerAccountLinkExists.isEmpty + } + (customerAccountLink, callContext) <- NewStyle.function.createCustomerAccountLink(postedData.customer_id, postedData.account_id, postedData.relationship_type, callContext) + } yield { + (JSONFactory500.createCustomerAccountLinkJson(customerAccountLink), HttpCode.`201`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( + getCustomerAccountLinksByCustomerId, + implementedInApiVersion, + nameOf(getCustomerAccountLinksByCustomerId), + "GET", + "/banks/BANK_ID/customers/CUSTOMER_ID/customer_account_links", + "Get Customer Account Links by CUSTOMER_ID", + s""" Get Customer Account Links by CUSTOMER_ID + | + |${authenticationRequiredMessage(true)} + | + |""", + EmptyBody, + customerAccountLinksJson, + List( + $UserNotLoggedIn, + $BankNotFound, + CustomerNotFoundByCustomerId, + UserHasMissingRoles, + UnknownError + ), + List(apiTagCustomer, apiTagNewStyle), + Some(List(canGetCustomerAccountLinks))) + lazy val getCustomerAccountLinksByCustomerId : OBPEndpoint = { + case "banks" :: BankId(bankId) :: "customers" :: customerId :: "customer_account_links" :: Nil JsonGet _ => { + cc => + for { + (customer, callContext) <- NewStyle.function.getCustomerByCustomerId(customerId, cc.callContext) + _ <- booleanToFuture(s"Bank of the customer specified by the CUSTOMER_ID(${customer.bankId}) has to matches BANK_ID(${bankId.value}) in URL", 400, callContext) { + customer.bankId == bankId.value + } + (customerAccountLinks, callContext) <- NewStyle.function.getCustomerAccountLinksByCustomerId(customerId, callContext) + } yield { + (JSONFactory500.createCustomerAccountLinksJon(customerAccountLinks), HttpCode.`200`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( + getCustomerAccountLinksByAccountId, + implementedInApiVersion, + nameOf(getCustomerAccountLinksByAccountId), + "GET", + "/banks/BANK_ID/accounts/ACCOUNT_ID/customer_account_links", + "Get Customer Account Links by ACCOUNT_ID", + s""" Get Customer Account Links by ACCOUNT_ID + | + |${authenticationRequiredMessage(true)} + | + |""", + EmptyBody, + customerAccountLinksJson, + List( + $UserNotLoggedIn, + $BankNotFound, + BankAccountNotFound, + UserHasMissingRoles, + UnknownError + ), + List(apiTagCustomer, apiTagNewStyle), + Some(List(canGetCustomerAccountLinks))) + lazy val getCustomerAccountLinksByAccountId : OBPEndpoint = { + case "banks" :: BankId(bankId) :: "accounts" :: accountId :: "customer_account_links" :: Nil JsonGet _ => { + cc => + for { + (customerAccountLinks, callContext) <- NewStyle.function.getCustomerAccountLinksByAccountId(accountId, cc.callContext) + } yield { + (JSONFactory500.createCustomerAccountLinksJon(customerAccountLinks), HttpCode.`200`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( + getCustomerAccountLinkById, + implementedInApiVersion, + nameOf(getCustomerAccountLinkById), + "GET", + "/banks/BANK_ID/customer_account_links/CUSTOMER_ACCOUNT_LINK_ID", + "Get Customer Account Link by Id", + s""" Get Customer Account Link by CUSTOMER_ACCOUNT_LINK_ID + | + |${authenticationRequiredMessage(true)} + | + |""", + EmptyBody, + customerAccountLinkJson, + List( + $UserNotLoggedIn, + $BankNotFound, + UserHasMissingRoles, + UnknownError + ), + List(apiTagCustomer, apiTagNewStyle), + Some(List(canGetCustomerAccountLink))) + lazy val getCustomerAccountLinkById : OBPEndpoint = { + case "banks" :: BankId(bankId) :: "customer_account_links" :: customerAccountLinkId :: Nil JsonGet _ => { + cc => + for { + (customerAccountLink, callContext) <- NewStyle.function.getCustomerAccountLinkById(customerAccountLinkId, cc.callContext) + } yield { + (JSONFactory500.createCustomerAccountLinkJson(customerAccountLink), HttpCode.`200`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( + updateCustomerAccountLinkById, + implementedInApiVersion, + nameOf(updateCustomerAccountLinkById), + "PUT", + "/banks/BANK_ID/customer_account_links/CUSTOMER_ACCOUNT_LINK_ID", + "Update Customer Account Link by Id", + s""" Update Customer Account Link by CUSTOMER_ACCOUNT_LINK_ID + | + |${authenticationRequiredMessage(true)} + | + |""", + EmptyBody, + customerAccountLinkJson, + List( + $UserNotLoggedIn, + $BankNotFound, + UserHasMissingRoles, + UnknownError + ), + List(apiTagCustomer, apiTagNewStyle), + Some(List(canUpdateCustomerAccountLink))) + lazy val updateCustomerAccountLinkById : OBPEndpoint = { + case "banks" :: BankId(bankId) :: "customer_account_links" :: customerAccountLinkId :: Nil JsonPut json -> _ => { + cc => + for { + postedData <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the $UpdateCustomerAccountLinkJson ", 400, cc.callContext) { + json.extract[CreateCustomerAccountLinkJson] + } + (_, callContext) <- NewStyle.function.getCustomerAccountLinkById(customerAccountLinkId, cc.callContext) + + (customerAccountLink, callContext) <- NewStyle.function.updateCustomerAccountLinkById(customerAccountLinkId, postedData.relationship_type, callContext) + } yield { + (JSONFactory500.createCustomerAccountLinkJson(customerAccountLink), HttpCode.`200`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( + deleteCustomerAccountLinkById, + implementedInApiVersion, + nameOf(deleteCustomerAccountLinkById), + "DELETE", + "/banks/BANK_ID/customer_account_links/CUSTOMER_ACCOUNT_LINK_ID", + "Delete Customer Account Link", + s""" Delete Customer Account Link by CUSTOMER_ACCOUNT_LINK_ID + | + |${authenticationRequiredMessage(true)} + | + |""", + EmptyBody, + EmptyBody, + List( + $UserNotLoggedIn, + $BankNotFound, + UserHasMissingRoles, + UnknownError + ), + List(apiTagCustomer, apiTagNewStyle), + Some(List(canDeleteCustomerAccountLink))) + lazy val deleteCustomerAccountLinkById : OBPEndpoint = { + case "banks" :: BankId(bankId) :: "customer_account_links" :: customerAccountLinkId :: Nil JsonDelete _ => { + cc => + for { + (_, callContext) <- NewStyle.function.getCustomerAccountLinkById(customerAccountLinkId, cc.callContext) + (deleted, callContext) <- NewStyle.function.deleteCustomerAccountLinkById(customerAccountLinkId, callContext) + } yield { + (Full(deleted), HttpCode.`200`(callContext)) + } + } + } } } diff --git a/obp-api/src/main/scala/code/api/v5_0_0/JSONFactory5.0.0.scala b/obp-api/src/main/scala/code/api/v5_0_0/JSONFactory5.0.0.scala index 9d450e0e9..662d8dcc0 100644 --- a/obp-api/src/main/scala/code/api/v5_0_0/JSONFactory5.0.0.scala +++ b/obp-api/src/main/scala/code/api/v5_0_0/JSONFactory5.0.0.scala @@ -28,7 +28,6 @@ package code.api.v5_0_0 import java.lang import java.util.Date - import code.api.util.APIUtil.{stringOptionOrNull, stringOrNull} import code.api.v1_2_1.BankRoutingJsonV121 import code.api.v1_4_0.JSONFactory1_4_0.{CustomerFaceImageJson, MetaJsonV140} @@ -40,6 +39,7 @@ import code.api.v3_0_0.{CustomerAttributeResponseJsonV300, JSONFactory300} import code.api.v3_1_0.{AccountAttributeResponseJson, AccountBasicV310, CustomerWithAttributesJsonV310, PhysicalCardWithAttributesJsonV310, PostConsentEntitlementJsonV310} import code.api.v4_0_0.BankAttributeBankResponseJsonV400 import code.bankattribute.BankAttribute +import code.customeraccountlinks.CustomerAccountLinkTrait import com.openbankproject.commons.model.{AccountAttribute, AccountRouting, AccountRoutingJsonV121, AmountOfMoneyJsonV121, Bank, BankAccount, CardAttribute, Customer, CustomerAttribute, PhysicalCardTrait, User, UserAuthContext, UserAuthContextUpdate, View, ViewBasic} import net.liftweb.json.JsonAST.JValue @@ -315,6 +315,28 @@ case class UpdatePhysicalCardJsonV500( brand: String ) +case class CreateCustomerAccountLinkJson( + customer_id: String, + account_id: String, + relationship_type: String +) + +case class UpdateCustomerAccountLinkJson( + relationship_type: String +) + +case class CustomerAccountLinkJson( + customer_account_link_id: String, + customer_id: String, + account_id: String, + relationship_type: String +) + +case class CustomerAccountLinksJson( + links:List[CustomerAccountLinkJson] +) + + object JSONFactory500 { def createUserAuthContextJson(userAuthContext: UserAuthContext): UserAuthContextJsonV500 = { @@ -478,5 +500,19 @@ object JSONFactory500 { brand = stringOptionOrNull(card.brand) ) } + + def createCustomerAccountLinkJson(customerAccountLink: CustomerAccountLinkTrait): CustomerAccountLinkJson ={ + CustomerAccountLinkJson( + customerAccountLink.customerAccountLinkId, + customerAccountLink.customerId, + customerAccountLink.accountId, + customerAccountLink.relationshipType + ) + } + + def createCustomerAccountLinksJon(customerAccountLinks: List[CustomerAccountLinkTrait]): CustomerAccountLinksJson = { + CustomerAccountLinksJson(customerAccountLinks.map(createCustomerAccountLinkJson)) + } + } diff --git a/obp-api/src/main/scala/code/bankconnectors/Connector.scala b/obp-api/src/main/scala/code/bankconnectors/Connector.scala index 4c159e305..9e44598b7 100644 --- a/obp-api/src/main/scala/code/bankconnectors/Connector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/Connector.scala @@ -2,7 +2,6 @@ package code.bankconnectors import java.util.Date import java.util.UUID.randomUUID - import _root_.akka.http.scaladsl.model.HttpMethod import code.accountholders.{AccountHolders, MapperAccountHolders} import code.api.attributedefinition.AttributeDefinition @@ -22,6 +21,7 @@ import code.bankconnectors.rest.RestConnector_vMar2019 import code.bankconnectors.storedprocedure.StoredProcedureConnector_vDec2019 import code.bankconnectors.vMay2019.KafkaMappedConnector_vMay2019 import code.bankconnectors.vSept2018.KafkaMappedConnector_vSept2018 +import code.customeraccountlinks.CustomerAccountLinkTrait import code.endpointTag.EndpointTagT import code.fx.fx.TTL import code.management.ImporterAPI.ImporterTransaction @@ -2574,5 +2574,19 @@ trait Connector extends MdcLoggable { message: String, callContext: Option[CallContext] ): OBPReturnType[Box[String]] = Future{(Failure(setUnimplementedError), callContext)} + + def getCustomerAccountLink(customerId: String, accountId: String, callContext: Option[CallContext]): OBPReturnType[Box[CustomerAccountLinkTrait]] = Future{(Failure(setUnimplementedError), callContext)} + + def getCustomerAccountLinksByCustomerId(customerId: String, callContext: Option[CallContext]): OBPReturnType[Box[List[CustomerAccountLinkTrait]]] = Future{(Failure(setUnimplementedError), callContext)} + + def getCustomerAccountLinksByAccountId(accountId: String, callContext: Option[CallContext]): OBPReturnType[Box[List[CustomerAccountLinkTrait]]] = Future{(Failure(setUnimplementedError), callContext)} + + def getCustomerAccountLinkById(customerAccountLinkId: String, callContext: Option[CallContext]): OBPReturnType[Box[CustomerAccountLinkTrait]] = Future{(Failure(setUnimplementedError), callContext)} + + def deleteCustomerAccountLinkById(customerAccountLinkId: String, callContext: Option[CallContext]): OBPReturnType[Box[Boolean]] = Future{(Failure(setUnimplementedError), callContext)} + + def createCustomerAccountLink(customerId: String, accountId: String, relationshipType: String, callContext: Option[CallContext]): OBPReturnType[Box[CustomerAccountLinkTrait]] = Future{(Failure(setUnimplementedError), callContext)} + + def updateCustomerAccountLinkById(customerAccountLinkId: String, relationshipType: String, callContext: Option[CallContext]): OBPReturnType[Box[CustomerAccountLinkTrait]] = Future{(Failure(setUnimplementedError), callContext)} } diff --git a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala index 4e9612e7d..7c2cf3a3d 100644 --- a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -2,7 +2,6 @@ package code.bankconnectors import java.util.Date import java.util.UUID.randomUUID - import _root_.akka.http.scaladsl.model.HttpMethod import code.DynamicData.DynamicDataProvider import code.DynamicEndpoint.{DynamicEndpointProvider, DynamicEndpointT} @@ -31,6 +30,7 @@ import code.cardattribute.CardAttributeX import code.cards.MappedPhysicalCard import code.context.{UserAuthContextProvider, UserAuthContextUpdateProvider} import code.customer._ +import code.customeraccountlinks.CustomerAccountLinkTrait import code.customeraddress.CustomerAddressX import code.customerattribute.CustomerAttributeX import code.database.authorisation.Authorisations @@ -5555,5 +5555,34 @@ object LocalMappedConnector extends Connector with MdcLoggable { } else Future{(Full("Success"), callContext)} } - + + override def getCustomerAccountLink(customerId: String, accountId: String, callContext: Option[CallContext]): OBPReturnType[Box[CustomerAccountLinkTrait]] = Future{ + CustomerAccountLinkTrait.customerAccountLink.vend.getCustomerAccountLink(customerId, accountId) map { ( _, callContext) } + } + + override def getCustomerAccountLinksByCustomerId(customerId: String, callContext: Option[CallContext]) = Future{ + (CustomerAccountLinkTrait.customerAccountLink.vend.getCustomerAccountLinksByCustomerId(customerId),callContext) + } + + + override def getCustomerAccountLinksByAccountId(accountId: String, callContext: Option[CallContext]): OBPReturnType[Box[List[CustomerAccountLinkTrait]]] = Future{ + (CustomerAccountLinkTrait.customerAccountLink.vend.getCustomerAccountLinksByAccountId(accountId),callContext) + } + + override def getCustomerAccountLinkById(customerAccountLinkId: String, callContext: Option[CallContext]) = Future{ + (CustomerAccountLinkTrait.customerAccountLink.vend.getCustomerAccountLinkById(customerAccountLinkId),callContext) + } + + + override def deleteCustomerAccountLinkById(customerAccountLinkId: String, callContext: Option[CallContext]) = + CustomerAccountLinkTrait.customerAccountLink.vend.deleteCustomerAccountLinkById(customerAccountLinkId).map {(_, callContext)} + + override def updateCustomerAccountLinkById(customerAccountLinkId: String, relationshipType: String, callContext: Option[CallContext]) = Future{ + (CustomerAccountLinkTrait.customerAccountLink.vend.updateCustomerAccountLinkById(customerAccountLinkId, relationshipType),callContext) + } + + override def createCustomerAccountLink(customerId: String, accountId: String, relationshipType: String, callContext: Option[CallContext]): OBPReturnType[Box[CustomerAccountLinkTrait]] = Future{ + CustomerAccountLinkTrait.customerAccountLink.vend.createCustomerAccountLink(customerId: String, accountId: String, relationshipType: String) map { ( _, callContext) } + } + } diff --git a/obp-api/src/main/scala/code/customeraccountlinks/CustomerAccountLink.scala b/obp-api/src/main/scala/code/customeraccountlinks/CustomerAccountLink.scala index 96a75ac10..5d162bbdf 100644 --- a/obp-api/src/main/scala/code/customeraccountlinks/CustomerAccountLink.scala +++ b/obp-api/src/main/scala/code/customeraccountlinks/CustomerAccountLink.scala @@ -22,26 +22,30 @@ object CustomerAccountLinkTrait extends SimpleInjector { trait CustomerAccountLinkProvider { def createCustomerAccountLink(customerId: String, accountId: String, relationshipType: String): Box[CustomerAccountLinkTrait] - def getOCreateCustomerAccountLink(customerId: String, accountId: String, relationshipType: String): Box[CustomerAccountLinkTrait] + def getOrCreateCustomerAccountLink(customerId: String, accountId: String, relationshipType: String): Box[CustomerAccountLinkTrait] def getCustomerAccountLinkByCustomerId(customerId: String): Box[CustomerAccountLinkTrait] - def getCustomerAccountLinksByCustomerId(customerId: String): List[CustomerAccountLinkTrait] - def getCustomerAccountLinksByAccountId(accountId: String): List[CustomerAccountLinkTrait] + def getCustomerAccountLinksByCustomerId(customerId: String): Box[List[CustomerAccountLinkTrait]] + def getCustomerAccountLinksByAccountId(accountId: String): Box[List[CustomerAccountLinkTrait]] def getCustomerAccountLink(customerId: String, accountId: String): Box[CustomerAccountLinkTrait] + def getCustomerAccountLinkById(customerAccountLinkId: String): Box[CustomerAccountLinkTrait] + def updateCustomerAccountLinkById(customerAccountLinkId: String, relationshipType: String): Box[CustomerAccountLinkTrait] def getCustomerAccountLinks: Box[List[CustomerAccountLinkTrait]] def bulkDeleteCustomerAccountLinks(): Boolean - def deleteCustomerAccountLink(customerAccountLinkId: String): Future[Box[Boolean]] + def deleteCustomerAccountLinkById(customerAccountLinkId: String): Future[Box[Boolean]] } class RemotedataCustomerAccountLinkProviderCaseClass { case class createCustomerAccountLink(customerId: String, accountId: String, relationshipType: String) - case class getOCreateCustomerAccountLink(customerId: String, accountId: String, relationshipType: String) + case class getOrCreateCustomerAccountLink(customerId: String, accountId: String, relationshipType: String) case class getCustomerAccountLinkByCustomerId(customerId: String) case class getCustomerAccountLinksByCustomerId(customerId: String) case class getCustomerAccountLinksByAccountId(accountId: String) + case class getCustomerAccountLinkById(customerAccountLinkId: String) + case class updateCustomerAccountLinkById(customerAccountLinkId: String, relationshipType: String) case class getCustomerAccountLink(customerId: String, accountId: String) case class getCustomerAccountLinks() case class bulkDeleteCustomerAccountLinks() - case class deleteCustomerAccountLink(customerAccountLinkId: String) + case class deleteCustomerAccountLinkById(customerAccountLinkId: String) } object RemotedataCustomerAccountLinkProviderCaseClass extends RemotedataCustomerAccountLinkProviderCaseClass diff --git a/obp-api/src/main/scala/code/customeraccountlinks/MappedCustomerAccountLink.scala b/obp-api/src/main/scala/code/customeraccountlinks/MappedCustomerAccountLink.scala index fe5ad0f6f..181ce4efa 100644 --- a/obp-api/src/main/scala/code/customeraccountlinks/MappedCustomerAccountLink.scala +++ b/obp-api/src/main/scala/code/customeraccountlinks/MappedCustomerAccountLink.scala @@ -7,19 +7,19 @@ import net.liftweb.mapper._ import scala.concurrent.Future import com.openbankproject.commons.ExecutionContext.Implicits.global +import net.liftweb.util.Helpers.tryo object MappedCustomerAccountLinkProvider extends CustomerAccountLinkProvider { def createCustomerAccountLink(customerId: String, accountId: String, relationshipType: String): Box[CustomerAccountLinkTrait] = { - - val createCustomerAccountLink = CustomerAccountLink.create + tryo { + CustomerAccountLink.create .CustomerId(customerId) .AccountId(accountId) .RelationshipType(relationshipType) .saveMe() - - Some(createCustomerAccountLink) + } } - def getOCreateCustomerAccountLink(customerId: String, accountId: String, relationshipType: String): Box[CustomerAccountLinkTrait] = { + def getOrCreateCustomerAccountLink(customerId: String, accountId: String, relationshipType: String): Box[CustomerAccountLinkTrait] = { getCustomerAccountLink(accountId, customerId) match { case Empty => val createCustomerAccountLink = CustomerAccountLink.create @@ -36,32 +36,51 @@ object MappedCustomerAccountLinkProvider extends CustomerAccountLinkProvider { CustomerAccountLink.find( By(CustomerAccountLink.CustomerId, customerId)) } - def getCustomerAccountLinksByCustomerId(customerId: String): List[CustomerAccountLinkTrait] = { - CustomerAccountLink.findAll( - By(CustomerAccountLink.CustomerId, customerId)) + + def getCustomerAccountLinksByCustomerId(customerId: String): Box[List[CustomerAccountLinkTrait]] = { + tryo { + CustomerAccountLink.findAll( + By(CustomerAccountLink.CustomerId, customerId)) + } } - def getCustomerAccountLinksByAccountId(accountId: String): List[CustomerAccountLinkTrait] = { - val customerAccountLinks : List[CustomerAccountLinkTrait] = CustomerAccountLink.findAll( - By(CustomerAccountLink.AccountId, accountId)).sortWith(_.id.get < _.id.get) - customerAccountLinks + def getCustomerAccountLinksByAccountId(accountId: String): Box[List[CustomerAccountLinkTrait]] = { + tryo { + CustomerAccountLink.findAll( + By(CustomerAccountLink.AccountId, accountId)).sortWith(_.id.get < _.id.get) + } } - def getCustomerAccountLink(accountId : String, customerId: String): Box[CustomerAccountLinkTrait] = { + def getCustomerAccountLink(customerId: String, accountId : String): Box[CustomerAccountLinkTrait] = { CustomerAccountLink.find( - By(CustomerAccountLink.AccountId, accountId), - By(CustomerAccountLink.CustomerId, customerId)) + By(CustomerAccountLink.CustomerId, customerId), + By(CustomerAccountLink.AccountId, accountId) + ) + } + + def getCustomerAccountLinkById(customerAccountLinkId: String): Box[CustomerAccountLinkTrait] = { + CustomerAccountLink.find( + By(CustomerAccountLink.CustomerAccountLinkId, customerAccountLinkId) + ) + } + + def updateCustomerAccountLinkById(customerAccountLinkId: String, relationshipType: String): Box[CustomerAccountLinkTrait] = { + CustomerAccountLink.find(By(CustomerAccountLink.CustomerAccountLinkId, customerAccountLinkId)) match { + case Full(t) => Full(t.RelationshipType(relationshipType).saveMe()) + case Empty => Empty ?~! ErrorMessages.CustomerAccountLinkNotFound + case Failure(msg, exception, chain) => Failure(msg, exception, chain) + } } def getCustomerAccountLinks: Box[List[CustomerAccountLinkTrait]] = { - Full(CustomerAccountLink.findAll()) + tryo {CustomerAccountLink.findAll()} } def bulkDeleteCustomerAccountLinks(): Boolean = { CustomerAccountLink.bulkDelete_!!() } - def deleteCustomerAccountLink(customerAccountLinkId: String): Future[Box[Boolean]] = { + def deleteCustomerAccountLinkById(customerAccountLinkId: String): Future[Box[Boolean]] = { Future { CustomerAccountLink.find(By(CustomerAccountLink.CustomerAccountLinkId, customerAccountLinkId)) match { case Full(t) => Full(t.delete_!) diff --git a/obp-api/src/main/scala/code/remotedata/RemotedataCustomerAccountLinks.scala b/obp-api/src/main/scala/code/remotedata/RemotedataCustomerAccountLinks.scala index d41457f72..ecaff6f83 100644 --- a/obp-api/src/main/scala/code/remotedata/RemotedataCustomerAccountLinks.scala +++ b/obp-api/src/main/scala/code/remotedata/RemotedataCustomerAccountLinks.scala @@ -15,19 +15,27 @@ object RemotedataCustomerAccountLinks extends ObpActorInit with CustomerAccountL (actor ? cc.createCustomerAccountLink(accountId, customerId, relationshipType)).mapTo[Box[CustomerAccountLinkTrait]] ) - def getOCreateCustomerAccountLink(customerId: String, accountId: String, relationshipType: String) : Box[CustomerAccountLinkTrait] = getValueFromFuture( - (actor ? cc.getOCreateCustomerAccountLink(accountId, customerId, relationshipType)).mapTo[Box[CustomerAccountLinkTrait]] + def getOrCreateCustomerAccountLink(customerId: String, accountId: String, relationshipType: String) : Box[CustomerAccountLinkTrait] = getValueFromFuture( + (actor ? cc.getOrCreateCustomerAccountLink(accountId, customerId, relationshipType)).mapTo[Box[CustomerAccountLinkTrait]] ) def getCustomerAccountLinkByCustomerId(customerId: String): Box[CustomerAccountLinkTrait] = getValueFromFuture( (actor ? cc.getCustomerAccountLinkByCustomerId(customerId)).mapTo[Box[CustomerAccountLinkTrait]] ) - def getCustomerAccountLinksByCustomerId(customerId: String): List[CustomerAccountLinkTrait] = getValueFromFuture( - (actor ? cc.getCustomerAccountLinksByCustomerId(customerId)).mapTo[List[CustomerAccountLinkTrait]] + def getCustomerAccountLinksByCustomerId(customerId: String): Box[List[CustomerAccountLinkTrait]] = getValueFromFuture( + (actor ? cc.getCustomerAccountLinksByCustomerId(customerId)).mapTo[Box[List[CustomerAccountLinkTrait]]] ) - def getCustomerAccountLinksByAccountId(accountId: String): List[CustomerAccountLinkTrait] = getValueFromFuture( - (actor ? cc.getCustomerAccountLinksByAccountId(accountId)).mapTo[List[CustomerAccountLinkTrait]] + def getCustomerAccountLinksByAccountId(accountId: String): Box[List[CustomerAccountLinkTrait]] = getValueFromFuture( + (actor ? cc.getCustomerAccountLinksByAccountId(accountId)).mapTo[Box[List[CustomerAccountLinkTrait]]] + ) + + def getCustomerAccountLinkById(customerAccountLinkId: String): Box[CustomerAccountLinkTrait] = getValueFromFuture( + (actor ? cc.getCustomerAccountLinkById(customerAccountLinkId)).mapTo[Box[CustomerAccountLinkTrait]] + ) + + def updateCustomerAccountLinkById(customerAccountLinkId: String, relationshipType: String): Box[CustomerAccountLinkTrait] = getValueFromFuture( + (actor ? cc.updateCustomerAccountLinkById(customerAccountLinkId: String, relationshipType: String)).mapTo[Box[CustomerAccountLinkTrait]] ) def getCustomerAccountLink(customerId: String, accountId: String): Box[CustomerAccountLinkTrait] = getValueFromFuture( @@ -41,8 +49,8 @@ object RemotedataCustomerAccountLinks extends ObpActorInit with CustomerAccountL def bulkDeleteCustomerAccountLinks(): Boolean = getValueFromFuture( (actor ? cc.bulkDeleteCustomerAccountLinks()).mapTo[Boolean] ) - def deleteCustomerAccountLink(customerAccountLinkId: String): Future[Box[Boolean]] = - (actor ? cc.deleteCustomerAccountLink(customerAccountLinkId)).mapTo[Box[Boolean]] + def deleteCustomerAccountLinkById(customerAccountLinkId: String): Future[Box[Boolean]] = + (actor ? cc.deleteCustomerAccountLinkById(customerAccountLinkId)).mapTo[Box[Boolean]] } diff --git a/obp-api/src/main/scala/code/remotedata/RemotedataCustomerAccountLinksActor.scala b/obp-api/src/main/scala/code/remotedata/RemotedataCustomerAccountLinksActor.scala index ba4fc9a9d..99359567e 100644 --- a/obp-api/src/main/scala/code/remotedata/RemotedataCustomerAccountLinksActor.scala +++ b/obp-api/src/main/scala/code/remotedata/RemotedataCustomerAccountLinksActor.scala @@ -18,9 +18,9 @@ class RemotedataCustomerAccountLinksActor extends Actor with ObpActorHelper with logger.debug(s"createCustomerAccountLink($accountId, $relationshipType)") sender ! (mapper.createCustomerAccountLink(accountId, customerId, relationshipType)) - case cc.getOCreateCustomerAccountLink(customerId: String, accountId: String, relationshipType) => - logger.debug(s"getOCreateCustomerAccountLink($accountId, $relationshipType)") - sender ! (mapper.getOCreateCustomerAccountLink(accountId, customerId, relationshipType)) + case cc.getOrCreateCustomerAccountLink(customerId: String, accountId: String, relationshipType) => + logger.debug(s"getOrCreateCustomerAccountLink($accountId, $relationshipType)") + sender ! (mapper.getOrCreateCustomerAccountLink(accountId, customerId, relationshipType)) case cc.getCustomerAccountLinkByCustomerId(customerId: String) => logger.debug(s"getCustomerAccountLinkByCustomerId($customerId)") @@ -33,6 +33,14 @@ class RemotedataCustomerAccountLinksActor extends Actor with ObpActorHelper with case cc.getCustomerAccountLinksByAccountId(accountId: String) => logger.debug(s"getCustomerAccountLinksByAccountId($accountId)") sender ! (mapper.getCustomerAccountLinksByAccountId(accountId)) + + case cc.getCustomerAccountLinkById(customerAccountLinkId: String)=> + logger.debug(s"getCustomerAccountLinkById($customerAccountLinkId)") + sender ! (mapper.getCustomerAccountLinkById(customerAccountLinkId)) + + case cc.updateCustomerAccountLinkById(customerAccountLinkId: String, relationshipType: String)=> + logger.debug(s"updateCustomerAccountLinkById($customerAccountLinkId, $relationshipType)") + sender ! (mapper.updateCustomerAccountLinkById(customerAccountLinkId, relationshipType)) case cc.getCustomerAccountLink(customerId: String, accountId: String) => logger.debug(s"getCustomerAccountLink($accountId, $customerId)") @@ -46,9 +54,9 @@ class RemotedataCustomerAccountLinksActor extends Actor with ObpActorHelper with logger.debug(s"bulkDeleteCustomerAccountLinks()") sender ! (mapper.bulkDeleteCustomerAccountLinks()) - case cc.deleteCustomerAccountLink(customerAccountLinkId) => + case cc.deleteCustomerAccountLinkById(customerAccountLinkId) => logger.debug(s"deleteCustomerAccountLink($customerAccountLinkId)") - mapper.deleteCustomerAccountLink(customerAccountLinkId) pipeTo sender + mapper.deleteCustomerAccountLinkById(customerAccountLinkId) pipeTo sender case message => logger.warn("[AKKA ACTOR ERROR - REQUEST NOT RECOGNIZED] " + message)