From 2b8d2c8d948bbb64e95cfce2807c5d46284102b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Fri, 31 Mar 2023 07:11:54 +0200 Subject: [PATCH] feature/Create ATM Attributes Endpoints --- .../main/scala/bootstrap/liftweb/Boot.scala | 2 + .../SwaggerDefinitionsJSON.scala | 17 +- .../main/scala/code/api/util/ApiRole.scala | 18 +- .../main/scala/code/api/util/NewStyle.scala | 59 +++++ .../scala/code/api/v5_1_0/APIMethods510.scala | 239 +++++++++++++++++- .../code/api/v5_1_0/JSONFactory5.1.0.scala | 62 +++++ .../code/atmattribute/AtmAttribute.scala | 47 ++++ .../MappedAtmAttributeProvider.scala | 105 ++++++++ .../scala/code/bankconnectors/Connector.scala | 22 ++ .../bankconnectors/LocalMappedConnector.scala | 35 +++ .../commons/model/CommonModelTrait.scala | 10 + .../commons/model/enums/Enumerations.scala | 8 +- 12 files changed, 618 insertions(+), 6 deletions(-) create mode 100644 obp-api/src/main/scala/code/atmattribute/AtmAttribute.scala create mode 100644 obp-api/src/main/scala/code/atmattribute/MappedAtmAttributeProvider.scala diff --git a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala index 4e38a3d4e..1cd2b68b9 100644 --- a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala +++ b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala @@ -50,6 +50,7 @@ import code.api.util.migration.Migration import code.api.util.migration.Migration.DbFunction import code.apicollection.ApiCollection import code.apicollectionendpoint.ApiCollectionEndpoint +import code.atmattribute.AtmAttribute import code.atms.MappedAtm import code.authtypevalidation.AuthenticationTypeValidation import code.bankattribute.BankAttribute @@ -1010,6 +1011,7 @@ object ToSchemify { // The following tables are accessed directly via Mapper / JDBC val models: List[MetaMapper[_]] = List( AuthUser, + AtmAttribute, Admin, MappedBank, MappedBankAccount, 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 df7bb2264..d7ed89ad4 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 @@ -36,7 +36,7 @@ import com.openbankproject.commons.util.{ApiVersion, FieldNameApiVersions, Refle import net.liftweb.json import java.net.URLEncoder -import code.api.v5_1_0.{CertificateInfoJsonV510, CurrenciesJsonV510, CurrencyJsonV510} +import code.api.v5_1_0.{AtmAttributeJsonV510, AtmAttributeResponseJsonV510, CertificateInfoJsonV510, CurrenciesJsonV510, CurrencyJsonV510} import code.endpointMapping.EndpointMappingCommons import scala.collection.immutable.List @@ -3999,6 +3999,12 @@ object SwaggerDefinitionsJSON { value = "12345678", is_active = Some(true) ) + val atmAttributeJsonV510 = AtmAttributeJsonV510( + name = "TAX_ID", + `type` = "INTEGER", + value = "12345678", + is_active = Some(true) + ) val bankAttributeResponseJsonV400 = BankAttributeResponseJsonV400( bank_id = bankIdExample.value, bank_attribute_id = "613c83ea-80f9-4560-8404-b9cd4ec42a7f", @@ -4007,6 +4013,15 @@ object SwaggerDefinitionsJSON { value = "2012-04-23", is_active = Some(true) ) + val atmAttributeResponseJsonV510 = AtmAttributeResponseJsonV510( + bank_id = bankIdExample.value, + atm_id = atmIdExample.value, + atm_attribute_id = "613c83ea-80f9-4560-8404-b9cd4ec42a7f", + name = "OVERDRAFT_START_DATE", + `type` = "DATE_WITH_DAY", + value = "2012-04-23", + is_active = Some(true) + ) val accountAttributeJson = AccountAttributeJson( 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 64fe185fd..a61adeec9 100644 --- a/obp-api/src/main/scala/code/api/util/ApiRole.scala +++ b/obp-api/src/main/scala/code/api/util/ApiRole.scala @@ -474,10 +474,16 @@ object ApiRole { lazy val canUpdateProductAttribute = CanUpdateProductAttribute() case class CanUpdateBankAttribute(requiresBankId: Boolean = true) extends ApiRole - lazy val canUpdateBankAttribute = CanUpdateBankAttribute() + lazy val canUpdateBankAttribute = CanUpdateBankAttribute() + + case class CanUpdateAtmAttribute(requiresBankId: Boolean = true) extends ApiRole + lazy val canUpdateAtmAttribute = CanUpdateAtmAttribute() case class CanGetBankAttribute(requiresBankId: Boolean = true) extends ApiRole - lazy val canGetBankAttribute = CanGetBankAttribute() + lazy val canGetBankAttribute = CanGetBankAttribute() + + case class CanGetAtmAttribute(requiresBankId: Boolean = true) extends ApiRole + lazy val canGetAtmAttribute = CanGetAtmAttribute() case class CanGetProductAttribute(requiresBankId: Boolean = true) extends ApiRole lazy val canGetProductAttribute = CanGetProductAttribute() @@ -486,13 +492,19 @@ object ApiRole { lazy val canDeleteProductAttribute = CanDeleteProductAttribute() case class CanDeleteBankAttribute(requiresBankId: Boolean = true) extends ApiRole - lazy val canDeleteBankAttribute = CanDeleteBankAttribute() + lazy val canDeleteBankAttribute = CanDeleteBankAttribute() + + case class CanDeleteAtmAttribute(requiresBankId: Boolean = true) extends ApiRole + lazy val canDeleteAtmAttribute = CanDeleteAtmAttribute() case class CanCreateProductAttribute(requiresBankId: Boolean = true) extends ApiRole lazy val canCreateProductAttribute = CanCreateProductAttribute() case class CanCreateBankAttribute(requiresBankId: Boolean = true) extends ApiRole lazy val canCreateBankAttribute = CanCreateBankAttribute() + + case class CanCreateAtmAttribute(requiresBankId: Boolean = true) extends ApiRole + lazy val canCreateAtmAttribute = CanCreateAtmAttribute() case class CanUpdateProductFee(requiresBankId: Boolean = true) extends ApiRole lazy val canUpdateProductFee = CanUpdateProductFee() 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 8a78454b9..0ea36cbd9 100644 --- a/obp-api/src/main/scala/code/api/util/NewStyle.scala +++ b/obp-api/src/main/scala/code/api/util/NewStyle.scala @@ -3,6 +3,7 @@ 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} @@ -67,6 +68,7 @@ import code.api.dynamic.endpoint.helper.DynamicEndpointHelper import code.api.v4_0_0.JSONFactory400 import code.api.dynamic.endpoint.helper.DynamicEndpointHelper import code.api.dynamic.entity.helper.{DynamicEntityHelper, DynamicEntityInfo} +import code.atmattribute.AtmAttribute import code.bankattribute.BankAttribute import code.connectormethod.{ConnectorMethodProvider, JsonConnectorMethod} import code.customeraccountlinks.CustomerAccountLinkTrait @@ -1660,6 +1662,30 @@ object NewStyle extends MdcLoggable{ i => (connectorEmptyResponse(i._1, callContext), i._2) } } + + def createOrUpdateAtmAttribute( + bankId: BankId, + atmId: AtmId, + atmAttributeId: Option[String], + name: String, + attributeType: AtmAttributeType.Value, + value: String, + isActive: Option[Boolean], + callContext: Option[CallContext] + ): OBPReturnType[AtmAttribute] = { + Connector.connector.vend.createOrUpdateAtmAttribute( + bankId: BankId, + atmId: AtmId, + atmAttributeId: Option[String], + name: String, + attributeType: AtmAttributeType.Value, + value: String, + isActive: Option[Boolean], + callContext: Option[CallContext] + ) map { + i => (connectorEmptyResponse(i._1, callContext), i._2) + } + } def getBankAttributesByBank(bank: BankId,callContext: Option[CallContext]): OBPReturnType[List[BankAttribute]] = { Connector.connector.vend.getBankAttributesByBank( @@ -1669,6 +1695,15 @@ object NewStyle extends MdcLoggable{ i => (connectorEmptyResponse(i._1, callContext), i._2) } } + def getAtmAttributesByAtm(bank: BankId, atm: AtmId, callContext: Option[CallContext]): OBPReturnType[List[AtmAttribute]] = { + Connector.connector.vend.getAtmAttributesByAtm( + bank: BankId, + atm: AtmId, + callContext: Option[CallContext] + ) map { + i => (connectorEmptyResponse(i._1, callContext), i._2) + } + } def getProductAttributesByBankAndCode( bank: BankId, productCode: ProductCode, @@ -1707,6 +1742,18 @@ object NewStyle extends MdcLoggable{ } } + def getAtmAttributeById( + atmAttributeId: String, + callContext: Option[CallContext] + ): OBPReturnType[AtmAttribute] = { + Connector.connector.vend.getAtmAttributeById( + atmAttributeId: String, + callContext: Option[CallContext] + ) map { + i => (connectorEmptyResponse(i._1, callContext), i._2) + } + } + def deleteBankAttribute( bankAttributeId: String, callContext: Option[CallContext] @@ -1717,6 +1764,18 @@ object NewStyle extends MdcLoggable{ ) map { i => (connectorEmptyResponse(i._1, callContext), i._2) } + } + + def deleteAtmAttribute( + atmAttributeId: String, + callContext: Option[CallContext] + ): OBPReturnType[Boolean] = { + Connector.connector.vend.deleteAtmAttribute( + atmAttributeId: String, + callContext: Option[CallContext] + ) map { + i => (connectorEmptyResponse(i._1, callContext), i._2) + } } def deleteProductAttribute( 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 b032a4579..a00a9b0cc 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 @@ -24,7 +24,8 @@ import code.util.Helper import code.views.system.{AccountAccess, ViewDefinition} import com.github.dwickern.macros.NameOf.nameOf import com.openbankproject.commons.ExecutionContext.Implicits.global -import com.openbankproject.commons.model.BankId +import com.openbankproject.commons.model.{AtmId, BankId} +import com.openbankproject.commons.model.enums.AtmAttributeType import com.openbankproject.commons.util.{ApiVersion, ScannedApiVersion} import net.liftweb.common.Full import net.liftweb.http.rest.RestHelper @@ -292,6 +293,242 @@ trait APIMethods510 { } } + + + + + + + + + + + + staticResourceDocs += ResourceDoc( + createAtmAttribute, + implementedInApiVersion, + nameOf(createAtmAttribute), + "POST", + "/banks/BANK_ID/atms/ATM_ID/attributes", + "Create ATM Attribute", + s""" Create ATM Attribute + | + |The type field must be one of "STRING", "INTEGER", "DOUBLE" or DATE_WITH_DAY" + | + |${authenticationRequiredMessage(true)} + | + |""", + atmAttributeJsonV510, + atmAttributeResponseJsonV510, + List( + $UserNotLoggedIn, + $BankNotFound, + InvalidJsonFormat, + UnknownError + ), + List(apiTagATM, apiTagNewStyle), + Some(List(canCreateAtmAttribute)) + ) + + lazy val createAtmAttribute : OBPEndpoint = { + case "banks" :: BankId(bankId) :: "atms" :: AtmId(atmId) :: "attributes" :: Nil JsonPost json -> _=> { + cc => + for { + (_, callContext) <- NewStyle.function.getAtm(bankId, atmId, cc.callContext) + failMsg = s"$InvalidJsonFormat The Json body should be the $AtmAttributeJsonV510 " + postedData <- NewStyle.function.tryons(failMsg, 400, callContext) { + json.extract[AtmAttributeJsonV510] + } + failMsg = s"$InvalidJsonFormat The `Type` field can only accept the following field: " + + s"${AtmAttributeType.DOUBLE}(12.1234), ${AtmAttributeType.STRING}(TAX_NUMBER), ${AtmAttributeType.INTEGER}(123) and ${AtmAttributeType.DATE_WITH_DAY}(2012-04-23)" + bankAttributeType <- NewStyle.function.tryons(failMsg, 400, callContext) { + AtmAttributeType.withName(postedData.`type`) + } + (atmAttribute, callContext) <- NewStyle.function.createOrUpdateAtmAttribute( + bankId, + atmId, + None, + postedData.name, + bankAttributeType, + postedData.value, + postedData.is_active, + callContext: Option[CallContext] + ) + } yield { + (JSONFactory510.createAtmAttributeJson(atmAttribute), HttpCode.`201`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( + getAtmAttributes, + implementedInApiVersion, + nameOf(getAtmAttributes), + "GET", + "/banks/BANK_ID/atms/ATM_ID/attributes", + "Get ATM Attributes", + s""" Get ATM Attributes + | + |${authenticationRequiredMessage(true)} + | + |""", + EmptyBody, + transactionAttributesResponseJson, + List( + $UserNotLoggedIn, + $BankNotFound, + InvalidJsonFormat, + UnknownError + ), + List(apiTagATM, apiTagNewStyle), + Some(List(canGetAtmAttribute)) + ) + + lazy val getAtmAttributes : OBPEndpoint = { + case "banks" :: BankId(bankId) :: "atms" :: AtmId(atmId) :: "attributes" :: Nil JsonGet _ => { + cc => + for { + (_, callContext) <- NewStyle.function.getAtm(bankId, atmId, cc.callContext) + (attributes, callContext) <- NewStyle.function.getAtmAttributesByAtm(bankId, atmId, callContext) + } yield { + (JSONFactory510.createAtmAttributesJson(attributes), HttpCode.`200`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( + getAtmAttribute, + implementedInApiVersion, + nameOf(getAtmAttribute), + "GET", + "/banks/BANK_ID/atms/ATM_ID/attributes/ATM_ATTRIBUTE_ID", + "Get ATM Attribute By ATM_ATTRIBUTE_ID", + s""" Get ATM Attribute By ATM_ATTRIBUTE_ID + | + |${authenticationRequiredMessage(true)} + | + |""", + EmptyBody, + atmAttributeResponseJsonV510, + List( + $UserNotLoggedIn, + $BankNotFound, + InvalidJsonFormat, + UnknownError + ), + List(apiTagATM, apiTagNewStyle), + Some(List(canGetAtmAttribute)) + ) + + lazy val getAtmAttribute : OBPEndpoint = { + case "banks" :: BankId(bankId) :: "atms" :: AtmId(atmId) :: "attributes" :: atmAttributeId :: Nil JsonGet _ => { + cc => + for { + (_, callContext) <- NewStyle.function.getAtm(bankId, atmId, cc.callContext) + (attribute, callContext) <- NewStyle.function.getAtmAttributeById(atmAttributeId, callContext) + } yield { + (JSONFactory510.createAtmAttributeJson(attribute), HttpCode.`200`(callContext)) + } + } + } + + + staticResourceDocs += ResourceDoc( + updateAtmAttribute, + implementedInApiVersion, + nameOf(updateAtmAttribute), + "PUT", + "/banks/BANK_ID/atms/ATM_ID/attributes/ATM_ATTRIBUTE_ID", + "Update ATM Attribute", + s""" Update ATM Attribute. + | + |Update an ATM Attribute by its id. + | + |${authenticationRequiredMessage(true)} + | + |""", + atmAttributeJsonV510, + atmAttributeResponseJsonV510, + List( + $UserNotLoggedIn, + $BankNotFound, + UserHasMissingRoles, + UnknownError + ), + List(apiTagATM, apiTagNewStyle), + Some(List(canUpdateAtmAttribute)) + ) + + lazy val updateAtmAttribute : OBPEndpoint = { + case "banks" :: BankId(bankId) :: "atms" :: AtmId(atmId) :: "attributes" :: atmAttributeId :: Nil JsonPut json -> _ =>{ + cc => + for { + (_, callContext) <- NewStyle.function.getAtm(bankId, atmId, cc.callContext) + failMsg = s"$InvalidJsonFormat The Json body should be the $AtmAttributeJsonV510 " + postedData <- NewStyle.function.tryons(failMsg, 400, callContext) { + json.extract[AtmAttributeJsonV510] + } + failMsg = s"$InvalidJsonFormat The `Type` field can only accept the following field: " + + s"${AtmAttributeType.DOUBLE}(12.1234), ${AtmAttributeType.STRING}(TAX_NUMBER), ${AtmAttributeType.INTEGER}(123) and ${AtmAttributeType.DATE_WITH_DAY}(2012-04-23)" + atmAttributeType <- NewStyle.function.tryons(failMsg, 400, cc.callContext) { + AtmAttributeType.withName(postedData.`type`) + } + (_, callContext) <- NewStyle.function.getAtmAttributeById(atmAttributeId, cc.callContext) + (atmAttribute, callContext) <- NewStyle.function.createOrUpdateAtmAttribute( + bankId, + atmId, + Some(atmAttributeId), + postedData.name, + atmAttributeType, + postedData.value, + postedData.is_active, + callContext: Option[CallContext] + ) + } yield { + (JSONFactory510.createAtmAttributeJson(atmAttribute), HttpCode.`200`(callContext)) + } + } + } + + + staticResourceDocs += ResourceDoc( + deleteAtmAttribute, + implementedInApiVersion, + nameOf(deleteAtmAttribute), + "DELETE", + "/banks/BANK_ID/atms/ATM_ID/attributes/ATM_ATTRIBUTE_ID", + "Delete ATM Attribute", + s""" Delete ATM Attribute + | + |Delete a Atm Attribute by its id. + | + |${authenticationRequiredMessage(true)} + | + |""", + EmptyBody, + EmptyBody, + List( + $UserNotLoggedIn, + $BankNotFound, + UserHasMissingRoles, + UnknownError + ), + List(apiTagATM, apiTagNewStyle), + Some(List(canDeleteAtmAttribute)) + ) + + lazy val deleteAtmAttribute : OBPEndpoint = { + case "banks" :: BankId(bankId) :: "atms" :: AtmId(atmId) :: "attributes" :: atmAttributeId :: Nil JsonDelete _=> { + cc => + for { + (_, callContext) <- NewStyle.function.getAtm(bankId, atmId, cc.callContext) + (atmAttribute, callContext) <- NewStyle.function.deleteAtmAttribute(atmAttributeId, callContext) + } yield { + (Full(atmAttribute), HttpCode.`204`(callContext)) + } + } + } + staticResourceDocs += ResourceDoc( 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 808614fb7..c111eceb8 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 @@ -30,6 +30,7 @@ import code.api.Constant import code.api.util.APIUtil import code.api.util.APIUtil.gitCommit import code.api.v4_0_0.{EnergySource400, HostedAt400, HostedBy400} +import code.atmattribute.AtmAttribute import code.views.system.{AccountAccess, ViewDefinition} import com.openbankproject.commons.util.{ApiVersion, ScannedApiVersion} @@ -67,6 +68,53 @@ case class CurrencyJsonV510(alphanumeric_code: String) case class CurrenciesJsonV510(currencies: List[CurrencyJsonV510]) + +case class ProductAttributeJsonV510( + name: String, + `type`: String, + value: String, + is_active: Option[Boolean] + ) +case class ProductAttributeResponseJsonV510( + bank_id: String, + product_code: String, + product_attribute_id: String, + name: String, + `type`: String, + value: String, + is_active: Option[Boolean] + ) +case class ProductAttributeResponseWithoutBankIdJsonV510( + product_code: String, + product_attribute_id: String, + name: String, + `type`: String, + value: String, + is_active: Option[Boolean] + ) + +case class AtmAttributeJsonV510( + name: String, + `type`: String, + value: String, + is_active: Option[Boolean]) + +case class AtmAttributeResponseJsonV510( + bank_id: String, + atm_id: String, + atm_attribute_id: String, + name: String, + `type`: String, + value: String, + is_active: Option[Boolean] + ) +case class AtmAttributesResponseJsonV510(bank_attributes: List[AtmAttributeResponseJsonV510]) +case class AtmAttributeBankResponseJsonV510(name: String, + value: String) +case class AtmAttributesResponseJson(list: List[AtmAttributeBankResponseJsonV510]) + + + object JSONFactory510 { def getCustomViewNamesCheck(views: List[ViewDefinition]): CheckSystemIntegrityJsonV510 = { @@ -136,6 +184,20 @@ object JSONFactory510 { ) } + def createAtmAttributeJson(atmAttribute: AtmAttribute): AtmAttributeResponseJsonV510 = + AtmAttributeResponseJsonV510( + bank_id = atmAttribute.bankId.value, + atm_id = atmAttribute.atmId.value, + atm_attribute_id = atmAttribute.atmAttributeId, + name = atmAttribute.name, + `type` = atmAttribute.attributeType.toString, + value = atmAttribute.value, + is_active = atmAttribute.isActive + ) + + def createAtmAttributesJson(bankAttributes: List[AtmAttribute]): AtmAttributesResponseJsonV510 = + AtmAttributesResponseJsonV510(bankAttributes.map(createAtmAttributeJson)) + } diff --git a/obp-api/src/main/scala/code/atmattribute/AtmAttribute.scala b/obp-api/src/main/scala/code/atmattribute/AtmAttribute.scala new file mode 100644 index 000000000..fd991db67 --- /dev/null +++ b/obp-api/src/main/scala/code/atmattribute/AtmAttribute.scala @@ -0,0 +1,47 @@ +package code.atmattribute + +/* For ProductAttribute */ + +import com.openbankproject.commons.model.{AtmId, BankId} +import com.openbankproject.commons.model.enums.AtmAttributeType +import net.liftweb.common.{Box, Logger} +import net.liftweb.util.SimpleInjector + +import scala.concurrent.Future + +object AtmAttributeX extends SimpleInjector { + + val atmAttributeProvider = new Inject(buildOne _) {} + + def buildOne: AtmAttributeProviderTrait = AtmAttributeProvider + + // Helper to get the count out of an option + def countOfAtmAttribute(listOpt: Option[List[AtmAttribute]]): Int = { + val count = listOpt match { + case Some(list) => list.size + case None => 0 + } + count + } + + +} + +trait AtmAttributeProviderTrait { + + private val logger = Logger(classOf[AtmAttributeProviderTrait]) + + def getAtmAttributesFromProvider(bankId: BankId, atmId: AtmId): Future[Box[List[AtmAttribute]]] + + def getAtmAttributeById(AtmAttributeId: String): Future[Box[AtmAttribute]] + + def createOrUpdateAtmAttribute(bankId : BankId, + atmId: AtmId, + AtmAttributeId: Option[String], + name: String, + attributeType: AtmAttributeType.Value, + value: String, + isActive: Option[Boolean]): Future[Box[AtmAttribute]] + def deleteAtmAttribute(AtmAttributeId: String): Future[Box[Boolean]] + // End of Trait +} diff --git a/obp-api/src/main/scala/code/atmattribute/MappedAtmAttributeProvider.scala b/obp-api/src/main/scala/code/atmattribute/MappedAtmAttributeProvider.scala new file mode 100644 index 000000000..11080f46d --- /dev/null +++ b/obp-api/src/main/scala/code/atmattribute/MappedAtmAttributeProvider.scala @@ -0,0 +1,105 @@ +package code.atmattribute + +import code.util.{MappedUUID, UUIDString} +import com.openbankproject.commons.ExecutionContext.Implicits.global +import com.openbankproject.commons.model.enums.AtmAttributeType +import com.openbankproject.commons.model.{AtmAttributeTrait, AtmId, BankId} +import net.liftweb.common.{Box, Empty, Full} +import net.liftweb.mapper.{MappedBoolean, _} +import net.liftweb.util.Helpers.tryo + +import scala.concurrent.Future + + +object AtmAttributeProvider extends AtmAttributeProviderTrait { + + override def getAtmAttributesFromProvider(bankId: BankId, atmId: AtmId): Future[Box[List[AtmAttribute]]] = + Future { + Box !! AtmAttribute.findAll( + By(AtmAttribute.BankId_, bankId.value), + By(AtmAttribute.AtmId_, atmId.value) + ) + } + + override def getAtmAttributeById(AtmAttributeId: String): Future[Box[AtmAttribute]] = Future { + AtmAttribute.find(By(AtmAttribute.AtmAttributeId, AtmAttributeId)) + } + + override def createOrUpdateAtmAttribute(bankId: BankId, + atmId: AtmId, + AtmAttributeId: Option[String], + name: String, + attributeType: AtmAttributeType.Value, + value: String, + isActive: Option[Boolean]): Future[Box[AtmAttribute]] = { + AtmAttributeId match { + case Some(id) => Future { + AtmAttribute.find(By(AtmAttribute.AtmAttributeId, id)) match { + case Full(attribute) => tryo { + attribute + .BankId_(bankId.value) + .AtmId_(atmId.value) + .Name(name) + .Type(attributeType.toString) + .`Value`(value) + .IsActive(isActive.getOrElse(true)) + .saveMe() + } + case _ => Empty + } + } + case None => Future { + Full { + AtmAttribute.create + .BankId_(bankId.value) + .AtmId_(atmId.value) + .Name(name) + .Type(attributeType.toString()) + .`Value`(value) + .IsActive(isActive.getOrElse(true)) + .saveMe() + } + } + } + } + + override def deleteAtmAttribute(AtmAttributeId: String): Future[Box[Boolean]] = Future { + Some( + AtmAttribute.bulkDelete_!!(By(AtmAttribute.AtmAttributeId, AtmAttributeId)) + ) + } +} + +class AtmAttribute extends AtmAttributeTrait with LongKeyedMapper[AtmAttribute] with IdPK { + + override def getSingleton = AtmAttribute + + object BankId_ extends UUIDString(this) { + override def dbColumnName = "BankId" + } + object AtmId_ extends UUIDString(this) { + override def dbColumnName = "AtmId" + } + object AtmAttributeId extends MappedUUID(this) + object Name extends MappedString(this, 50) + object Type extends MappedString(this, 50) + object `Value` extends MappedString(this, 255) + object IsActive extends MappedBoolean(this) { + override def defaultValue = true + } + + + override def bankId: BankId = BankId(BankId_.get) + override def atmId: AtmId = AtmId(AtmId_.get) + override def atmAttributeId: String = AtmAttributeId.get + override def name: String = Name.get + override def attributeType: AtmAttributeType.Value = AtmAttributeType.withName(Type.get) + override def value: String = `Value`.get + override def isActive: Option[Boolean] = if (IsActive.jdbcFriendly(IsActive.calcFieldName) == null) { None } else Some(IsActive.get) + +} + +object AtmAttribute extends AtmAttribute with LongKeyedMetaMapper[AtmAttribute] { + override def dbIndexes: List[BaseIndex[AtmAttribute]] = Index(BankId_, AtmId_) :: super.dbIndexes +} + diff --git a/obp-api/src/main/scala/code/bankconnectors/Connector.scala b/obp-api/src/main/scala/code/bankconnectors/Connector.scala index 2f2e7ad94..e2ad37791 100644 --- a/obp-api/src/main/scala/code/bankconnectors/Connector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/Connector.scala @@ -16,6 +16,7 @@ import code.api.v1_4_0.JSONFactory1_4_0.TransactionRequestAccountJsonV140 import code.api.v2_1_0._ import code.api.v4_0_0.ModeratedFirehoseAccountsJsonV400 import code.api.{APIFailure, APIFailureNewStyle} +import code.atmattribute.AtmAttribute import code.bankattribute.BankAttribute import code.bankconnectors.LocalMappedConnector.setUnimplementedError import code.bankconnectors.akka.AkkaConnector_vDec2018 @@ -2122,13 +2123,30 @@ trait Connector extends MdcLoggable { isActive: Option[Boolean], callContext: Option[CallContext] ): OBPReturnType[Box[BankAttribute]] = Future{(Failure(setUnimplementedError), callContext)} + + def createOrUpdateAtmAttribute(bankId: BankId, + atmId: AtmId, + atmAttributeId: Option[String], + name: String, + atmAttributeType: AtmAttributeType.Value, + value: String, + isActive: Option[Boolean], + callContext: Option[CallContext] + ): OBPReturnType[Box[AtmAttribute]] = Future{(Failure(setUnimplementedError), callContext)} def getBankAttributesByBank(bank: BankId, callContext: Option[CallContext]): OBPReturnType[Box[List[BankAttribute]]] = Future{(Failure(setUnimplementedError), callContext)} + def getAtmAttributesByAtm(bank: BankId, atm: AtmId, callContext: Option[CallContext]): OBPReturnType[Box[List[AtmAttribute]]] = + Future{(Failure(setUnimplementedError), callContext)} + def getBankAttributeById(bankAttributeId: String, callContext: Option[CallContext] ): OBPReturnType[Box[BankAttribute]] = Future{(Failure(setUnimplementedError), callContext)} + + def getAtmAttributeById(atmAttributeId: String, + callContext: Option[CallContext]): OBPReturnType[Box[AtmAttribute]] = + Future{(Failure(setUnimplementedError), callContext)} def getProductAttributeById( productAttributeId: String, @@ -2146,6 +2164,10 @@ trait Connector extends MdcLoggable { callContext: Option[CallContext] ): OBPReturnType[Box[Boolean]] = Future{(Failure(setUnimplementedError), callContext)} + def deleteAtmAttribute(atmAttributeId: String, + callContext: Option[CallContext] + ): OBPReturnType[Box[Boolean]] = Future{(Failure(setUnimplementedError), callContext)} + def deleteProductAttribute( productAttributeId: String, callContext: Option[CallContext] diff --git a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala index c32f8c8e5..1bf2d3759 100644 --- a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -22,6 +22,7 @@ import code.api.util._ import code.api.v1_4_0.JSONFactory1_4_0.TransactionRequestAccountJsonV140 import code.api.v2_1_0._ import code.api.v4_0_0.{PostSimpleCounterpartyJson400, TransactionRequestBodySimpleJsonV400} +import code.atmattribute.{AtmAttribute, AtmAttributeX} import code.atms.Atms.Atm import code.atms.{Atms, MappedAtm} import code.bankattribute.{BankAttribute, BankAttributeX} @@ -3833,12 +3834,36 @@ object LocalMappedConnector extends Connector with MdcLoggable { value: String, isActive: Option[Boolean]) map { (_, callContext) } + + override def createOrUpdateAtmAttribute(bankId: BankId, + atmId: AtmId, + atmAttributeId: Option[String], + name: String, + atmAttributeType: AtmAttributeType.Value, + value: String, + isActive: Option[Boolean], + callContext: Option[CallContext] + ): OBPReturnType[Box[AtmAttribute]] = + AtmAttributeX.atmAttributeProvider.vend.createOrUpdateAtmAttribute( + bankId: BankId, + atmId: AtmId, + atmAttributeId: Option[String], + name: String, + atmAttributeType: AtmAttributeType.Value, + value: String, isActive: Option[Boolean]) map { + (_, callContext) + } override def getBankAttributesByBank(bank: BankId, callContext: Option[CallContext]): OBPReturnType[Box[List[BankAttribute]]] = BankAttributeX.bankAttributeProvider.vend.getBankAttributesFromProvider(bank: BankId) map { (_, callContext) } + + override def getAtmAttributesByAtm(bank: BankId, atm: AtmId, callContext: Option[CallContext]): OBPReturnType[Box[List[AtmAttribute]]] = + AtmAttributeX.atmAttributeProvider.vend.getAtmAttributesFromProvider(bank: BankId, atm: AtmId) map { + (_, callContext) + } override def getProductAttributesByBankAndCode( bank: BankId, @@ -3854,6 +3879,11 @@ object LocalMappedConnector extends Connector with MdcLoggable { (_, callContext) } + override def getAtmAttributeById(atmAttributeId: String, callContext: Option[CallContext]): OBPReturnType[Box[AtmAttribute]] = + AtmAttributeX.atmAttributeProvider.vend.getAtmAttributeById(atmAttributeId: String) map { + (_, callContext) + } + override def getProductAttributeById( productAttributeId: String, callContext: Option[CallContext] @@ -3867,6 +3897,11 @@ object LocalMappedConnector extends Connector with MdcLoggable { BankAttributeX.bankAttributeProvider.vend.deleteBankAttribute(bankAttributeId: String) map { (_, callContext) } + override def deleteAtmAttribute(atmAttributeId: String, + callContext: Option[CallContext]): OBPReturnType[Box[Boolean]] = + AtmAttributeX.atmAttributeProvider.vend.deleteAtmAttribute(atmAttributeId: String) map { + (_, callContext) + } override def deleteProductAttribute( productAttributeId: String, diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/model/CommonModelTrait.scala b/obp-commons/src/main/scala/com/openbankproject/commons/model/CommonModelTrait.scala index 1425fe19b..23342a60e 100644 --- a/obp-commons/src/main/scala/com/openbankproject/commons/model/CommonModelTrait.scala +++ b/obp-commons/src/main/scala/com/openbankproject/commons/model/CommonModelTrait.scala @@ -469,6 +469,16 @@ trait CustomerMessage { def transport : Option[String] = None //TODO, introduced from V400, may set mandatory later, need to check V140. } +trait AtmAttributeTrait { + def bankId: BankId + def atmId: AtmId + def atmAttributeId: String + def attributeType: AtmAttributeType.Value + def name: String + def value: String + def isActive: Option[Boolean] +} + trait BankAttributeTrait { def bankId: BankId def bankAttributeId: String diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/model/enums/Enumerations.scala b/obp-commons/src/main/scala/com/openbankproject/commons/model/enums/Enumerations.scala index d242d4870..28ff90cc5 100644 --- a/obp-commons/src/main/scala/com/openbankproject/commons/model/enums/Enumerations.scala +++ b/obp-commons/src/main/scala/com/openbankproject/commons/model/enums/Enumerations.scala @@ -15,7 +15,13 @@ object UserAttributeType extends OBPEnumeration[UserAttributeType]{ object DOUBLE extends Value object DATE_WITH_DAY extends Value } - +sealed trait AtmAttributeType extends EnumValue +object AtmAttributeType extends OBPEnumeration[AtmAttributeType]{ + object STRING extends Value + object INTEGER extends Value + object DOUBLE extends Value + object DATE_WITH_DAY extends Value +} sealed trait BankAttributeType extends EnumValue object BankAttributeType extends OBPEnumeration[BankAttributeType]{ object STRING extends Value