#243 Added Iban in SEPA details reponse and fixed the FROM_FORM data format

This commit is contained in:
hongwei1 2016-11-22 20:11:45 +01:00
parent a664dd3b91
commit a895c10aec
11 changed files with 2825 additions and 38 deletions

View File

@ -89,7 +89,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1206-jdbc4</version>
<version>9.4.1211</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>

View File

@ -93,6 +93,7 @@ object ErrorMessages {
val CustomerNumberAlreadyExists = "OBP-30006: Customer Number already exists. Please specify a different value for BANK_ID or CUSTOMER_NUMBER."
val CustomerAlreadyExistsForUser = "OBP-30007: The User is already linked to a Customer at the bank specified by BANK_ID"
val CustomerDoNotExistsForUser = "OBP-30008: User is not linked to a Customer at the bank specified by BANK_ID"
val CounterpartyNotFoundByIban = "OBP-30009: Counterparty not found. The IBan specified does not exist on this server."
val MeetingsNotSupported = "OBP-30101: Meetings are not supported on this server."
val MeetingApiKeyNotConfigured = "OBP-30102: Meeting provider API Key is not configured."

View File

@ -14,16 +14,19 @@ import code.api.v2_1_0.JSONFactory210._
import code.bankconnectors.Connector
import code.entitlement.Entitlement
import code.fx.fx
import code.metadata.counterparties.MappedCounterpartyMetadata
import code.model.dataAccess.OBPUser
import code.model.{BankId, _}
import net.liftweb.http.{CurrentReq, Req}
import net.liftweb.json.Extraction
import net.liftweb.json.JsonAST.JValue
import net.liftweb.json.Serialization._
import net.liftweb.mapper.By
import net.liftweb.util.Props
import scala.collection.immutable.Nil
import scala.collection.mutable.ArrayBuffer
// Makes JValue assignment to Nil work
import code.util.Helper._
import net.liftweb.json.JsonDSL._
@ -44,7 +47,6 @@ import net.liftweb.json.Serialization.{read, write}
trait APIMethods210 {
//needs to be a RestHelper to get access to JsonGet, JsonPost, etc.
self: RestHelper =>
// helper methods begin here
// helper methods end here
@ -214,8 +216,8 @@ trait APIMethods210 {
|
|""",
Extraction.decompose(TransactionRequestBodyJSON (
TransactionRequestAccountJSON("BANK_ID", "ACCOUNT_ID"),
AmountOfMoneyJSON("EUR", "100.53"),
TransactionRequestAccountJSON("bank_id", "account_id"),
AmountOfMoneyJSON("eur", "100.53"),
"A description for the transaction to be created"
)
),
@ -277,16 +279,7 @@ trait APIMethods210 {
// Prevent default value for transaction request type (at least).
transferCurrencyEqual <- tryo(assert(transDetailsJson.value.currency == fromAccount.currency)) ?~! {s"${ErrorMessages.InvalidTransactionRequestCurrency} From Account Currency is ${fromAccount.currency} Requested Transaction Currency is: ${transDetailsJson.value.currency}"}
transDetailsSerialized <- transactionRequestType.value match {
case "FREE_FORM" => tryo{
implicit val formats = Serialization.formats(NoTypeHints)
write(json)
}
case _ => tryo{
implicit val formats = Serialization.formats(NoTypeHints)
write(transDetailsJson)
}
}
amountOfMoneyJSON <- Full(AmountOfMoneyJSON(transDetails.value.currency, transDetails.value.amount))
// Note: These store in the table TransactionRequestv210
createdTransactionRequest <- transactionRequestType.value match {
@ -295,16 +288,52 @@ trait APIMethods210 {
toBankId <- Full(BankId(transDetailsJson.asInstanceOf[TransactionRequestDetailsSandBoxTanJSON].to.bank_id))
toAccountId <- Full(AccountId(transDetailsJson.asInstanceOf[TransactionRequestDetailsSandBoxTanJSON].to.account_id))
toAccount <- BankAccount(toBankId, toAccountId) ?~! {ErrorMessages.CounterpartyNotFound}
transDetailsSerialized <- tryo {
implicit val formats = Serialization.formats(NoTypeHints)
write(json)
}
createdTransactionRequest <- Connector.connector.vend.createTransactionRequestv210(u, fromAccount, Full(toAccount), transactionRequestType, transDetails, transDetailsSerialized)
} yield createdTransactionRequest
}
case "SEPA" => {
Connector.connector.vend.createTransactionRequestv210(u, fromAccount, Empty, transactionRequestType, transDetails, transDetailsSerialized)
for {
//for SEPA, the user do not send the Bank_ID and Acound_ID,so this will search for the bank firstly.
toIban<- Full(transDetailsJson.asInstanceOf[TransactionRequestDetailsSEPAJSON].iban)
mappedCounterpartyMetadata <- MappedCounterpartyMetadata.find(By(MappedCounterpartyMetadata.accountNumber, toIban)) ?~! {ErrorMessages.CounterpartyNotFoundByIban}
toBankId <- Full(BankId(mappedCounterpartyMetadata.thisAccountBankId))
toAccountId <- Full(AccountId(mappedCounterpartyMetadata.thisAccountId))
toAccount <- BankAccount(toBankId, toAccountId) ?~! {ErrorMessages.CounterpartyNotFound}
// Following four lines: just transfer the details body ,add Bank_Id and Account_Id in the Detail part.
transactionRequestAccountJSON = TransactionRequestAccountJSON(toBankId.value, toAccountId.value)
detailDescription = transDetailsJson.asInstanceOf[TransactionRequestDetailsSEPAJSON].description
transactionRequestDetailsAddedTobankSEPAJSON = TransactionRequestDetailsSEPAResponseJSON(toIban.toString,transactionRequestAccountJSON, amountOfMoneyJSON, detailDescription.toString)
transResponseDetails = getTransactionRequestDetailsAddedTobankSEPAJSONFromJson(transactionRequestDetailsAddedTobankSEPAJSON)
//Serialize the new format SEPA data.
transDetailsResponseSerialized <-tryo{
implicit val formats = Serialization.formats(NoTypeHints)
write(transResponseDetails)
}
createdTransactionRequest <- Connector.connector.vend.createTransactionRequestv210(u, fromAccount, Full(toAccount), transactionRequestType, transResponseDetails, transDetailsResponseSerialized)
} yield createdTransactionRequest
}
case "FREE_FORM" => {
Connector.connector.vend.createTransactionRequestv210(u, fromAccount, Empty, transactionRequestType, transDetails, transDetailsSerialized)
for {
// Following three lines: just transfer the details body ,add Bank_Id and Account_Id in the Detail part.
transactionRequestAccountJSON <- Full(TransactionRequestAccountJSON(fromAccount.bankId.value, fromAccount.accountId.value))
// the Free form the discription is empty, so make it "" in the following code
transactionRequestDetailsFreeFormResponseJSON = TransactionRequestDetailsFreeFormResponseJSON(transactionRequestAccountJSON,amountOfMoneyJSON,"")
transResponseDetails <- Full(getTransactionRequestDetailsFreeFormAddedTobankJson(transactionRequestDetailsFreeFormResponseJSON))
transDetailsResponseSerialized<-tryo{
implicit val formats = Serialization.formats(NoTypeHints)
write(transResponseDetails)
}
createdTransactionRequest <- Connector.connector.vend.createTransactionRequestv210(u, fromAccount, Full(fromAccount), transactionRequestType, transResponseDetails, transDetailsResponseSerialized)
} yield
createdTransactionRequest
}
}
} yield {
@ -609,7 +638,7 @@ trait APIMethods210 {
u <- user ?~! ErrorMessages.UserNotLoggedIn
putData <- tryo{json.extract[PutEnabledJSON]} ?~! ErrorMessages.InvalidJsonFormat
hasEntitlement <- putData.enabled match {
case true => booleanToBox(hasEntitlement("", u.userId, ApiRole.CanEnableConsumers), s"$CanEnableConsumers entitlement required")
case true => booleanToBox(hasEntitlement("", u.userId, ApiRole.CanEnableConsumers), s"$CanEnableConsumers entitlement required")
case false => booleanToBox(hasEntitlement("", u.userId, ApiRole.CanDisableConsumers), s"$CanDisableConsumers entitlement required")
}
consumer <- Consumer.find(By(Consumer.id, consumerId.toLong))
@ -624,7 +653,6 @@ trait APIMethods210 {
}
resourceDocs += ResourceDoc(
addCardsForBank,
apiVersion,
@ -758,7 +786,7 @@ trait APIMethods210 {
| * charge : The charge to the customer for each one of these
|
|${authenticationRequiredMessage(getTransactionTypesIsPublic)}""",
Extraction.decompose(TransactionTypeJSON(TransactionTypeId("wuwjfuha234678"), "1", "2", "3", "4", AmountOfMoneyJSON("EUR", "123"))),
Extraction.decompose(TransactionTypeJSON(TransactionTypeId("wuwjfuha234678"), "1", "2", "3", "4", AmountOfMoneyJSON("eur", "123"))),
emptyObjectJson,
emptyObjectJson :: Nil,
false,
@ -768,7 +796,6 @@ trait APIMethods210 {
)
lazy val createTransactionType: PartialFunction[Req, Box[User] => Box[JsonResponse]] = {
case "banks" :: BankId(bankId) :: "transaction-types" :: Nil JsonPut json -> _ => {
user => {

View File

@ -37,7 +37,7 @@ import code.api.util.ApiRole
import code.api.v1_2_1.AmountOfMoneyJSON
import code.api.v1_4_0.JSONFactory1_4_0.{ChallengeJSON, TransactionRequestAccountJSON}
import code.api.v2_0_0.TransactionRequestChargeJSON
import code.model.{AmountOfMoney, Consumer}
import code.model.{AmountOfMoney, Consumer, CounterpartyMetadataIban, Iban}
import code.transactionrequests.TransactionRequests._
import net.liftweb.json.JValue
@ -58,15 +58,30 @@ case class TransactionRequestDetailsSandBoxTanJSON(
) extends TransactionRequestDetailsJSON
case class TransactionRequestDetailsSEPAJSON(
value : AmountOfMoneyJSON,
IBAN: String,
description : String
) extends TransactionRequestDetailsJSON
value: AmountOfMoneyJSON,
iban: String,
description: String
) extends TransactionRequestDetailsJSON
case class TransactionRequestDetailsSEPAResponseJSON(
iban: String,
to: TransactionRequestAccountJSON,
value: AmountOfMoneyJSON,
description: String
) extends TransactionRequestDetailsJSON
case class TransactionRequestDetailsFreeFormJSON(
value : AmountOfMoneyJSON
) extends TransactionRequestDetailsJSON
case class TransactionRequestDetailsFreeFormResponseJSON(
to: TransactionRequestAccountJSON,
value: AmountOfMoneyJSON,
description: String
) extends TransactionRequestDetailsJSON
case class TransactionRequestWithChargeJSON210(
id: String,
`type`: String,
@ -135,12 +150,35 @@ object JSONFactory210{
}
def getTransactionRequestDetailsSEPAFromJson(details: TransactionRequestDetailsSEPAJSON) : TransactionRequestDetailsSEPA = {
val toAccIban = Iban (
iban = details.iban
)
val amount = AmountOfMoney (
currency = details.value.currency,
amount = details.value.amount
)
TransactionRequestDetailsSEPA (
iban = details.iban,
value = amount,
description = details.description
)
}
def getTransactionRequestDetailsAddedTobankSEPAJSONFromJson(details: TransactionRequestDetailsSEPAResponseJSON) : TransactionRequestDetailsSEPAResponse = {
val toAcc = TransactionRequestAccount (
bank_id = details.to.bank_id,
account_id = details.to.account_id
)
val toAccIban = Iban (
iban = details.iban
)
val amount = AmountOfMoney (
currency = details.value.currency,
amount = details.value.amount
)
TransactionRequestDetailsSEPAResponse (
iban = details.iban,
to=toAcc,
value = amount,
description = details.description
)
@ -157,6 +195,23 @@ object JSONFactory210{
)
}
def getTransactionRequestDetailsFreeFormAddedTobankJson(details: TransactionRequestDetailsFreeFormResponseJSON) : TransactionRequestDetailsFreeFormResponse = {
val toAcc = TransactionRequestAccount (
bank_id = details.to.bank_id,
account_id = details.to.account_id
)
val amount = AmountOfMoney (
currency = details.value.currency,
amount = details.value.amount
)
TransactionRequestDetailsFreeFormResponse (
to=toAcc,
value = amount,
description = details.description
)
}
/** Creates v2.1.0 representation of a TransactionType
*
* @param tr An internal TransactionRequest instance

View File

@ -5,7 +5,7 @@ import java.util.Date
import code.api.util.APIUtil._
import code.api.util.ApiRole._
import code.api.util.ErrorMessages
import code.api.v2_1_0.{TransactionRequestDetailsFreeFormJSON, TransactionRequestDetailsSEPAJSON, TransactionRequestDetailsSandBoxTanJSON}
import code.api.v2_1_0.{TransactionRequestDetailsFreeFormJSON, TransactionRequestDetailsSEPAResponseJSON, TransactionRequestDetailsSandBoxTanJSON}
import code.fx.fx
import code.management.ImporterAPI.ImporterTransaction
import code.model.{Transaction, User, _}
@ -266,7 +266,6 @@ trait Connector {
//set challenge to null
result = Full(result.get.copy(challenge = null))
//save transaction_id if we have one
createdTransactionId match {
case Full(ti) => {
@ -395,7 +394,9 @@ trait Connector {
case "SANDBOX_TAN" => Connector.connector.vend.makePaymentv200(initiator, BankAccountUID(fromAccount.bankId, fromAccount.accountId),
BankAccountUID(toAccount.get.bankId, toAccount.get.accountId), BigDecimal(details.value.amount), details.asInstanceOf[TransactionRequestDetailsSandBoxTan].description)
case "SEPA" => Connector.connector.vend.makePaymentv200(initiator, BankAccountUID(fromAccount.bankId, fromAccount.accountId),
BankAccountUID(toAccount.get.bankId, toAccount.get.accountId), BigDecimal(details.value.amount), details.asInstanceOf[TransactionRequestDetailsSandBoxTan].description)
BankAccountUID(toAccount.get.bankId, toAccount.get.accountId), BigDecimal(details.value.amount), details.asInstanceOf[TransactionRequestDetailsSEPAResponse].description)
case "FREE_FORM" => Connector.connector.vend.makePaymentv200(initiator, BankAccountUID(fromAccount.bankId, fromAccount.accountId),
BankAccountUID(toAccount.get.bankId, toAccount.get.accountId), BigDecimal(details.value.amount), "")
}
//set challenge to null

View File

@ -112,6 +112,12 @@ object BankId {
def unapply(id : String) = Some(BankId(id))
}
case class CounterpartyMetadataIban(val value : String) {
override def toString = value
}
object CounterpartyMetadataIban {
def unapply(id : String) = Some(CounterpartyMetadataIban(id))
}
case class CustomerId(val value : String) {
override def toString = value
@ -658,4 +664,8 @@ class Transaction(
case class AmountOfMoney (
val currency: String,
val amount: String
)
case class Iban(
val iban: String
)

View File

@ -67,14 +67,28 @@ object TransactionRequests extends SimpleInjector {
val description : String
) extends TransactionRequestDetails
case class TransactionRequestDetailsSEPA (
val value : AmountOfMoney,
val description : String
) extends TransactionRequestDetails
case class TransactionRequestDetailsSEPA(
val iban: String,
val value: AmountOfMoney,
val description: String
) extends TransactionRequestDetails
case class TransactionRequestDetailsSEPAResponse(
val iban: String,
val to: TransactionRequestAccount,
val value: AmountOfMoney,
val description: String
) extends TransactionRequestDetails
case class TransactionRequestDetailsFreeForm(
val value: AmountOfMoney
) extends TransactionRequestDetails
case class TransactionRequestDetailsFreeFormResponse(
val to: TransactionRequestAccount,
val value: AmountOfMoney,
val description: String
) extends TransactionRequestDetails
case class TransactionRequestDetailsFreeForm (
val value : AmountOfMoney
) extends TransactionRequestDetails
val transactionRequestProvider = new Inject(buildOne _) {}

View File

@ -9,6 +9,7 @@ import net.liftweb.common.Box
import net.liftweb.mapper.MetaMapper
import net.liftweb.util.Helpers._
import code.entitlement.{Entitlement, MappedEntitlement}
import code.metadata.counterparties.MappedCounterpartyMetadata
import code.transaction.MappedTransaction
import scala.util.Random
@ -26,6 +27,14 @@ trait LocalMappedConnectorTestSetup extends TestConnectorSetupWithStandardPermis
.national_identifier(randomString(5)).saveMe
}
override protected def createCounterpartyMetadata(BankId:String,AccountId:String,iBan:String):CounterpartyMetadata = {
MappedCounterpartyMetadata.create.
thisAccountBankId(BankId).
thisAccountId(AccountId).
accountNumber(iBan).
saveMe
}
// TODO: Should return an option or box so can test if the insert succeeded
// or if it failed due to unique exception etc. However, we'll need to modify / lift callers so they can handle an Option
// override protected def createBank(id : String) : Option[Bank] = {

View File

@ -2,7 +2,8 @@ package code.api
import java.util.{Calendar, Date}
import code.bankconnectors.{OBPLimit, OBPOffset, Connector}
import code.bankconnectors.{Connector, OBPLimit, OBPOffset}
import code.metadata.counterparties.MappedCounterpartyMetadata
import code.model._
import net.liftweb.util.Helpers._
@ -13,6 +14,8 @@ trait TestConnectorSetup {
protected def createAccount(bankId: BankId, accountId : AccountId, currency : String) : BankAccount
protected def createTransaction(account : BankAccount, startDate : Date, finishDate : Date)
//TODO: Here I use the createCounterpartyMetadata.accountNumber to replace the Iban. I will fix it when new version is comming.
protected def createCounterpartyMetadata(BankId:String,AccountId:String,iBan:String):CounterpartyMetadata
final protected def createAccountAndOwnerView(accountOwner: Option[User], bankId: BankId, accountId : AccountId, currency : String) : BankAccount = {
val account = createAccount(bankId, accountId, currency)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff