diff --git a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala index 37723d3f1..dd71ba290 100644 --- a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala +++ b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala @@ -1129,7 +1129,7 @@ object ToSchemify { CustomerAccountLink, TransactionIdMapping, RegulatedEntityAttribute, - BankAccountBalance + code.bankaccountbalance.BankAccountBalance ) // 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 a37cb357d..061691dbb 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 @@ -5669,7 +5669,22 @@ object SwaggerDefinitionsJSON { lazy val regulatedEntityAttributesJsonV510 = RegulatedEntityAttributesJsonV510( List(regulatedEntityAttributeResponseJsonV510) ) + + lazy val bankAccountBalanceRequestJsonV510 = BankAccountBalanceRequestJsonV510( + balance_type = balanceTypeExample.value, + balance_amount = balanceAmountExample.value + ) + lazy val bankAccountBalanceResponseJsonV510 = BankAccountBalanceResponseJsonV510( + balance_id = balanceIdExample.value, + account_id = accountIdExample.value, + balance_type = balanceTypeExample.value, + balance_amount = balanceAmountExample.value + ) + + lazy val bankAccountBalancesJsonV510 = BankAccountBalancesJsonV510( + balances = List(bankAccountBalanceResponseJsonV510) + ) //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 33297ba01..7b228f65f 100644 --- a/obp-api/src/main/scala/code/api/util/ApiRole.scala +++ b/obp-api/src/main/scala/code/api/util/ApiRole.scala @@ -1009,7 +1009,23 @@ object ApiRole extends MdcLoggable{ case class CanGetBankLevelEndpointTag(requiresBankId: Boolean = true) extends ApiRole lazy val canGetBankLevelEndpointTag = CanGetBankLevelEndpointTag() - + + // BankAccountBalance roles + case class CanCreateBankAccountBalance(requiresBankId: Boolean = false) extends ApiRole + lazy val canCreateBankAccountBalance = CanCreateBankAccountBalance() + + case class CanGetBankAccountBalance(requiresBankId: Boolean = false) extends ApiRole + lazy val canGetBankAccountBalance = CanGetBankAccountBalance() + + case class CanGetBankAccountBalances(requiresBankId: Boolean = false) extends ApiRole + lazy val canGetBankAccountBalances = CanGetBankAccountBalances() + + case class CanUpdateBankAccountBalance(requiresBankId: Boolean = false) extends ApiRole + lazy val canUpdateBankAccountBalance = CanUpdateBankAccountBalance() + + case class CanDeleteBankAccountBalance(requiresBankId: Boolean = false) extends ApiRole + lazy val canDeleteBankAccountBalance = CanDeleteBankAccountBalance() + case class CanCreateHistoricalTransactionAtBank(requiresBankId: Boolean = true) extends ApiRole lazy val canCreateHistoricalTransactionAtBank = CanCreateHistoricalTransactionAtBank() 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 8e6265150..db3934772 100644 --- a/obp-api/src/main/scala/code/api/util/ApiTag.scala +++ b/obp-api/src/main/scala/code/api/util/ApiTag.scala @@ -67,6 +67,7 @@ object ApiTag { val apiTagMXOpenFinance = ResourceDocTag("MXOpenFinance") val apiTagAggregateMetrics = ResourceDocTag("Aggregate-Metrics") val apiTagSystemIntegrity = ResourceDocTag("System-Integrity") + val apiTagBalance = ResourceDocTag("Balance") val apiTagWebhook = ResourceDocTag("Webhook") val apiTagMockedData = ResourceDocTag("Mocked-Data") val apiTagConsent = ResourceDocTag("Consent") 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 610f24125..18c385d30 100644 --- a/obp-api/src/main/scala/code/api/util/ExampleValue.scala +++ b/obp-api/src/main/scala/code/api/util/ExampleValue.scala @@ -298,6 +298,12 @@ object ExampleValue { lazy val accountTypeExample = ConnectorField("AC","A short code that represents the type of the account as provided by the bank.") lazy val balanceAmountExample = ConnectorField("50.89", "The balance on the account.") + + lazy val balanceTypeExample = ConnectorField("openingBooked", "The balance type.") + glossaryItems += makeGlossaryItem("balance_type", balanceTypeExample) + + lazy val balanceIdExample = ConnectorField("7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", "A string that MUST uniquely identify the Account Balance on this OBP instance, can be used in all cache.") + glossaryItems += makeGlossaryItem("balance_id", balanceIdExample) lazy val amountExample = ConnectorField("10.12", "The balance on the account.") diff --git a/obp-api/src/main/scala/code/api/util/newstyle/BankAccountBalanceNewStyle.scala b/obp-api/src/main/scala/code/api/util/newstyle/BankAccountBalanceNewStyle.scala new file mode 100644 index 000000000..4fa3232e4 --- /dev/null +++ b/obp-api/src/main/scala/code/api/util/newstyle/BankAccountBalanceNewStyle.scala @@ -0,0 +1,91 @@ +package code.api.util.newstyle + +import code.api.util.APIUtil.{OBPReturnType, unboxFullOrFail} +import code.api.util.ErrorMessages.{InvalidConnectorResponse} +import code.api.util.CallContext +import code.bankaccountbalance.{BankAccountBalanceX} +import com.openbankproject.commons.ExecutionContext.Implicits.global +import com.openbankproject.commons.model.{AccountId, BankAccountBalanceTrait} +import com.github.dwickern.macros.NameOf.nameOf +import com.openbankproject.commons.model.BalanceId + + +object BankAccountBalanceNewStyle { + + def getBankAccountBalances( + accountId: AccountId, + callContext: Option[CallContext] + ): OBPReturnType[List[BankAccountBalanceTrait]] = { + BankAccountBalanceX.bankAccountBalanceProvider.vend.getBankAccountBalances(accountId).map { + result => + ( + unboxFullOrFail( + result, + callContext, + s"$InvalidConnectorResponse ${nameOf(getBankAccountBalances _)}", + 404), + callContext + ) + } + } + + def getBankAccountBalanceById( + balanceId: BalanceId, + callContext: Option[CallContext] + ): OBPReturnType[BankAccountBalanceTrait] = { + BankAccountBalanceX.bankAccountBalanceProvider.vend.getBankAccountBalanceById(balanceId).map { + result => + ( + unboxFullOrFail( + result, + callContext, + s"$InvalidConnectorResponse ${nameOf(getBankAccountBalanceById _)}", + 404), + callContext + ) + } + } + + def createOrUpdateBankAccountBalance( + balanceId: Option[BalanceId], + accountId: AccountId, + balanceType: String, + balanceAmount: BigDecimal, + callContext: Option[CallContext] + ): OBPReturnType[BankAccountBalanceTrait] = { + BankAccountBalanceX.bankAccountBalanceProvider.vend.createOrUpdateBankAccountBalance( + balanceId, + accountId, + balanceType, + balanceAmount + ).map { + result => + ( + unboxFullOrFail( + result, + callContext, + s"$InvalidConnectorResponse ${nameOf(createOrUpdateBankAccountBalance _)}", + 400), + callContext + ) + } + } + + def deleteBankAccountBalance( + balanceId: BalanceId, + callContext: Option[CallContext] + ): OBPReturnType[Boolean] = { + BankAccountBalanceX.bankAccountBalanceProvider.vend.deleteBankAccountBalance(balanceId).map { + result => + ( + unboxFullOrFail( + result, + callContext, + s"$InvalidConnectorResponse ${nameOf(deleteBankAccountBalance _)}", + 400), + callContext + ) + } + } + +} \ No newline at end of file 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 3c1449092..025336220 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 @@ -188,6 +188,221 @@ trait APIMethods510 { } } + staticResourceDocs += ResourceDoc( + createBankAccountBalance, + implementedInApiVersion, + nameOf(createBankAccountBalance), + "POST", + "/accounts/ACCOUNT_ID/balances", + "Create Bank Account Balance", + s"""Create a new Balance for a Bank Account. + | + |${userAuthenticationMessage(true)} + | + |""", + bankAccountBalanceRequestJsonV510, + bankAccountBalanceResponseJsonV510, + List( + $UserNotLoggedIn, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), + List(apiTagAccount, apiTagBalance), + Some(List(canCreateBankAccountBalance)) + ) + + lazy val createBankAccountBalance: OBPEndpoint = { + case "accounts" :: AccountId(accountId) :: "balances" :: Nil JsonPost json -> _ => { + cc => + implicit val ec = EndpointContext(Some(cc)) + for { + (Full(u), callContext) <- SS.user + postedData <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the $BankAccountBalanceRequestJsonV510 ", 400, callContext) { + json.extract[BankAccountBalanceRequestJsonV510] + } + balanceAmount <- NewStyle.function.tryons(s"$InvalidNumber Current balance_amount is ${postedData.balance_amount}" , 400, cc.callContext) { + BigDecimal(postedData.balance_amount) + } + (balance, callContext) <- code.api.util.newstyle.BankAccountBalanceNewStyle.createOrUpdateBankAccountBalance( + balanceId = None, + accountId = accountId, + balanceType = postedData.balance_type, + balanceAmount = balanceAmount, + callContext = cc.callContext + ) + } yield { + (JSONFactory510.createBankAccountBalanceJson(balance), HttpCode.`201`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( + getBankAccountBalanceById, + implementedInApiVersion, + nameOf(getBankAccountBalanceById), + "GET", + "/accounts/ACCOUNT_ID/balances/BALANCE_ID", + "Get Bank Account Balance By ID", + s"""Get a specific Bank Account Balance by its BALANCE_ID. + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + bankAccountBalanceResponseJsonV510, + List( + $UserNotLoggedIn, + UserHasMissingRoles, + UnknownError + ), + List(apiTagAccount, apiTagBalance), + Some(List(canGetBankAccountBalance)) + ) + + lazy val getBankAccountBalanceById: OBPEndpoint = { + case "accounts" :: AccountId(accountId) :: "balances" :: BalanceId(balanceId) :: Nil JsonGet _ => { + cc => + implicit val ec = EndpointContext(Some(cc)) + for { + (Full(u), callContext) <- SS.user + (balance, callContext) <- code.api.util.newstyle.BankAccountBalanceNewStyle.getBankAccountBalanceById( + balanceId, + callContext + ) + } yield { + (JSONFactory510.createBankAccountBalanceJson(balance), HttpCode.`200`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( + getAllBankAccountBalances, + implementedInApiVersion, + nameOf(getAllBankAccountBalances), + "GET", + "/accounts/ACCOUNT_ID/balances", + "Get All Bank Account Balances", + s"""Get all Balances for a Bank Account. + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + bankAccountBalancesJsonV510, + List( + $UserNotLoggedIn, + UserHasMissingRoles, + UnknownError + ), + List(apiTagAccount, apiTagBalance), + Some(List(canGetBankAccountBalances)) + ) + + lazy val getAllBankAccountBalances: OBPEndpoint = { + case "accounts" :: AccountId(accountId) :: "balances" :: Nil JsonGet _ => { + cc => + implicit val ec = EndpointContext(Some(cc)) + for { + (Full(u), callContext) <- SS.user + (balances, callContext) <- code.api.util.newstyle.BankAccountBalanceNewStyle.getBankAccountBalances( + accountId, + callContext + ) + } yield { + (JSONFactory510.createBankAccountBalancesJson(balances), HttpCode.`200`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( + updateBankAccountBalance, + implementedInApiVersion, + nameOf(updateBankAccountBalance), + "PUT", + "/accounts/ACCOUNT_ID/balances/BALANCE_ID", + "Update Bank Account Balance", + s"""Update an existing Bank Account Balance specified by BALANCE_ID. + | + |${userAuthenticationMessage(true)} + | + |""", + bankAccountBalanceRequestJsonV510, + bankAccountBalanceResponseJsonV510, + List( + $UserNotLoggedIn, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), + List(apiTagAccount, apiTagBalance), + Some(List(canUpdateBankAccountBalance)) + ) + + lazy val updateBankAccountBalance: OBPEndpoint = { + case "accounts" :: AccountId(accountId) :: "balances" :: BalanceId(balanceId) :: Nil JsonPut json -> _ => { + cc => + implicit val ec = EndpointContext(Some(cc)) + for { + (Full(u), callContext) <- SS.user + postedData <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the BankAccountBalanceRequestJsonV510 ", 400, callContext) { + json.extract[BankAccountBalanceRequestJsonV510] + } + balanceAmount <- NewStyle.function.tryons(s"$InvalidNumber Current balance_amount is ${postedData.balance_amount}" , 400, cc.callContext) { + BigDecimal(postedData.balance_amount) + } + (balance, callContext) <- code.api.util.newstyle.BankAccountBalanceNewStyle.createOrUpdateBankAccountBalance( + balanceId = Some(balanceId), + accountId = accountId, + balanceType = postedData.balance_type, + balanceAmount = balanceAmount, + callContext = callContext + ) + } yield { + (JSONFactory510.createBankAccountBalanceJson(balance), HttpCode.`200`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( + deleteBankAccountBalance, + implementedInApiVersion, + nameOf(deleteBankAccountBalance), + "DELETE", + "/accounts/ACCOUNT_ID/balances/BALANCE_ID", + "Delete Bank Account Balance", + s"""Delete a Bank Account Balance specified by BALANCE_ID. + | + |${userAuthenticationMessage(true)} + | + |""", + EmptyBody, + EmptyBody, + List( + $UserNotLoggedIn, + UserHasMissingRoles, + UnknownError + ), + List(apiTagAccount, apiTagBalance), + Some(List(canDeleteBankAccountBalance)) + ) + + lazy val deleteBankAccountBalance: OBPEndpoint = { + case "accounts" :: AccountId(accountId) :: "balances" :: BalanceId(balanceId) :: Nil JsonDelete _ => { + cc => + implicit val ec = EndpointContext(Some(cc)) + for { + (Full(u), callContext) <- SS.user + (deleted, callContext) <- code.api.util.newstyle.BankAccountBalanceNewStyle.deleteBankAccountBalance( + balanceId, + callContext + ) + } yield { + (Full(deleted), HttpCode.`204`(callContext)) + } + } + } + staticResourceDocs += ResourceDoc( createRegulatedEntity, 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 427cec8ab..e0391c916 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 @@ -611,6 +611,23 @@ case class SyncExternalUserJson(user_id: String) case class UserValidatedJson(is_validated: Boolean) + +case class BankAccountBalanceRequestJsonV510( + balance_type: String, + balance_amount: String +) + +case class BankAccountBalanceResponseJsonV510( + account_id: String, + balance_id: String, + balance_type: String, + balance_amount: String +) + +case class BankAccountBalancesJsonV510( + balances: List[BankAccountBalanceResponseJsonV510] +) + object JSONFactory510 extends CustomJsonFormats { def createTransactionRequestJson(tr : TransactionRequest, transactionRequestAttributes: List[TransactionRequestAttributeTrait] ) : TransactionRequestJsonV510 = { @@ -651,7 +668,7 @@ object JSONFactory510 extends CustomJsonFormats { createTransactionRequestJson(transactionRequest, transactionRequestAttributes) )) } - + def createViewJson(view: View): CustomViewJsonV510 = { val alias = if (view.usePublicAliasIfOneExists) @@ -1073,7 +1090,7 @@ object JSONFactory510 extends CustomJsonFormats { logo_url = if (c.logoUrl.get == null || c.logoUrl.get.isEmpty ) null else Some(c.logoUrl.get) ) } - + def createConsumersJson(consumers:List[Consumer]) = { ConsumersJsonV510(consumers.map(createConsumerJSON(_,None))) } @@ -1100,7 +1117,7 @@ object JSONFactory510 extends CustomJsonFormats { agent_number = agent.number ))) } - + def createRegulatedEntityAttributeJson(attribute: RegulatedEntityAttributeTrait): RegulatedEntityAttributeResponseJsonV510 = { RegulatedEntityAttributeResponseJsonV510( regulated_entity_id = attribute.regulatedEntityId.value, @@ -1119,7 +1136,20 @@ object JSONFactory510 extends CustomJsonFormats { attributes.map(createRegulatedEntityAttributeJson) ) } - + + def createBankAccountBalanceJson(balance: BankAccountBalanceTrait): BankAccountBalanceResponseJsonV510 = { + BankAccountBalanceResponseJsonV510( + balance_id = balance.balanceId.value, + account_id = balance.accountId.value, + balance_type = balance.balanceType, + balance_amount = balance.balanceAmount.toString + ) + } + + def createBankAccountBalancesJson(balances: List[BankAccountBalanceTrait]): BankAccountBalancesJsonV510 = { + BankAccountBalancesJsonV510( + balances.map(createBankAccountBalanceJson) + ) + } } - diff --git a/obp-api/src/main/scala/code/bankaccountbalance/BankAccountBalance.scala b/obp-api/src/main/scala/code/bankaccountbalance/BankAccountBalance.scala new file mode 100644 index 000000000..343dbeb22 --- /dev/null +++ b/obp-api/src/main/scala/code/bankaccountbalance/BankAccountBalance.scala @@ -0,0 +1,33 @@ +package code.bankaccountbalance + +import code.model.dataAccess.MappedBankAccount +import code.util.{Helper, MappedUUID} + +import com.openbankproject.commons.model.{AccountId, BalanceId, BankAccountBalanceTrait} +import net.liftweb.common.{Box, Empty, Full, Logger} +import net.liftweb.mapper._ + + +class BankAccountBalance extends BankAccountBalanceTrait with LongKeyedMapper[BankAccountBalance] with CreatedUpdated with IdPK { + + override def getSingleton = BankAccountBalance + + object BalanceId_ extends MappedUUID(this) +// object AccountId_ extends MappedLongForeignKey(this, MappedBankAccount) + object AccountId_ extends MappedUUID(this) + object BalanceType extends MappedString(this, 255) + //this is the smallest unit of currency! eg. cents, yen, pence, øre, etc. + object BalanceAmount extends MappedLong(this) + + val foreignMappedBankAccount: Box[MappedBankAccount] = code.model.dataAccess.MappedBankAccount.find( + By(MappedBankAccount.theAccountId, AccountId_.get) + ) + val foreignMappedBankAccountCurrency = foreignMappedBankAccount.map(_.currency).getOrElse("EUR") + + override def balanceId: BalanceId = BalanceId(BalanceId_.get) + override def accountId: AccountId = AccountId(AccountId_.get) + override def balanceType: String = BalanceType.get + override def balanceAmount: BigDecimal = Helper.smallestCurrencyUnitToBigDecimal(BalanceAmount.get, foreignMappedBankAccountCurrency) +} + +object BankAccountBalance extends BankAccountBalance with LongKeyedMetaMapper[BankAccountBalance] {} diff --git a/obp-api/src/main/scala/code/bankaccountbalance/BankAccountBalanceProvider.scala b/obp-api/src/main/scala/code/bankaccountbalance/BankAccountBalanceProvider.scala new file mode 100644 index 000000000..97bc181ec --- /dev/null +++ b/obp-api/src/main/scala/code/bankaccountbalance/BankAccountBalanceProvider.scala @@ -0,0 +1,112 @@ +package code.bankaccountbalance + +import code.model.dataAccess.MappedBankAccount +import code.util.{Helper, MappedUUID} +import com.openbankproject.commons.ExecutionContext.Implicits.global +import com.openbankproject.commons.model.{AccountId, BankAccountBalanceTrait} +import net.liftweb.common.{Box, Empty, Full} +import net.liftweb.mapper._ +import net.liftweb.util.Helpers.tryo +import net.liftweb.util.SimpleInjector +import com.openbankproject.commons.model.BalanceId + +import scala.concurrent.Future + +object BankAccountBalanceX extends SimpleInjector { + + val bankAccountBalanceProvider = new Inject(buildOne _) {} + + def buildOne: BankAccountBalanceProviderTrait = MappedBankAccountBalanceProvider + + // Helper to get the count out of an option + def countOfBankAccountBalance(listOpt: Option[List[BankAccountBalance]]): Int = { + val count = listOpt match { + case Some(list) => list.size + case None => 0 + } + count + } +} + +trait BankAccountBalanceProviderTrait { + + def getBankAccountBalances(accountId: AccountId): Future[Box[List[BankAccountBalance]]] + + def getBankAccountBalanceById(balanceId: BalanceId): Future[Box[BankAccountBalance]] + + def createOrUpdateBankAccountBalance( + balanceId: Option[BalanceId], + accountId: AccountId, + balanceType: String, + balanceAmount: BigDecimal): Future[Box[BankAccountBalance]] + + def deleteBankAccountBalance(balanceId: BalanceId): Future[Box[Boolean]] + +} + +object MappedBankAccountBalanceProvider extends BankAccountBalanceProviderTrait { + + override def getBankAccountBalances(accountId: AccountId): Future[Box[List[BankAccountBalance]]] = Future { + tryo{ + BankAccountBalance.findAll( + By(BankAccountBalance.AccountId_,accountId.value) + )} + } + + override def getBankAccountBalanceById(balanceId: BalanceId): Future[Box[BankAccountBalance]] = Future { + // Find a balance by its ID + BankAccountBalance.find( + By(BankAccountBalance.BalanceId_, balanceId.value) + ) + } + + override def createOrUpdateBankAccountBalance( + balanceId: Option[BalanceId], + accountId: AccountId, + balanceType: String, + balanceAmount: BigDecimal + ): Future[Box[BankAccountBalance]] = Future { + // Get the MappedBankAccount for the given account ID + val mappedBankAccount = code.model.dataAccess.MappedBankAccount + .find( + By(MappedBankAccount.theAccountId, accountId.value) + ) + + mappedBankAccount match { + case Full(account) => + balanceId match { + case Some(id) => + BankAccountBalance.find( + By(BankAccountBalance.BalanceId_, id.value) + ) match { + case Full(balance) => + tryo { + balance + .AccountId_(accountId.value) + .BalanceType(balanceType) + .BalanceAmount(Helper.convertToSmallestCurrencyUnits(balanceAmount, account.currency)) + .saveMe() + } + case _ => Empty + } + case _ => + tryo { + BankAccountBalance.create + .AccountId_(accountId.value) + .BalanceType(balanceType) + .BalanceAmount(Helper.convertToSmallestCurrencyUnits(balanceAmount, account.currency)) + .saveMe() + } + } + case _ => Empty + } + } + + override def deleteBankAccountBalance(balanceId: BalanceId): Future[Box[Boolean]] = Future { + // Delete a balance by its ID + BankAccountBalance.find( + By(BankAccountBalance.BalanceId_, balanceId.value) + ).map(_.delete_!) + } + +} diff --git a/obp-api/src/main/scala/code/model/dataAccess/BankAccountBalance.scala b/obp-api/src/main/scala/code/model/dataAccess/BankAccountBalance.scala deleted file mode 100644 index 6ca859991..000000000 --- a/obp-api/src/main/scala/code/model/dataAccess/BankAccountBalance.scala +++ /dev/null @@ -1,29 +0,0 @@ -package code.model.dataAccess - -import com.openbankproject.commons.model._ -import net.liftweb.common.Box -import net.liftweb.mapper._ -import code.util.Helper - -class BankAccountBalance extends BankAccountBalanceTrait with LongKeyedMapper[BankAccountBalance] with CreatedUpdated with IdPK{ - - override def getSingleton = BankAccountBalance - - object AccountId_ extends MappedLongForeignKey(this, MappedBankAccount) - object BalanceType extends MappedString(this, 255) - //this is the smallest unit of currency! eg. cents, yen, pence, øre, etc. - object BalanceAmount extends MappedLong(this) - - val foreignMappedBankAccount: Box[MappedBankAccount] = AccountId_.foreign - val foreignMappedBankAccountCurrency = foreignMappedBankAccount.map(_.currency).getOrElse("EUR") - - override def accountId : AccountId = { - foreignMappedBankAccount.map(_.accountId).getOrElse(AccountId("")) - } - override def balanceType: String = BalanceType.get - override def balanceAmount: BigDecimal = Helper.smallestCurrencyUnitToBigDecimal(BalanceAmount.get, foreignMappedBankAccountCurrency) - - -} - -object BankAccountBalance extends BankAccountBalance with LongKeyedMetaMapper[BankAccountBalance] {} diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/model/BankingModel.scala b/obp-commons/src/main/scala/com/openbankproject/commons/model/BankingModel.scala index f38552376..c916b45b7 100644 --- a/obp-commons/src/main/scala/com/openbankproject/commons/model/BankingModel.scala +++ b/obp-commons/src/main/scala/com/openbankproject/commons/model/BankingModel.scala @@ -136,6 +136,14 @@ object RegulatedEntityId { def unapply(id : String) = Some(RegulatedEntityId(id)) } +case class BalanceId(val value : String) { + override def toString = value +} + +object BalanceId { + def unapply(id : String) = Some(BalanceId(id)) +} + case class AccountId(val value : String) { override def toString = value } @@ -229,7 +237,8 @@ trait BankAccount{ } trait BankAccountBalanceTrait { - def accountId : AccountId + def balanceId: BalanceId + def accountId: AccountId def balanceType: String def balanceAmount: BigDecimal }