From f830e733f4274d571e4b92371ea548deae1b435c Mon Sep 17 00:00:00 2001 From: sorinmanole Date: Tue, 13 Sep 2016 16:57:32 +0200 Subject: [PATCH] issue130 - endpoint for create/get branch --- .../scala/code/api/v2_1_0/APIMethods210.scala | 148 ++++++++++++--- .../code/api/v2_1_0/JSONFactory2.1.0.scala | 176 +++++++++++++++--- .../scala/code/api/v2_1_0/OBPAPI2_1_0.scala | 2 + .../scala/code/bankconnectors/Connector.scala | 6 + .../bankconnectors/KafkaMappedConnector.scala | 7 +- .../code/bankconnectors/LocalConnector.scala | 6 + .../bankconnectors/LocalMappedConnector.scala | 46 +++++ src/main/scala/code/branches/Branches.scala | 7 +- .../code/api/v1_3_0/PhysicalCardsTest.scala | 4 + 9 files changed, 355 insertions(+), 47 deletions(-) diff --git a/src/main/scala/code/api/v2_1_0/APIMethods210.scala b/src/main/scala/code/api/v2_1_0/APIMethods210.scala index b64e0ba89..74ae6c55e 100644 --- a/src/main/scala/code/api/v2_1_0/APIMethods210.scala +++ b/src/main/scala/code/api/v2_1_0/APIMethods210.scala @@ -9,10 +9,12 @@ import code.api.v2_0_0.JSONFactory200._ import code.api.v2_0_0.{JSONFactory200, TransactionRequestBodyJSON} import code.api.v2_1_0.JSONFactory210._ import code.bankconnectors.Connector +import code.branches.Branches.BranchId import code.fx.fx import code.model._ import net.liftweb.http.Req +import net.liftweb.json import net.liftweb.json.Extraction import net.liftweb.json.JsonAST.JValue import net.liftweb.util.Props @@ -25,7 +27,7 @@ import net.liftweb.json.JsonDSL._ import code.api.APIFailure import code.api.util.APIUtil._ -import code.sandbox.{OBPDataImport, SandboxDataImport} +import code.sandbox.{SandboxBranchImport, OBPDataImport, SandboxDataImport} import code.util.Helper import net.liftweb.common.{Empty, Full, Box} import net.liftweb.http.JsonResponse @@ -65,7 +67,7 @@ trait APIMethods210 { "POST", "/sandbox/data-import", "Import data into the sandbox.", - s"""Import bulk data into the sandbox (Authenticated access). + """Import bulk data into the sandbox (Authenticated access). |The user needs to have CanCreateSandbox entitlement. | |An example of an import set of data (json) can be found [here](https://raw.githubusercontent.com/OpenBankProject/OBP-API/develop/src/main/scala/code/api/sandbox/example_data/2016-04-28/example_import.json) @@ -89,7 +91,8 @@ trait APIMethods210 { allowDataImportProp <- Props.get("allow_sandbox_data_import") ~> APIFailure("Data import is disabled for this API instance.", 403) allowDataImport <- Helper.booleanToBox(allowDataImportProp == "true") ~> APIFailure("Data import is disabled for this API instance.", 403) canCreateSandbox <- booleanToBox(hasEntitlement("", u.userId, CanCreateSandbox), s"$CanCreateSandbox entitlement required") - importData <- tryo {json.extract[SandboxDataImport]} ?~ "invalid json" + importData <- tryo {json.extract[ + SandboxDataImport]} ?~ "invalid json" importWorked <- OBPDataImport.importer.vend.importData(importData) } yield { successJsonResponse(JsRaw("{}"), 201) @@ -107,7 +110,7 @@ trait APIMethods210 { "GET", "/banks/BANK_ID/transaction-request-types", "Get the Transaction Request Types supported by the bank", - s"""Get the list of the Transaction Request Types supported by the bank. + """Get the list of the Transaction Request Types supported by the bank. | |${authenticationRequiredMessage(!getTransactionRequestTypesIsPublic)} |""", @@ -144,7 +147,9 @@ trait APIMethods210 { import net.liftweb.json.JsonAST._ import net.liftweb.json.Extraction._ - import net.liftweb.json.Printer._ + import net + + .liftweb.json.Printer._ val exchangeRates = pretty(render(decompose(fx.exchangeRates))) resourceDocs += ResourceDoc( @@ -215,9 +220,12 @@ trait APIMethods210 { u <- user ?~ ErrorMessages.UserNotLoggedIn // Get Transaction Request Types from Props "transactionRequests_supported_types". Default is empty string - validTransactionRequestTypes <- tryo{Props.get("transactionRequests_supported_types", "")} + validTransactionRequestTypes <- tryo{Props.get( + "transactionRequests_supported_types", "")} // Use a list instead of a string to avoid partial matches - validTransactionRequestTypesList <- tryo{validTransactionRequestTypes.split(",")} + validTransactionRequestTypesList <- + tryo{validTransactionRequestTypes.split( + ",")} isValidTransactionRequestType <- tryo(assert(transactionRequestType.value != "TRANSACTION_REQUEST_TYPE" && validTransactionRequestTypesList.contains(transactionRequestType.value))) ?~! s"${ErrorMessages.InvalidTransactionRequestType} : Invalid value is: '${transactionRequestType.value}' Valid values are: ${validTransactionRequestTypes}" transDetailsJson <- transactionRequestType.value match { @@ -239,24 +247,35 @@ trait APIMethods210 { } transDetails <- transactionRequestType.value match { - case "SANDBOX_TAN" => tryo{getTransactionRequestDetailsSandBoxTanFromJson(transDetailsJson.asInstanceOf[TransactionRequestDetailsSandBoxTanJSON])} - case "SEPA" => tryo{getTransactionRequestDetailsSEPAFromJson(transDetailsJson.asInstanceOf[TransactionRequestDetailsSEPAJSON])} - case "FREE_FORM" => tryo{getTransactionRequestDetailsFreeFormFromJson(transDetailsJson.asInstanceOf[TransactionRequestDetailsFreeFormJSON])} + case "SANDBOX_TAN" => tryo {getTransactionRequestDetailsSandBoxTanFromJson(transDetailsJson.asInstanceOf[TransactionRequestDetailsSandBoxTanJSON] + )} + case "SEPA" => tryo{ + getTransactionRequestDetailsSEPAFromJson(transDetailsJson.asInstanceOf[TransactionRequestDetailsSEPAJSON]) + } + case "FREE_FORM" => tryo { + getTransactionRequestDetailsFreeFormFromJson(transDetailsJson.asInstanceOf[TransactionRequestDetailsFreeFormJSON]) + } } - fromBank <- Bank(bankId) ?~! {ErrorMessages.BankNotFound} - fromAccount <- BankAccount(bankId, accountId) ?~! {ErrorMessages.AccountNotFound} - isOwnerOrHasEntitlement <- booleanToBox(u.ownerAccess(fromAccount) == true || hasEntitlement(fromAccount.bankId.value, u.userId, CanCreateAnyTransactionRequest) == true , ErrorMessages.InsufficientAuthorisationToCreateTransactionRequest) + fromBank <- Bank(bankId) ?~! { + ErrorMessages.BankNotFound + } + fromAccount <- BankAccount(bankId, accountId) ?~! { + ErrorMessages.AccountNotFound + } + isOwnerOrHasEntitlement <- booleanToBox(u.ownerAccess(fromAccount) == true || hasEntitlement(fromAccount.bankId.value, u.userId, CanCreateAnyTransactionRequest) == true, ErrorMessages.InsufficientAuthorisationToCreateTransactionRequest) // Prevent default value for transaction request type (at least). - transferCurrencyEqual <- tryo(assert(transDetailsJson.value.currency == fromAccount.currency)) ?~! {"Transfer body currency and holder account currency must be the same."} + transferCurrencyEqual <- tryo(assert(transDetailsJson.value.currency == fromAccount.currency)) ?~! { + "Transfer body currency and holder account currency must be the same." + } - transDetailsSerialized<- transactionRequestType.value match { - case "FREE_FORM" => tryo{ + transDetailsSerialized <- transactionRequestType.value match { + case "FREE_FORM" => tryo { implicit val formats = Serialization.formats(NoTypeHints) write(json) } - case _ => tryo{ + case _ => tryo { implicit val formats = Serialization.formats(NoTypeHints) write(transDetailsJson) } @@ -267,7 +286,9 @@ trait APIMethods210 { for { toBankId <- Full(BankId(transDetailsJson.asInstanceOf[TransactionRequestDetailsSandBoxTanJSON].to.bank_id)) toAccountId <- Full(AccountId(transDetailsJson.asInstanceOf[TransactionRequestDetailsSandBoxTanJSON].to.account_id)) - toAccount <- BankAccount(toBankId, toAccountId) ?~! {ErrorMessages.CounterpartyNotFound} + toAccount <- BankAccount(toBankId, toAccountId) ?~! { + ErrorMessages.CounterpartyNotFound + } createdTransactionRequest <- Connector.connector.vend.createTransactionRequestv210(u, fromAccount, Full(toAccount), transactionRequestType, transDetails, transDetailsSerialized) } yield createdTransactionRequest @@ -298,7 +319,7 @@ trait APIMethods210 { "getTransactionRequests", "GET", "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transaction-requests", - "Get Transaction Requests." , + "Get Transaction Requests.", """Returns transaction requests for account specified by ACCOUNT_ID at bank specified by BANK_ID. | |The VIEW_ID specified must be 'owner' and the user must have access to this view. @@ -335,9 +356,15 @@ trait APIMethods210 { if (Props.getBool("transactionRequests_enabled", false)) { for { u <- user ?~ ErrorMessages.UserNotLoggedIn - fromBank <- Bank(bankId) ?~! {ErrorMessages.BankNotFound} - fromAccount <- BankAccount(bankId, accountId) ?~! {ErrorMessages.AccountNotFound} - view <- tryo(fromAccount.permittedViews(user).find(_ == viewId)) ?~ {"Current user does not have access to the view " + viewId} + fromBank <- Bank(bankId) ?~! { + ErrorMessages.BankNotFound + } + fromAccount <- BankAccount(bankId, accountId) ?~! { + ErrorMessages.AccountNotFound + } + view <- tryo(fromAccount.permittedViews(user).find(_ == viewId)) ?~ { + "Current user does not have access to the view " + viewId + } transactionRequests <- Connector.connector.vend.getTransactionRequests210(u, fromAccount) } yield { @@ -350,6 +377,83 @@ trait APIMethods210 { } } } + + + resourceDocs += ResourceDoc( + createBranch, + apiVersion, + "createBranch", + "POST", + "/banks/BANK_ID/branches", + "Create Branch", + s"""Create branch for the bank (Authenticated access). + |${authenticationRequiredMessage(true)} + |""", + emptyObjectJson, + emptyObjectJson, + emptyObjectJson :: Nil, + false, + false, + false, + List(apiTagAccount, apiTagPrivateData, apiTagPublicData)) + + + lazy val createBranch: PartialFunction[Req, Box[User] => Box[JsonResponse]] = { + // Import data into the sandbox + case "banks" :: BankId(bankId) :: "branches" :: Nil JsonPost json -> _ => { + user => + for { + u <- user ?~ ErrorMessages.UserNotLoggedIn + bank <- Bank(bankId) ?~! { + ErrorMessages.BankNotFound + } + branch <- tryo { + json.extract[SandboxBranchImport] + } ?~ "invalid json" + success <- Connector.connector.vend.createBranch(branch) + } yield { + successJsonResponse(JsRaw("{}"), 201) + } + } + } + + + resourceDocs += ResourceDoc( + getBranch, + apiVersion, + "getBranch", + "GET", + "/banks/BANK_ID/branches/BRANCH_ID", + "Get Branch", + s"""Get branch by ID (Authenticated access). + |${authenticationRequiredMessage(true)} + |""", + emptyObjectJson, + emptyObjectJson, + emptyObjectJson :: Nil, + false, + false, + false, + List(apiTagAccount, apiTagPrivateData, apiTagPublicData)) + + + lazy val getBranch: PartialFunction[Req, Box[User] => Box[JsonResponse]] = { + // Import data into the sandbox + case "banks" :: BankId(bankId) :: "branches" :: BranchId(branchId) :: Nil JsonGet _ => { + user => + for { + u <- user ?~ ErrorMessages.UserNotLoggedIn + bank <- Bank(bankId) ?~! { + ErrorMessages.BankNotFound + } + branch <- Connector.connector.vend.getBranch(branchId) + } yield { + val json = JSONFactory210.createBranchJSON(branch) + successJsonResponse(Extraction.decompose(json)) + } + } + } + } } diff --git a/src/main/scala/code/api/v2_1_0/JSONFactory2.1.0.scala b/src/main/scala/code/api/v2_1_0/JSONFactory2.1.0.scala index e854a30dd..e02f2746f 100644 --- a/src/main/scala/code/api/v2_1_0/JSONFactory2.1.0.scala +++ b/src/main/scala/code/api/v2_1_0/JSONFactory2.1.0.scala @@ -1,32 +1,32 @@ /** -Open Bank Project - API -Copyright (C) 2011-2015, TESOBE Ltd + * Open Bank Project - API + * Copyright (C) 2011-2015, TESOBE Ltd -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . -Email: contact@tesobe.com -TESOBE / Music Pictures Ltd -Osloerstrasse 16/17 -Berlin 13359, Germany + * Email: contact@tesobe.com + * TESOBE / Music Pictures Ltd + * Osloerstrasse 16/17 + * Berlin 13359, Germany - This product includes software developed at - TESOBE (http://www.tesobe.com/) - by - Simon Redfern : simon AT tesobe DOT com - Stefan Bethge : stefan AT tesobe DOT com - Everett Sochowski : everett AT tesobe DOT com - Ayoub Benali: ayoub AT tesobe DOT com + * This product includes software developed at + * TESOBE (http://www.tesobe.com/) + * by + * Simon Redfern : simon AT tesobe DOT com + * Stefan Bethge : stefan AT tesobe DOT com + * Everett Sochowski : everett AT tesobe DOT com + * Ayoub Benali: ayoub AT tesobe DOT com */ package code.api.v2_1_0 @@ -36,8 +36,13 @@ import java.util.Date import code.api.v1_2_1.AmountOfMoneyJSON import code.api.v1_4_0.JSONFactory1_4_0.{ChallengeJSON, TransactionRequestAccountJSON} import code.api.v2_0_0.{TransactionRequestWithChargeJSONs, TransactionRequestChargeJSON, TransactionRequestBodyJSON} +import code.branches.Branches.{BranchId, DriveUp, Lobby, Branch} import code.model.AmountOfMoney import code.transactionrequests.TransactionRequests._ +import code.common.{Meta, License, Location, Address} + +case class AddressImpl(line1 : String, line2 : String, line3 : String, city : String, county : String, + state : String, postCode : String, countryCode : String) extends Address case class TransactionRequestTypeJSON(transaction_request_type: String) case class TransactionRequestTypesJSON(transaction_request_types: List[TransactionRequestTypeJSON]) @@ -79,6 +84,53 @@ case class TransactionRequestWithChargeJSONs210( transaction_requests_with_charges : List[TransactionRequestWithChargeJSON210] ) +case class BranchJSON (branchId : String, + name : String, + address : AddressJSON, + location : LocationJSON, + lobby : LobbyJSON, + driveUp : DriveUpJSON, + meta : MetaJSON + ) + +case class LobbyJSON ( + hours : String +) + +case class DriveUpJSON ( + hours : String +) + +case class MetaJSON ( + license : LicenseJSON +) + +case class LicenseJSON ( + id : String, + name : String +) + +case class AddressJSON ( + line1 : String, + line2 : String, + line3 : String, + city : String, + county : String, + state : String, + postCode : String, + countryCode : String +) + +case class LocationJSON ( + latitude: Double, + longitude: Double +) + + + + + + object JSONFactory210{ def createTransactionRequestTypeJSON(transactionRequestType : String ) : TransactionRequestTypeJSON = { new TransactionRequestTypeJSON( @@ -131,6 +183,84 @@ object JSONFactory210{ ) } + def getBranchFromJson(branchJSON: BranchJSON) : Branch = { + val address = new Address { + override def line1 = branchJSON.address.line1 + override def line2 = branchJSON.address.line2 + override def line3 = branchJSON.address.line3 + override def city = branchJSON.address.city + override def county = branchJSON.address.county + override def state = branchJSON.address.state + override def postCode = branchJSON.address.postCode + override def countryCode = branchJSON.address.countryCode + } + + val location = new Location { + override def latitude = branchJSON.location.latitude + override def longitude = branchJSON.location.longitude + } + + val lobby = new Lobby { + override def hours = branchJSON.lobby.hours + } + + val driveUp = new DriveUp { + override def hours = branchJSON.driveUp.hours + } + + val license = new License { + override def id = branchJSON.meta.license.id + override def name = branchJSON.meta.license.name + } + + val meta = new Meta { + override def license = license + } + + new Branch { + override def branchId = BranchId(branchJSON.branchId) + override def name = branchJSON.name + override def address = address + override def location = location + override def lobby = lobby + override def driveUp = driveUp + override def meta = meta + } + } + + def createBranchJSON(branch : Branch) : BranchJSON = { + new BranchJSON( + branchId = branch.branchId.value, + name = branch.name, + address = AddressJSON( + line1 = branch.address.line1, + line2 = branch.address.line2, + line3 = branch.address.line3, + city = branch.address.city, + county = branch.address.county, + state = branch.address.state, + postCode = branch.address.postCode, + countryCode = branch.address.countryCode + ), + location = LocationJSON( + latitude = branch.location.latitude, + longitude = branch.location.longitude + ), + lobby = LobbyJSON( + hours = branch.lobby.hours + ), + driveUp = DriveUpJSON( + hours = branch.driveUp.hours + ), + meta = MetaJSON( + license = LicenseJSON( + id = branch.meta.license.id, + name = branch.meta.license.name + ) + ) + ) + } + /** Creates v2.1.0 representation of a TransactionType * * @param tr An internal TransactionRequest instance diff --git a/src/main/scala/code/api/v2_1_0/OBPAPI2_1_0.scala b/src/main/scala/code/api/v2_1_0/OBPAPI2_1_0.scala index 876a5c852..ac1be8890 100644 --- a/src/main/scala/code/api/v2_1_0/OBPAPI2_1_0.scala +++ b/src/main/scala/code/api/v2_1_0/OBPAPI2_1_0.scala @@ -225,6 +225,8 @@ object OBPAPI2_1_0 extends OBPRestHelper with APIMethods130 with APIMethods140 w if (!disabledEndpoints.contains("getTransactionRequestTypesSupportedByBank")) routes = routes:::List(Implementations2_1_0.getTransactionRequestTypesSupportedByBank) if (!disabledEndpoints.contains("createTransactionRequest")) routes = routes:::List(Implementations2_1_0.createTransactionRequest) if (!disabledEndpoints.contains("getTransactionRequests")) routes = routes:::List(Implementations2_1_0.getTransactionRequests) + if (!disabledEndpoints.contains("createBranch")) routes = routes:::List(Implementations2_1_0.createBranch) + if (!disabledEndpoints.contains("getBranch")) routes = routes:::List(Implementations2_1_0.getBranch) } // ### VERSION 2.1.0 - END ### diff --git a/src/main/scala/code/bankconnectors/Connector.scala b/src/main/scala/code/bankconnectors/Connector.scala index 4e3bfbe54..5f56a194c 100644 --- a/src/main/scala/code/bankconnectors/Connector.scala +++ b/src/main/scala/code/bankconnectors/Connector.scala @@ -5,9 +5,11 @@ import java.util.Date import code.api.util.APIUtil._ import code.api.util.ApiRole._ import code.api.util.ErrorMessages +import code.branches.Branches.{Branch, BranchId} import code.fx.fx import code.management.ImporterAPI.ImporterTransaction import code.model.{OtherBankAccount, Transaction, User, _} +import code.sandbox.SandboxBranchImport import code.transactionrequests.TransactionRequests import code.transactionrequests.TransactionRequests._ import code.util.Helper._ @@ -590,4 +592,8 @@ trait Connector { def updateAccountLabel(bankId: BankId, accountId: AccountId, label: String): Boolean + def createBranch(branch: SandboxBranchImport): Box[Boolean] + + def getBranch(branchId: BranchId): Box[Branch] + } \ No newline at end of file diff --git a/src/main/scala/code/bankconnectors/KafkaMappedConnector.scala b/src/main/scala/code/bankconnectors/KafkaMappedConnector.scala index 2821861af..2cef479a3 100644 --- a/src/main/scala/code/bankconnectors/KafkaMappedConnector.scala +++ b/src/main/scala/code/bankconnectors/KafkaMappedConnector.scala @@ -4,6 +4,7 @@ import java.text.SimpleDateFormat import java.util.{Date, Locale, UUID} import code.api.util.ErrorMessages +import code.branches.Branches.{Branch, BranchId} import code.management.ImporterAPI.ImporterTransaction import code.metadata.comments.MappedComment import code.metadata.counterparties.Counterparties @@ -13,7 +14,7 @@ import code.metadata.transactionimages.MappedTransactionImage import code.metadata.wheretags.MappedWhereTag import code.model._ import code.model.dataAccess._ -import code.sandbox.{CreateViewImpls, Saveable} +import code.sandbox.{SandboxBranchImport, CreateViewImpls, Saveable} import code.transaction.MappedTransaction import code.transactionrequests.{MappedTransactionRequest210, MappedTransactionRequest} import code.transactionrequests.TransactionRequests._ @@ -917,6 +918,10 @@ object KafkaMappedConnector extends Connector with CreateViewImpls with Loggable } } + override def createBranch(branch: SandboxBranchImport) : Box[Boolean] = ??? + + override def getBranch(branchId: BranchId): Box[Branch] = ??? + case class KafkaBank(r: KafkaInboundBank) extends Bank { def fullName = r.full_name diff --git a/src/main/scala/code/bankconnectors/LocalConnector.scala b/src/main/scala/code/bankconnectors/LocalConnector.scala index df4663ef2..778a83a29 100644 --- a/src/main/scala/code/bankconnectors/LocalConnector.scala +++ b/src/main/scala/code/bankconnectors/LocalConnector.scala @@ -3,10 +3,12 @@ package code.bankconnectors import java.text.SimpleDateFormat import java.util.{Date, TimeZone, UUID} +import code.branches.Branches.{Branch, BranchId} import code.management.ImporterAPI.ImporterTransaction import code.metadata.counterparties.{Counterparties, Metadata, MongoCounterparties} import code.model._ import code.model.dataAccess._ +import code.sandbox.SandboxBranchImport import code.transactionrequests.TransactionRequests._ import code.util.Helper import com.mongodb.QueryBuilder @@ -551,4 +553,8 @@ private object LocalConnector extends Connector with Loggable { false } } + + override def createBranch(branch: SandboxBranchImport) : Box[Boolean] = ??? + + override def getBranch(branchId: BranchId): Box[Branch] = ??? } \ No newline at end of file diff --git a/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/src/main/scala/code/bankconnectors/LocalMappedConnector.scala index 5182d1b54..c9a2a7b5c 100644 --- a/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -2,6 +2,8 @@ package code.bankconnectors import java.util.{Date, UUID} +import code.branches.Branches.{Branch, BranchId} +import code.branches.MappedBranch import code.fx.fx import code.management.ImporterAPI.ImporterTransaction import code.metadata.comments.MappedComment @@ -12,6 +14,8 @@ import code.metadata.transactionimages.MappedTransactionImage import code.metadata.wheretags.MappedWhereTag import code.model._ import code.model.dataAccess._ +import code.sandbox.LocalMappedConnectorDataImport.BranchType +import code.sandbox.{MappedSaveable, Saveable, SandboxBranchImport} import code.tesobe.CashTransaction import code.transaction.MappedTransaction import code.transactionrequests.{MappedTransactionRequest210, MappedTransactionRequest} @@ -613,4 +617,46 @@ object LocalMappedConnector extends Connector with Loggable { result.getOrElse(false) } + override def createBranch(branch: SandboxBranchImport) : Box[Boolean] = { + + val lobbyHours = if (branch.lobby.isDefined) {branch.lobby.get.hours.toString} else "" + val driveUpHours = if (branch.driveUp.isDefined) {branch.driveUp.get.hours.toString} else "" + + val mappedBranch = MappedBranch.create + .mBranchId(branch.id) + .mBankId(branch.bank_id) + .mName(branch.name) + // Note: address fields are returned in meta.address + // but are stored flat as fields / columns in the table + .mLine1(branch.address.line_1) + .mLine2(branch.address.line_2) + .mLine3(branch.address.line_3) + .mCity(branch.address.city) + .mCounty(branch.address.county) + .mState(branch.address.state) + .mPostCode(branch.address.post_code) + .mCountryCode(branch.address.country_code) + .mlocationLatitude(branch.location.latitude) + .mlocationLongitude(branch.location.longitude) + .mLicenseId(branch.meta.license.id) + .mLicenseName(branch.meta.license.name) + .mLobbyHours(lobbyHours) + .mDriveUpHours(driveUpHours) + + val validationErrors = mappedBranch.validate + + if(validationErrors.nonEmpty) { + Full(false) + } else { + Full(true) + } + } + + //gets a particular bank handled by this connector + override def getBranch(branchId: BranchId): Box[Branch] = + getMappedBranch(branchId) + + private def getMappedBranch(branchId: BranchId): Box[MappedBranch] = + MappedBranch.find(By(MappedBranch.mBranchId, branchId.value)) + } diff --git a/src/main/scala/code/branches/Branches.scala b/src/main/scala/code/branches/Branches.scala index e71cedd7a..73a1b4280 100644 --- a/src/main/scala/code/branches/Branches.scala +++ b/src/main/scala/code/branches/Branches.scala @@ -13,8 +13,13 @@ import net.liftweb.common.Logger import net.liftweb.util.SimpleInjector object Branches extends SimpleInjector { + case class BranchId(val value : String) { + override def toString = value + } - case class BranchId(value : String) + object BranchId { + def unapply(id : String) = Some(BranchId(id)) + } trait Branch { def branchId : BranchId diff --git a/src/test/scala/code/api/v1_3_0/PhysicalCardsTest.scala b/src/test/scala/code/api/v1_3_0/PhysicalCardsTest.scala index 6eb3dde97..5ae8c89f8 100644 --- a/src/test/scala/code/api/v1_3_0/PhysicalCardsTest.scala +++ b/src/test/scala/code/api/v1_3_0/PhysicalCardsTest.scala @@ -5,8 +5,10 @@ import java.util.Date import code.api.util.APIUtil.OAuth._ import code.api.{DefaultUsers, ServerSetup} import code.bankconnectors.{Connector, OBPQueryParam} +import code.branches.Branches.{Branch, BranchId} import code.management.ImporterAPI.ImporterTransaction import code.model.{PhysicalCard, Consumer => OBPConsumer, Token => OBPToken, _} +import code.sandbox.SandboxBranchImport import code.transactionrequests.TransactionRequests._ import net.liftweb.common.{Box, Empty, Failure, Loggable} @@ -134,6 +136,8 @@ class PhysicalCardsTest extends ServerSetup with DefaultUsers { override def updateAccountBalance(bankId: BankId, accountId: AccountId, newBalance: BigDecimal): Boolean = ??? override def setBankAccountLastUpdated(bankNationalIdentifier: String, accountNumber : String, updateDate: Date) : Boolean = ??? override def updateAccountLabel(bankId: BankId, accountId: AccountId, label: String): Boolean = ??? + override def createBranch(branch: SandboxBranchImport) : Box[Boolean] = ??? + override def getBranch(branchId: BranchId): Box[Branch] = ??? } override def beforeAll() {