diff --git a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala index 676fc29859..4a865039d9 100644 --- a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala +++ b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala @@ -63,6 +63,7 @@ import code.connectormethod.ConnectorMethod import code.consent.{ConsentRequest, MappedConsent} import code.consumer.Consumers import code.context.{MappedConsentAuthContext, MappedUserAuthContext, MappedUserAuthContextUpdate} +import code.counterpartylimit.CounterpartyLimit import code.crm.MappedCrmEvent import code.customer.internalMapping.MappedCustomerIdMapping import code.customer.{MappedCustomer, MappedCustomerMessage} @@ -1087,7 +1088,8 @@ object ToSchemify { EndpointTag, ProductFee, ViewPermission, - UserInitAction + UserInitAction, + CounterpartyLimit ) // start grpc server 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 c4e3fd69bb..28b897a38d 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 @@ -5396,6 +5396,27 @@ object SwaggerDefinitionsJSON { phone = phoneExample.value, ) + val postCounterpartyLimitV510 = PostCounterpartyLimitV510( + max_single_amount = maxSingleAmountExample.value.toInt, + max_monthly_amount = maxMonthlyAmountExample.value.toInt, + max_number_of_monthly_transactions = maxNumberOfMonthlyTransactionsExample.value.toInt, + max_yearly_amount = maxYearlyAmountExample.value.toInt, + max_number_of_yearly_transactions = maxNumberOfYearlyTransactionsExample.value.toInt + ) + + val counterpartyLimitV510 = CounterpartyLimitV510( + counterparty_limit_id = counterpartyLimitIdExample.value, + bank_id = bankIdExample.value, + account_id = accountIdExample.value, + view_id = viewIdExample.value, + counterparty_id = counterpartyIdExample.value, + max_single_amount = maxSingleAmountExample.value.toInt, + max_monthly_amount = maxMonthlyAmountExample.value.toInt, + max_number_of_monthly_transactions = maxNumberOfMonthlyTransactionsExample.value.toInt, + max_yearly_amount = maxYearlyAmountExample.value.toInt, + max_number_of_yearly_transactions = maxNumberOfYearlyTransactionsExample.value.toInt + ) + val atmsJsonV510 = AtmsJsonV510( atms = List(atmJsonV510) ) 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 958fd43c55..9c27240ef1 100644 --- a/obp-api/src/main/scala/code/api/util/APIUtil.scala +++ b/obp-api/src/main/scala/code/api/util/APIUtil.scala @@ -1696,6 +1696,8 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ private val isNeedCheckView = errorResponseBodies.contains($UserNoPermissionAccessView) && requestUrlPartPath.contains("BANK_ID") && requestUrlPartPath.contains("ACCOUNT_ID") && requestUrlPartPath.contains("VIEW_ID") + private val isNeedCheckCounterparty = errorResponseBodies.contains($CounterpartyNotFoundByCounterpartyId) && requestUrlPartPath.contains("COUNTERPARTY_ID") + private val reversedRequestUrl = requestUrlPartPath.reverse def getPathParams(url: List[String]): Map[String, String] = reversedRequestUrl.zip(url.reverse) collect { @@ -1775,6 +1777,14 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ Future.successful(null.asInstanceOf[View]) } } + + def checkCounterparty(counterpartyId: Option[CounterpartyId], callContext: Option[CallContext]): OBPReturnType[CounterpartyTrait] = { + if(isNeedCheckCounterparty && counterpartyId.isDefined) { + checkCounterpartyFun(counterpartyId.get)(callContext) + } else { + Future.successful(null.asInstanceOf[CounterpartyTrait] -> callContext) + } + } // reset connectorMethods { val checkerFunctions = mutable.ListBuffer[PartialFunction[_, _]]() @@ -1795,6 +1805,9 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ if (isNeedCheckView) { checkerFunctions += checkViewFun } + if (isNeedCheckCounterparty) { + checkerFunctions += checkCounterpartyFun + } val addedMethods: List[String] = checkerFunctions.toList.flatMap(getDependentConnectorMethods(_)) .map(value =>("obp." +value).intern()) @@ -1841,6 +1854,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ val bankId = pathParams.get("BANK_ID").map(BankId(_)) val accountId = pathParams.get("ACCOUNT_ID").map(AccountId(_)) val viewId = pathParams.get("VIEW_ID").map(ViewId(_)) + val counterpartyId = pathParams.get("COUNTERPARTY_ID").map(CounterpartyId(_)) val request: Box[Req] = S.request val session: Box[LiftSession] = S.session @@ -1851,7 +1865,8 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ * 2. check bankId * 3. roles check * 4. check accountId - * 5. view + * 5. view access + * 6. check counterpartyId * * A Bank MUST be checked before Roles. * In opposite case we get next paradox: @@ -1878,6 +1893,9 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ // check user access permission of this viewId corresponding view view <- checkView(viewId, bankId, accountId, boxUser, callContext) + + counterparty <- checkCounterparty(counterpartyId, callContext) + } yield { val newCallContext = if(boxUser.isDefined) callContext.map(_.copy(user=boxUser)) else callContext @@ -4232,6 +4250,9 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ private val checkViewFun: PartialFunction[ViewId, (BankIdAccountId, Option[User], Option[CallContext]) => Future[View]] = { case x => NewStyle.function.checkViewAccessAndReturnView(x, _, _, _) } + private val checkCounterpartyFun: PartialFunction[CounterpartyId, Option[CallContext] => OBPReturnType[CounterpartyTrait]] = { + case x => NewStyle.function.getCounterpartyByCounterpartyId(x, _) + } // cache for method -> called obp methods: // (className, methodName, signature) -> List[(className, methodName, signature)] diff --git a/obp-api/src/main/scala/code/api/util/ApiTag.scala b/obp-api/src/main/scala/code/api/util/ApiTag.scala index ce37df8540..238ac379da 100644 --- a/obp-api/src/main/scala/code/api/util/ApiTag.scala +++ b/obp-api/src/main/scala/code/api/util/ApiTag.scala @@ -73,6 +73,7 @@ object ApiTag { val apiTagWebUiProps = ResourceDocTag("WebUi-Props") val apiTagEndpointMapping = ResourceDocTag("Endpoint-Mapping") val apiTagRateLimits = ResourceDocTag("Rate-Limits") + val apiTagCounterpartyLimits = ResourceDocTag("Counterparty-Limits") val apiTagApiCollection = ResourceDocTag("Api-Collection") 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 742e2843ef..06bd801cd4 100644 --- a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala +++ b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala @@ -506,6 +506,11 @@ object ErrorMessages { val SystemViewCannotBePublicError = "OBP-30258: System view cannot be public" val CreateCustomViewError = "OBP-30259: Could not create the custom view" val UpdateCustomViewError = "OBP-30260: Could not update the custom view" + val CreateCounterpartyLimitError = "OBP-30261: Could not create the counterparty limit." + val UpdateCounterpartyLimitError = "OBP-30262: Could not update the counterparty limit." + val GetCounterpartyLimitError = "OBP-30263: Counterparty limit not found. Please specify a valid value for BANK_ID, ACCOUNT_ID, VIEW_ID or COUNTERPARTY_ID." + val CounterpartyLimitAlreadyExists = "OBP-30264: Counterparty limit already exists. Please specify a different value for BANK_ID, ACCOUNT_ID, VIEW_ID or COUNTERPARTY_ID." + val DeleteCounterpartyLimitError = "OBP-30265: Could not delete the counterparty limit." 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. " @@ -848,6 +853,11 @@ object ErrorMessages { * validate method: NewStyle.function.checkViewAccessAndReturnView */ def $UserNoPermissionAccessView = UserNoPermissionAccessView + + /** + * validate method: NewStyle.function.getCounterpartyByCounterpartyId + */ + def $CounterpartyNotFoundByCounterpartyId = CounterpartyNotFoundByCounterpartyId def getDuplicatedMessageNumbers = { 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 2ce0791848..d180ff3589 100644 --- a/obp-api/src/main/scala/code/api/util/ExampleValue.scala +++ b/obp-api/src/main/scala/code/api/util/ExampleValue.scala @@ -2147,6 +2147,24 @@ object ExampleValue { lazy val transactionRequestTypesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided) glossaryItems += makeGlossaryItem("transaction_request_types", transactionRequestTypesExample) + lazy val counterpartyLimitIdExample = ConnectorField("abc9a7e4-6d02-40e3-a129-0b2bf89de9b1","A string that MUST uniquely identify the Counterparty Limit on this OBP instance.") + glossaryItems += makeGlossaryItem("counterparty_limit_id", counterpartyLimitIdExample) + + lazy val maxSingleAmountExample = ConnectorField("1000",NoDescriptionProvided) + glossaryItems += makeGlossaryItem("max_single_amount", maxSingleAmountExample) + + lazy val maxMonthlyAmountExample = ConnectorField("10000",NoDescriptionProvided) + glossaryItems += makeGlossaryItem("max_monthly_amount", maxMonthlyAmountExample) + + lazy val maxNumberOfMonthlyTransactionsExample = ConnectorField("10",NoDescriptionProvided) + glossaryItems += makeGlossaryItem("max_number_of_monthly_transactions", maxNumberOfMonthlyTransactionsExample) + + lazy val maxYearlyAmountExample = ConnectorField("12000",NoDescriptionProvided) + glossaryItems += makeGlossaryItem("max_yearly_amount", maxYearlyAmountExample) + + lazy val maxNumberOfYearlyTransactionsExample = ConnectorField("100",NoDescriptionProvided) + glossaryItems += makeGlossaryItem("max_number_of_yearly_transactions", maxNumberOfYearlyTransactionsExample) + lazy val canAddImageUrlExample = ConnectorField(booleanTrue,NoDescriptionProvided) glossaryItems += makeGlossaryItem("can_add_image_url", canAddImageUrlExample) 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 5ed5458816..a086dfe26a 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} @@ -54,8 +53,8 @@ import net.liftweb.json.JsonDSL._ import net.liftweb.json.{JField, JInt, JNothing, JNull, JObject, JString, JValue, _} import net.liftweb.util.Helpers.tryo import org.apache.commons.lang3.StringUtils -import java.security.AccessControlException +import java.security.AccessControlException import scala.collection.immutable.{List, Nil} import scala.concurrent.Future import scala.math.BigDecimal @@ -71,6 +70,7 @@ import code.api.dynamic.entity.helper.{DynamicEntityHelper, DynamicEntityInfo} import code.atmattribute.AtmAttribute import code.bankattribute.BankAttribute import code.connectormethod.{ConnectorMethodProvider, JsonConnectorMethod} +import code.counterpartylimit.{CounterpartyLimit, CounterpartyLimitTrait} import code.crm.CrmEvent import code.crm.CrmEvent.CrmEvent import code.customeraccountlinks.CustomerAccountLinkTrait @@ -4056,6 +4056,67 @@ object NewStyle extends MdcLoggable{ (unboxFullOrFail(i, callContext, s"$DeleteCustomViewError"), callContext) } + def createOrUpdateCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + maxSingleAmount: Int, + maxMonthlyAmount: Int, + maxNumberOfMonthlyTransactions: Int, + maxYearlyAmount: Int, + maxNumberOfYearlyTransactions: Int, + callContext: Option[CallContext] + ): OBPReturnType[CounterpartyLimitTrait] = + Connector.connector.vend.createOrUpdateCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + maxSingleAmount: Int, + maxMonthlyAmount: Int, + maxNumberOfMonthlyTransactions: Int, + maxYearlyAmount: Int, + maxNumberOfYearlyTransactions: Int, + callContext: Option[CallContext] + ) map { + i => (unboxFullOrFail(i._1, callContext, CreateCounterpartyLimitError), i._2) + } + + def getCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + callContext: Option[CallContext] + ): OBPReturnType[CounterpartyLimitTrait] = + Connector.connector.vend.getCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + callContext: Option[CallContext] + ) map { + i => (unboxFullOrFail(i._1, callContext, s"$GetCounterpartyLimitError Current BANK_ID($bankId), " + + s"ACCOUNT_ID($accountId), VIEW_ID($viewId),COUNTERPARTY_ID($counterpartyId)"), i._2) + } + + def deleteCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + callContext: Option[CallContext] + ): OBPReturnType[Boolean] = + Connector.connector.vend.deleteCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + callContext: Option[CallContext] + ) map { + i => (unboxFullOrFail(i._1, callContext, s"$DeleteCounterpartyLimitError"), i._2) + } } } diff --git a/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala b/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala index ee5bb3031e..968f7f5ed1 100644 --- a/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala +++ b/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala @@ -645,7 +645,8 @@ trait APIMethods121 { ), List(apiTagAccount, apiTagView, apiTagOldStyle) ) - + + //TODO. remove and replace it with V510. lazy val updateViewForBankAccount: OBPEndpoint = { //updates a view on a bank account case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId diff --git a/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala b/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala index e3a103ca17..c7a63c729c 100644 --- a/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala +++ b/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala @@ -198,6 +198,7 @@ trait APIMethods300 { ), List(apiTagView, apiTagAccount)) + //TODO. remove and replace it with V510. lazy val createViewForBankAccount : OBPEndpoint = { //creates a view on an bank account case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "views" :: Nil JsonPost json -> _ => { 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 6dc6ca5d99..aa7ffcc8bb 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 @@ -1,6 +1,7 @@ package code.api.v5_1_0 +import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON import code.api.{Constant, UserNotFound} import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ import code.api.util.APIUtil._ @@ -15,7 +16,9 @@ import code.api.util._ import code.api.util.newstyle.BalanceNewStyle import code.api.util.newstyle.Consumer.createConsumerNewStyle import code.api.util.newstyle.RegulatedEntityNewStyle.{createRegulatedEntityNewStyle, deleteRegulatedEntityNewStyle, getRegulatedEntitiesNewStyle, getRegulatedEntityByEntityIdNewStyle} +import code.api.v1_2_1.CreateViewJsonV121 import code.api.v2_1_0.{ConsumerRedirectUrlJSON, JSONFactory210} +import code.api.v2_2_0.JSONFactory220 import code.api.v3_0_0.JSONFactory300 import code.api.v3_0_0.JSONFactory300.createAggregateMetricJson import code.api.v3_1_0.ConsentJsonV310 @@ -28,14 +31,14 @@ import code.bankconnectors.Connector import code.consent.Consents import code.loginattempts.LoginAttempt import code.metrics.APIMetrics -import code.model.AppType +import code.model.{AppType, BankAccountX} import code.model.dataAccess.MappedBankAccount import code.regulatedentities.MappedRegulatedEntityProvider import code.transactionrequests.TransactionRequests.TransactionRequestTypes.{apply => _} import code.userlocks.UserLocksProvider import code.users.Users import code.util.Helper -import code.util.Helper.ObpS +import code.util.Helper.{ObpS, booleanToBox} import code.views.Views import code.views.system.{AccountAccess, ViewDefinition} import com.github.dwickern.macros.NameOf.nameOf @@ -45,9 +48,9 @@ import com.openbankproject.commons.model._ import com.openbankproject.commons.util.{ApiVersion, ScannedApiVersion} import net.liftweb.common.Full import net.liftweb.http.rest.RestHelper -import net.liftweb.json.{compactRender, parse, prettyRender} +import net.liftweb.json.{Extraction, compactRender, parse, prettyRender} import net.liftweb.mapper.By -import net.liftweb.util.Helpers +import net.liftweb.util.{Helpers, StringHelpers} import net.liftweb.util.Helpers.tryo import scala.collection.immutable.{List, Nil} @@ -2287,10 +2290,190 @@ trait APIMethods510 { } } + staticResourceDocs += ResourceDoc( + createCounterpartyLimit, + implementedInApiVersion, + nameOf(createCounterpartyLimit), + "POST", + "/banks/BANK_ID/accounts/ACCOUNT_ID/views/VIEW_ID/counterparties/COUNTERPARTY_ID/limits", + "Create Counterparty Limit", + s"""Create Counterparty Limit.""", + postCounterpartyLimitV510, + counterpartyLimitV510, + List( + $UserNotLoggedIn, + $BankNotFound, + $BankAccountNotFound, + $UserNoPermissionAccessView, + $CounterpartyNotFoundByCounterpartyId, + InvalidJsonFormat, + UnknownError + ), + List(apiTagCounterpartyLimits), + ) + lazy val createCounterpartyLimit: OBPEndpoint = { + case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "views" :: ViewId(viewId) ::"counterparties" :: CounterpartyId(counterpartyId) ::"limits" :: Nil JsonPost json -> _ => { + cc => implicit val ec = EndpointContext(Some(cc)) + for { + postCounterpartyLimitV510 <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the ${classOf[AtmJsonV510]}", 400, cc.callContext) { + json.extract[PostCounterpartyLimitV510] + } + (counterpartyLimitBox, callContext) <- Connector.connector.vend.getCounterpartyLimit( + bankId.value, + accountId.value, + viewId.value, + counterpartyId.value, + cc.callContext + ) + failMsg = s"$CounterpartyLimitAlreadyExists Current BANK_ID($bankId), ACCOUNT_ID($accountId), VIEW_ID($viewId),COUNTERPARTY_ID($counterpartyId)" + _ <- Helper.booleanToFuture(failMsg, cc = callContext) { + counterpartyLimitBox.isEmpty + } + (counterpartyLimit,callContext) <- NewStyle.function.createOrUpdateCounterpartyLimit( + bankId.value, + accountId.value, + viewId.value, + counterpartyId.value, + postCounterpartyLimitV510.max_single_amount, + postCounterpartyLimitV510.max_monthly_amount, + postCounterpartyLimitV510.max_number_of_monthly_transactions, + postCounterpartyLimitV510.max_yearly_amount, + postCounterpartyLimitV510.max_number_of_yearly_transactions, + cc.callContext + ) + } yield { + + (counterpartyLimit.toJValue, HttpCode.`201`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( + updateCounterpartyLimit, + implementedInApiVersion, + nameOf(updateCounterpartyLimit), + "PUT", + "/banks/BANK_ID/accounts/ACCOUNT_ID/views/VIEW_ID/counterparties/COUNTERPARTY_ID/limits", + "Update Counterparty Limit", + s"""Update Counterparty Limit.""", + postCounterpartyLimitV510, + counterpartyLimitV510, + List( + $UserNotLoggedIn, + $BankNotFound, + $BankAccountNotFound, + $UserNoPermissionAccessView, + $CounterpartyNotFoundByCounterpartyId, + InvalidJsonFormat, + UnknownError + ), + List(apiTagCounterpartyLimits), + ) + lazy val updateCounterpartyLimit: OBPEndpoint = { + case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "views" :: ViewId(viewId) ::"counterparties" :: CounterpartyId(counterpartyId) ::"limits" :: Nil JsonPut json -> _ => { + cc => implicit val ec = EndpointContext(Some(cc)) + for { + postCounterpartyLimitV510 <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the ${classOf[AtmJsonV510]}", 400, cc.callContext) { + json.extract[PostCounterpartyLimitV510] + } + (counterpartyLimit,callContext) <- NewStyle.function.createOrUpdateCounterpartyLimit( + bankId.value, + accountId.value, + viewId.value, + counterpartyId.value, + postCounterpartyLimitV510.max_single_amount, + postCounterpartyLimitV510.max_monthly_amount, + postCounterpartyLimitV510.max_number_of_monthly_transactions, + postCounterpartyLimitV510.max_yearly_amount, + postCounterpartyLimitV510.max_number_of_yearly_transactions, + cc.callContext + ) + } yield { + (counterpartyLimit.toJValue, HttpCode.`200`(cc.callContext)) + } + } + } + staticResourceDocs += ResourceDoc( + getCounterpartyLimit, + implementedInApiVersion, + nameOf(getCounterpartyLimit), + "GET", + "/banks/BANK_ID/accounts/ACCOUNT_ID/views/VIEW_ID/counterparties/COUNTERPARTY_ID/limits", + "Get Counterparty Limit", + s"""Get Counterparty Limit.""", + EmptyBody, + counterpartyLimitV510, + List( + $UserNotLoggedIn, + $BankNotFound, + $BankAccountNotFound, + $UserNoPermissionAccessView, + $CounterpartyNotFoundByCounterpartyId, + InvalidJsonFormat, + UnknownError + ), + List(apiTagCounterpartyLimits), + ) + lazy val getCounterpartyLimit: OBPEndpoint = { + case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "views" :: ViewId(viewId) ::"counterparties" :: CounterpartyId(counterpartyId) ::"limits" :: Nil JsonGet _ => { + cc => implicit val ec = EndpointContext(Some(cc)) + for { + (counterpartyLimit, callContext) <- NewStyle.function.getCounterpartyLimit( + bankId.value, + accountId.value, + viewId.value, + counterpartyId.value, + cc.callContext + ) + } yield { + (counterpartyLimit.toJValue, HttpCode.`200`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( + deleteCounterpartyLimit, + implementedInApiVersion, + nameOf(deleteCounterpartyLimit), + "DELETE", + "/banks/BANK_ID/accounts/ACCOUNT_ID/views/VIEW_ID/counterparties/COUNTERPARTY_ID/limits", + "Delete Counterparty Limit", + s"""Delete Counterparty Limit.""", + EmptyBody, + EmptyBody, + List( + $UserNotLoggedIn, + $BankNotFound, + $BankAccountNotFound, + $UserNoPermissionAccessView, + $CounterpartyNotFoundByCounterpartyId, + InvalidJsonFormat, + UnknownError + ), + List(apiTagCounterpartyLimits), + ) + lazy val deleteCounterpartyLimit: OBPEndpoint = { + case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "views" :: ViewId(viewId) ::"counterparties" :: CounterpartyId(counterpartyId) ::"limits" :: Nil JsonDelete _ => { + cc => implicit val ec = EndpointContext(Some(cc)) + for { + (counterpartyLimit, callContext)<- NewStyle.function.deleteCounterpartyLimit( + bankId.value, + accountId.value, + viewId.value, + counterpartyId.value, + cc.callContext + ) + } yield { + (Full(counterpartyLimit), HttpCode.`204`(cc.callContext)) + } + } + } } } + + object APIMethods510 extends RestHelper with APIMethods510 { lazy val newStyleEndpoints: List[(String, String)] = Implementations5_1_0.resourceDocs.map { rd => (rd.partialFunctionName, rd.implementedInApiVersion.toString()) 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 fe92e53e75..14fd4c4f18 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 @@ -160,6 +160,27 @@ case class PostAtmJsonV510 ( phone: String ) +case class PostCounterpartyLimitV510( + max_single_amount: Int, + max_monthly_amount: Int, + max_number_of_monthly_transactions: Int, + max_yearly_amount: Int, + max_number_of_yearly_transactions: Int +) + +case class CounterpartyLimitV510( + counterparty_limit_id: String, + bank_id: String, + account_id: String, + view_id: String, + counterparty_id: String, + max_single_amount: Int, + max_monthly_amount: Int, + max_number_of_monthly_transactions: Int, + max_yearly_amount: Int, + max_number_of_yearly_transactions: Int +) + case class AtmJsonV510 ( id : Option[String], bank_id : String, diff --git a/obp-api/src/main/scala/code/bankconnectors/Connector.scala b/obp-api/src/main/scala/code/bankconnectors/Connector.scala index d03e3b8494..02096bb748 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.Constant.{SYSTEM_ACCOUNTANT_VIEW_ID, SYSTEM_AUDITOR_VIEW_ID, SYSTEM_OWNER_VIEW_ID, localIdentityProvider} @@ -24,6 +23,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.counterpartylimit.{CounterpartyLimit, CounterpartyLimitTrait} import code.customeraccountlinks.CustomerAccountLinkTrait import code.endpointTag.EndpointTagT import code.fx.fx.TTL @@ -2662,5 +2662,34 @@ trait Connector extends MdcLoggable { def updateCustomerAccountLinkById(customerAccountLinkId: String, relationshipType: String, callContext: Option[CallContext]): OBPReturnType[Box[CustomerAccountLinkTrait]] = Future{(Failure(setUnimplementedError), callContext)} def getConsentImplicitSCA(user: User, callContext: Option[CallContext]): OBPReturnType[Box[ConsentImplicitSCAT]] = Future{(Failure(setUnimplementedError), callContext)} + + def createOrUpdateCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + maxSingleAmount: Int, + maxMonthlyAmount: Int, + maxNumberOfMonthlyTransactions: Int, + maxYearlyAmount: Int, + maxNumberOfYearlyTransactions: Int, callContext: Option[CallContext] + ): OBPReturnType[Box[CounterpartyLimitTrait]] = Future{(Failure(setUnimplementedError), callContext)} + + def getCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + callContext: Option[CallContext] + ): OBPReturnType[Box[CounterpartyLimitTrait]] = Future{(Failure(setUnimplementedError), callContext)} + def deleteCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + callContext: Option[CallContext] + ): OBPReturnType[Box[Boolean]] = 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 631bac4fdf..ac64a799ec 100644 --- a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -30,6 +30,7 @@ import code.branches.MappedBranch import code.cardattribute.CardAttributeX import code.cards.MappedPhysicalCard import code.context.{UserAuthContextProvider, UserAuthContextUpdateProvider} +import code.counterpartylimit.{CounterpartyLimit, CounterpartyLimitProvider, CounterpartyLimitTrait} import code.customer._ import code.customeraccountlinks.CustomerAccountLinkTrait import code.customeraddress.CustomerAddressX @@ -5913,5 +5914,58 @@ object LocalMappedConnector extends Connector with MdcLoggable { )), callContext) } + override def createOrUpdateCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + maxSingleAmount: Int, + maxMonthlyAmount: Int, + maxNumberOfMonthlyTransactions: Int, + maxYearlyAmount: Int, + maxNumberOfYearlyTransactions: Int, callContext: Option[CallContext]) = + CounterpartyLimitProvider.counterpartyLimit.vend.createOrUpdateCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + maxSingleAmount: Int, + maxMonthlyAmount: Int, + maxNumberOfMonthlyTransactions: Int, + maxYearlyAmount: Int, + maxNumberOfYearlyTransactions: Int) map { + (_, callContext) + } + + override def getCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + callContext: Option[CallContext] + ) = + CounterpartyLimitProvider.counterpartyLimit.vend.getCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String + ) map { + (_, callContext) + } + + override def deleteCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + callContext: Option[CallContext] + ): OBPReturnType[Box[Boolean]] = + CounterpartyLimitProvider.counterpartyLimit.vend.deleteCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String) map { + (_, callContext) + } } diff --git a/obp-api/src/main/scala/code/counterpartylimit/CounterpartyLimit.scala b/obp-api/src/main/scala/code/counterpartylimit/CounterpartyLimit.scala new file mode 100644 index 0000000000..92bc5f5591 --- /dev/null +++ b/obp-api/src/main/scala/code/counterpartylimit/CounterpartyLimit.scala @@ -0,0 +1,57 @@ +package code.counterpartylimit + +import code.api.util.APIUtil +import com.openbankproject.commons.util.JsonAble +import net.liftweb.util.SimpleInjector +import net.liftweb.common.Box +import scala.concurrent.Future + +object CounterpartyLimitProvider extends SimpleInjector { + val counterpartyLimit = new Inject(buildOne _) {} + def buildOne: CounterpartyLimitProviderTrait = APIUtil.getPropsAsBoolValue("use_akka", false) match { + case _ => MappedCounterpartyLimitProvider +// case true => RemotedataCounterpartyLimit // we are getting rid of the akka now. so do not implement it here + } +} + +trait CounterpartyLimitProviderTrait { + def getCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String + ): Future[Box[CounterpartyLimitTrait]] + + def deleteCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String + ): Future[Box[Boolean]] + + def createOrUpdateCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + maxSingleAmount: Int, + maxMonthlyAmount: Int, + maxNumberOfMonthlyTransactions: Int, + maxYearlyAmount: Int, + maxNumberOfYearlyTransactions: Int): Future[Box[CounterpartyLimitTrait]] +} + +trait CounterpartyLimitTrait extends JsonAble{ + def counterpartyLimitId: String + def bankId: String + def accountId: String + def viewId: String + def counterpartyId: String + + def maxSingleAmount: Int + def maxMonthlyAmount: Int + def maxNumberOfMonthlyTransactions: Int + def maxYearlyAmount: Int + def maxNumberOfYearlyTransactions: Int +} + diff --git a/obp-api/src/main/scala/code/counterpartylimit/MappedCounterpartyLimit.scala b/obp-api/src/main/scala/code/counterpartylimit/MappedCounterpartyLimit.scala new file mode 100644 index 0000000000..a919f3c96c --- /dev/null +++ b/obp-api/src/main/scala/code/counterpartylimit/MappedCounterpartyLimit.scala @@ -0,0 +1,149 @@ +package code.counterpartylimit + +import code.util.MappedUUID +import net.liftweb.common.{Box, Full} +import net.liftweb.mapper._ +import net.liftweb.util.Helpers.tryo +import com.openbankproject.commons.ExecutionContext.Implicits.global +import net.liftweb.json +import net.liftweb.json.Formats +import net.liftweb.json.JsonAST.{JValue,JString} +import net.liftweb.json.JsonDSL._ +import scala.concurrent.Future + +object MappedCounterpartyLimitProvider extends CounterpartyLimitProviderTrait { + + def getCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String + ): Future[Box[CounterpartyLimitTrait]] = Future { + CounterpartyLimit.find( + By(CounterpartyLimit.BankId, bankId), + By(CounterpartyLimit.AccountId, accountId), + By(CounterpartyLimit.ViewId, viewId), + By(CounterpartyLimit.CounterpartyId, counterpartyId) + ) + } + + def deleteCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String + ): Future[Box[Boolean]] = Future { + CounterpartyLimit.find( + By(CounterpartyLimit.BankId, bankId), + By(CounterpartyLimit.AccountId, accountId), + By(CounterpartyLimit.ViewId, viewId), + By(CounterpartyLimit.CounterpartyId, counterpartyId) + ).map(_.delete_!) + } + + def createOrUpdateCounterpartyLimit( + bankId: String, + accountId: String, + viewId: String, + counterpartyId: String, + maxSingleAmount: Int, + maxMonthlyAmount: Int, + maxNumberOfMonthlyTransactions: Int, + maxYearlyAmount: Int, + maxNumberOfYearlyTransactions: Int)= Future { + + def createCounterpartyLimit(counterpartyLimit: CounterpartyLimit)= { + tryo { + counterpartyLimit.BankId(bankId) + counterpartyLimit.AccountId(accountId) + counterpartyLimit.ViewId(viewId) + counterpartyLimit.CounterpartyId(counterpartyId) + counterpartyLimit.MaxSingleAmount(maxSingleAmount) + counterpartyLimit.MaxMonthlyAmount(maxMonthlyAmount) + counterpartyLimit.MaxNumberOfMonthlyTransactions(maxNumberOfMonthlyTransactions) + counterpartyLimit.MaxYearlyAmount(maxYearlyAmount) + counterpartyLimit.MaxNumberOfYearlyTransactions(maxNumberOfYearlyTransactions) + counterpartyLimit.saveMe() + } + } + + def getCounterpartyLimit = CounterpartyLimit.find( + By(CounterpartyLimit.BankId, bankId), + By(CounterpartyLimit.AccountId, accountId), + By(CounterpartyLimit.ViewId, viewId), + By(CounterpartyLimit.CounterpartyId, counterpartyId), + ) + + val result = getCounterpartyLimit match { + case Full(counterpartyLimit) => createCounterpartyLimit(counterpartyLimit) + case _ => createCounterpartyLimit(CounterpartyLimit.create) + } + result + } +} + +class CounterpartyLimit extends CounterpartyLimitTrait with LongKeyedMapper[CounterpartyLimit] with IdPK with CreatedUpdated { + override def getSingleton = CounterpartyLimit + + object CounterpartyLimitId extends MappedUUID(this) + + object BankId extends MappedString(this, 255){ + override def dbNotNull_? = true + } + object AccountId extends MappedString(this, 255){ + override def dbNotNull_? = true + } + object ViewId extends MappedString(this, 255){ + override def dbNotNull_? = true + } + object CounterpartyId extends MappedString(this, 255){ + override def dbNotNull_? = true + } + + + object MaxSingleAmount extends MappedInt(this) { + override def defaultValue = -1 + } + object MaxMonthlyAmount extends MappedInt(this) { + override def defaultValue = -1 + } + object MaxNumberOfMonthlyTransactions extends MappedInt(this) { + override def defaultValue = -1 + } + object MaxYearlyAmount extends MappedInt(this) { + override def defaultValue = -1 + } + object MaxNumberOfYearlyTransactions extends MappedInt(this) { + override def defaultValue = -1 + } + + def counterpartyLimitId: String = CounterpartyLimitId.get + + def bankId: String = BankId.get + def accountId: String = AccountId.get + def viewId: String = ViewId.get + def counterpartyId: String = CounterpartyId.get + + def maxSingleAmount: Int = MaxSingleAmount.get + def maxMonthlyAmount: Int = MaxMonthlyAmount.get + def maxNumberOfMonthlyTransactions: Int = MaxNumberOfMonthlyTransactions.get + def maxYearlyAmount: Int = MaxYearlyAmount.get + def maxNumberOfYearlyTransactions: Int = MaxNumberOfYearlyTransactions.get + + override def toJValue(implicit format: Formats): JValue ={ + ("counterparty_limit_id", counterpartyLimitId) ~ + ("bank_id", bankId) ~ + ("account_id",accountId) ~ + ("view_id",viewId) ~ + ("counterparty_id",counterpartyId) ~ + ("max_single_amount", maxSingleAmount) ~ + ("max_monthly_amount", maxMonthlyAmount) ~ + ("max_number_of_monthly_transactions", maxNumberOfMonthlyTransactions) ~ + ("max_yearly_amount", maxYearlyAmount) ~ + ("max_number_of_yearly_transactions", maxNumberOfYearlyTransactions) + } +} + +object CounterpartyLimit extends CounterpartyLimit with LongKeyedMetaMapper[CounterpartyLimit] { + override def dbIndexes = UniqueIndex(CounterpartyLimitId) :: UniqueIndex(BankId, AccountId, ViewId, CounterpartyId) :: super.dbIndexes +} diff --git a/obp-api/src/test/scala/code/api/v5_1_0/CounterpartyLimitTest.scala b/obp-api/src/test/scala/code/api/v5_1_0/CounterpartyLimitTest.scala new file mode 100644 index 0000000000..7c7c5adf14 --- /dev/null +++ b/obp-api/src/test/scala/code/api/v5_1_0/CounterpartyLimitTest.scala @@ -0,0 +1,185 @@ +package code.api.v5_1_0 +import java.util.UUID +import code.api.Constant.{SYSTEM_MANAGE_CUSTOM_VIEWS_VIEW_ID, SYSTEM_OWNER_VIEW_ID} +import code.api.util.ErrorMessages._ +import code.api.util.APIUtil.OAuth._ +import code.api.v5_1_0.OBPAPI5_1_0.Implementations5_1_0 +import com.github.dwickern.macros.NameOf.nameOf +import com.openbankproject.commons.model.ErrorMessage +import com.openbankproject.commons.util.ApiVersion +import net.liftweb.json.Serialization.write +import org.scalatest.Tag + +class CounterpartyLimitTest extends V510ServerSetup { + /** + * Test tags + * Example: To run tests with tag "getPermissions": + * mvn test -D tagsToInclude + * + * This is made possible by the scalatest maven plugin + */ + object VersionOfApi extends Tag(ApiVersion.v5_1_0.toString) + object ApiEndpoint1 extends Tag(nameOf(Implementations5_1_0.createCounterpartyLimit)) + object ApiEndpoint2 extends Tag(nameOf(Implementations5_1_0.getCounterpartyLimit)) + object ApiEndpoint3 extends Tag(nameOf(Implementations5_1_0.updateCounterpartyLimit)) + object ApiEndpoint4 extends Tag(nameOf(Implementations5_1_0.deleteCounterpartyLimit)) + + + val bankId = testBankId1.value + val accountId = testAccountId1.value + val ownerView = SYSTEM_OWNER_VIEW_ID + val postCounterpartyLimitV510 = code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.postCounterpartyLimitV510 + val putCounterpartyLimitV510 = PostCounterpartyLimitV510( + max_single_amount = 1, + max_monthly_amount = 2, + max_number_of_monthly_transactions = 3, + max_yearly_amount = 4, + max_number_of_yearly_transactions = 5 + ) + + + feature(s"test $ApiEndpoint1 Authorized access") { + + scenario("We will call the endpoint without user credentials", ApiEndpoint1, ApiEndpoint2,ApiEndpoint3,ApiEndpoint4,VersionOfApi) { + val counterparty = createCounterparty(bankId, accountId, accountId, true, UUID.randomUUID.toString); + + When("We make a request v5.1.0") + val request510 = (v5_1_0_Request / "banks" / bankId / "accounts" / accountId / "views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").POST + val response510 = makePostRequest(request510, write(postCounterpartyLimitV510)) + Then("We should get a 401") + response510.code should equal(401) + response510.body.extract[ErrorMessage].message should equal(UserNotLoggedIn) + + { + + val request510 = (v5_1_0_Request / "banks" / bankId / "accounts" / accountId /"views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").PUT + val response510 = makePutRequest(request510, write(postCounterpartyLimitV510)) + Then("We should get a 401") + response510.code should equal(401) + response510.body.extract[ErrorMessage].message should equal(UserNotLoggedIn) + + } + { + val request510 = (v5_1_0_Request / "banks" / bankId / "accounts" / accountId /"views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").GET + val response510 = makeGetRequest(request510) + Then("We should get a 401") + response510.code should equal(401) + response510.body.extract[ErrorMessage].message should equal(UserNotLoggedIn) + + } + { + val request510 = (v5_1_0_Request / "banks" / bankId / "accounts" / accountId /"views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").DELETE + val response510 = makeDeleteRequest(request510) + Then("We should get a 401") + response510.code should equal(401) + response510.body.extract[ErrorMessage].message should equal(UserNotLoggedIn) + + } + } + + scenario("We will call the endpoint success case", ApiEndpoint1, ApiEndpoint2,ApiEndpoint3,ApiEndpoint4,VersionOfApi) { + val counterparty = createCounterparty(bankId, accountId, accountId, true, UUID.randomUUID.toString); + + When("We make a request v5.1.0") + val request510 = (v5_1_0_Request / "banks" / bankId / "accounts" / accountId / "views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").POST <@ (user1) + val response510 = makePostRequest(request510, write(postCounterpartyLimitV510)) + Then("We should get a 201") + response510.code should equal(201) + response510.body.extract[CounterpartyLimitV510].max_monthly_amount should equal(postCounterpartyLimitV510.max_monthly_amount) + response510.body.extract[CounterpartyLimitV510].max_number_of_monthly_transactions should equal(postCounterpartyLimitV510.max_number_of_monthly_transactions) + response510.body.extract[CounterpartyLimitV510].max_number_of_yearly_transactions should equal(postCounterpartyLimitV510.max_number_of_yearly_transactions) + response510.body.extract[CounterpartyLimitV510].max_single_amount should equal(postCounterpartyLimitV510.max_single_amount) + response510.body.extract[CounterpartyLimitV510].max_yearly_amount should equal(postCounterpartyLimitV510.max_yearly_amount) + + { + val request510 = (v5_1_0_Request / "banks" / bankId / "accounts" / accountId /"views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").GET<@ (user1) + val response510 = makeGetRequest(request510) + Then("We should get a 200") + response510.code should equal(200) + response510.body.extract[CounterpartyLimitV510].max_monthly_amount should equal(postCounterpartyLimitV510.max_monthly_amount) + response510.body.extract[CounterpartyLimitV510].max_number_of_monthly_transactions should equal(postCounterpartyLimitV510.max_number_of_monthly_transactions) + response510.body.extract[CounterpartyLimitV510].max_number_of_yearly_transactions should equal(postCounterpartyLimitV510.max_number_of_yearly_transactions) + response510.body.extract[CounterpartyLimitV510].max_single_amount should equal(postCounterpartyLimitV510.max_single_amount) + response510.body.extract[CounterpartyLimitV510].max_yearly_amount should equal(postCounterpartyLimitV510.max_yearly_amount) + + } + + { + + val request510 = (v5_1_0_Request / "banks" / bankId / "accounts" / accountId /"views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").PUT<@ (user1) + val response510 = makePutRequest(request510, write(putCounterpartyLimitV510)) + Then("We should get a 200") + response510.code should equal(200) + response510.body.extract[CounterpartyLimitV510].max_monthly_amount should equal(putCounterpartyLimitV510.max_monthly_amount) + response510.body.extract[CounterpartyLimitV510].max_number_of_monthly_transactions should equal(putCounterpartyLimitV510.max_number_of_monthly_transactions) + response510.body.extract[CounterpartyLimitV510].max_number_of_yearly_transactions should equal(putCounterpartyLimitV510.max_number_of_yearly_transactions) + response510.body.extract[CounterpartyLimitV510].max_single_amount should equal(putCounterpartyLimitV510.max_single_amount) + response510.body.extract[CounterpartyLimitV510].max_yearly_amount should equal(putCounterpartyLimitV510.max_yearly_amount) + } + + { + val request510 = (v5_1_0_Request / "banks" / bankId / "accounts" / accountId /"views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").GET<@ (user1) + val response510 = makeGetRequest(request510) + Then("We should get a 200") + response510.code should equal(200) + response510.body.extract[CounterpartyLimitV510].max_monthly_amount should equal(putCounterpartyLimitV510.max_monthly_amount) + response510.body.extract[CounterpartyLimitV510].max_number_of_monthly_transactions should equal(putCounterpartyLimitV510.max_number_of_monthly_transactions) + response510.body.extract[CounterpartyLimitV510].max_number_of_yearly_transactions should equal(putCounterpartyLimitV510.max_number_of_yearly_transactions) + response510.body.extract[CounterpartyLimitV510].max_single_amount should equal(putCounterpartyLimitV510.max_single_amount) + response510.body.extract[CounterpartyLimitV510].max_yearly_amount should equal(putCounterpartyLimitV510.max_yearly_amount) + } + + { + val request510 = (v5_1_0_Request / "banks" / bankId / "accounts" / accountId /"views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").DELETE<@ (user1) + val response510 = makeDeleteRequest(request510) + Then("We should get a 204") + response510.code should equal(204) + } + } + + scenario("We will call the endpoint wrong bankId case", ApiEndpoint1, ApiEndpoint2,ApiEndpoint3,ApiEndpoint4,VersionOfApi) { + val counterparty = createCounterparty(bankId, accountId, accountId, true, UUID.randomUUID.toString); + + When("We make a request v5.1.0") + val request510 = (v5_1_0_Request / "banks" / "wrongId" / "accounts" / accountId / "views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").POST <@ (user1) + val response510 = makePostRequest(request510, write(postCounterpartyLimitV510)) + Then("We should get a 404") + response510.code should equal(404) + response510.body.extract[ErrorMessage].message contains(BankNotFound) shouldBe (true) + + { + val request510 = (v5_1_0_Request / "banks" / "wrongId" / "accounts" / accountId /"views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").GET<@ (user1) + val response510 = makeGetRequest(request510) + Then("We should get a 404") + response510.code should equal(404) + response510.body.extract[ErrorMessage].message contains(BankNotFound) shouldBe (true) + + } + + { + + val request510 = (v5_1_0_Request / "banks" / "wrongId" / "accounts" / accountId /"views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").PUT<@ (user1) + val response510 = makePutRequest(request510, write(putCounterpartyLimitV510)) + Then("We should get a 404") + response510.code should equal(404) + response510.body.extract[ErrorMessage].message contains(BankNotFound) shouldBe (true) + } + + { + val request510 = (v5_1_0_Request / "banks" / "wrongId" / "accounts" / accountId /"views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").GET<@ (user1) + val response510 = makeGetRequest(request510) + Then("We should get a 404") + response510.code should equal(404) + response510.body.extract[ErrorMessage].message contains(BankNotFound) shouldBe (true) + } + + { + val request510 = (v5_1_0_Request / "banks" / "wrongId" / "accounts" / accountId /"views" / ownerView /"counterparties" / counterparty.counterpartyId /"limits").DELETE<@ (user1) + val response510 = makeDeleteRequest(request510) + Then("We should get a 404") + response510.code should equal(404) + response510.body.extract[ErrorMessage].message contains(BankNotFound) shouldBe (true) + } + } + } +}