mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 17:17:09 +00:00
#431 modify createTransactionRequest endpoint (Kafka) for COUNTERPARTY and SEPA -- 4
rame "TransactionRequestDetails" -- > TransactionRequestBody, make code clear( reference #124) save the Body fields to transacionrequest table delete the transactionUUID, now we have the transactionId instead
This commit is contained in:
parent
fcf605faa0
commit
7898693770
@ -153,7 +153,6 @@ object OBPAPI1_1 extends RestHelper with Loggable {
|
||||
|
||||
private def transactionJson(t : ModeratedTransaction) : JObject = {
|
||||
("transaction" ->
|
||||
("uuid" -> t.UUID) ~
|
||||
("id" -> t.id.value) ~
|
||||
("this_account" -> t.bankAccount.map(thisAccountJson)) ~
|
||||
("other_account" -> t.otherBankAccount.map(otherAccountToJson)) ~
|
||||
|
||||
@ -260,7 +260,7 @@ trait APIMethods210 {
|
||||
|The routing details of the counterparty will be forwarded for the transfer.
|
||||
|
|
||||
""".stripMargin,
|
||||
Extraction.decompose(TransactionRequestDetailsCounterpartyJSON (
|
||||
Extraction.decompose(TransactionRequestBodyCounterpartyJSON(
|
||||
CounterpartyIdJson("lalalalwieuryi79878987fds"),
|
||||
AmountOfMoneyJSON("EUR", "100.53"),
|
||||
"A description for the transaction to the counterparty",
|
||||
@ -292,7 +292,7 @@ trait APIMethods210 {
|
||||
|The routing details (IBAN) of the counterparty will be forwarded to the core banking system for the transfer.
|
||||
|
|
||||
""".stripMargin,
|
||||
Extraction.decompose(TransactionRequestDetailsSEPAJSON(lowAmount, IbanJson("IBAN-798789873234"), "This is a SEPA Transaction Request", sharedChargePolicy.toString)
|
||||
Extraction.decompose(TransactionRequestBodySEPAJSON(lowAmount, IbanJson("IBAN-798789873234"), "This is a SEPA Transaction Request", sharedChargePolicy.toString)
|
||||
),
|
||||
emptyObjectJson,
|
||||
emptyObjectJson :: Nil,
|
||||
@ -318,7 +318,7 @@ trait APIMethods210 {
|
||||
s"${ErrorMessages.InvalidTransactionRequestType}: '${transactionRequestType.value}'"
|
||||
|
||||
// Check the input JSON format, here is just check the common parts of all four tpyes
|
||||
transDetailsJson <- tryo {json.extract[TransactionRequestDetailsCommonJSON]} ?~! ErrorMessages.InvalidJsonFormat
|
||||
transDetailsJson <- tryo {json.extract[TransactionRequestBodyCommonJSON]} ?~! ErrorMessages.InvalidJsonFormat
|
||||
isValidAmountNumber <- tryo(BigDecimal(transDetailsJson.value.amount)) ?~! ErrorMessages.InvalidNumber
|
||||
isPositiveAmount <- booleanToBox(isValidAmountNumber > BigDecimal("0"), ErrorMessages.NotPositiveAmount)
|
||||
isValidCurrencyISOCode <- tryo(assert(isValidCurrencyISOCode(transDetailsJson.value.currency))) ?~! ErrorMessages.InvalidISOCurrencyCode
|
||||
@ -331,27 +331,27 @@ trait APIMethods210 {
|
||||
createdTransactionRequest <- transactionRequestType.value match {
|
||||
case "SANDBOX_TAN" => {
|
||||
for {
|
||||
transDetailsSandboxTanJson <- tryo(json.extract[TransactionRequestDetailsSandBoxTanJSON]) ?~! ErrorMessages.InvalidJsonFormat
|
||||
toBankId <- Full(BankId(transDetailsSandboxTanJson.to.bank_id))
|
||||
toAccountId <- Full(AccountId(transDetailsSandboxTanJson.to.account_id))
|
||||
transactionRequestBodySandboxTan <- tryo(json.extract[TransactionRequestBodySandBoxTanJSON]) ?~! ErrorMessages.InvalidJsonFormat
|
||||
toBankId <- Full(BankId(transactionRequestBodySandboxTan.to.bank_id))
|
||||
toAccountId <- Full(AccountId(transactionRequestBodySandboxTan.to.account_id))
|
||||
toAccount <- BankAccount(toBankId, toAccountId) ?~! {ErrorMessages.CounterpartyNotFound}
|
||||
transDetailsSerialized <- tryo {write(transDetailsSandboxTanJson)(Serialization.formats(NoTypeHints))}
|
||||
transDetailsSerialized <- tryo {write(transactionRequestBodySandboxTan)(Serialization.formats(NoTypeHints))}
|
||||
createdTransactionRequest <- Connector.connector.vend.createTransactionRequestv210(u,
|
||||
viewId.value,
|
||||
viewId,
|
||||
fromAccount,
|
||||
toAccount,
|
||||
new MappedCounterparty(), //in SANDBOX_TAN, we only use toAccount, toCounterparty is empty
|
||||
new MappedCounterparty(), //in SANDBOX_TAN, toCounterparty is empty
|
||||
transactionRequestType,
|
||||
transDetailsSandboxTanJson,
|
||||
sharedChargePolicy.toString,
|
||||
transDetailsSerialized)
|
||||
transactionRequestBodySandboxTan,
|
||||
transDetailsSerialized,
|
||||
sharedChargePolicy.toString) //in SANDBOX_TAN, ChargePolicy set default "SHARED"
|
||||
} yield createdTransactionRequest
|
||||
}
|
||||
case "COUNTERPARTY" => {
|
||||
for {
|
||||
//For COUNTERPARTY, Use the counterpartyId to find the toCounterparty and set up the toAccount
|
||||
transDetailsCounterpartyJson <- tryo {json.extract[TransactionRequestDetailsCounterpartyJSON]} ?~! {ErrorMessages.InvalidJsonFormat}
|
||||
toCounterpartyId <- Full(transDetailsCounterpartyJson.to.counterparty_id)
|
||||
transactionRequestBodyCounterparty <- tryo {json.extract[TransactionRequestBodyCounterpartyJSON]} ?~! {ErrorMessages.InvalidJsonFormat}
|
||||
toCounterpartyId <- Full(transactionRequestBodyCounterparty.to.counterparty_id)
|
||||
// Get the Counterparty by id
|
||||
toCounterparty <- Connector.connector.vend.getCounterpartyByCounterpartyId(CounterpartyId(toCounterpartyId)) ?~! {ErrorMessages.CounterpartyNotFoundByCounterpartyId}
|
||||
|
||||
@ -376,31 +376,30 @@ trait APIMethods210 {
|
||||
|
||||
// Following lines: just transfer the details body, add Bank_Id and Account_Id in the Detail part. This is for persistence and 'answerTransactionRequestChallenge'
|
||||
transactionRequestAccountJSON = TransactionRequestAccountJSON(toAccount.bankId.value, toAccount.accountId.value)
|
||||
chargePolicy = transDetailsCounterpartyJson.charge_policy
|
||||
chargePolicy = transactionRequestBodyCounterparty.charge_policy
|
||||
chargePolicyIsValid<-tryo(assert(ChargePolicy.values.contains(ChargePolicy.withName(chargePolicy)))) ?~! ErrorMessages.InvalidChargePolicy
|
||||
transactionRequestDetailsMapperCounterparty = TransactionRequestDetailsMapperCounterpartyJSON(toCounterpartyId.toString,
|
||||
transactionRequestAccountJSON,
|
||||
amountOfMoneyJSON,
|
||||
transDetailsCounterpartyJson.description,
|
||||
transDetailsCounterpartyJson.charge_policy)
|
||||
//Serialize the transResponseDetails to String.
|
||||
transDetailsResponseSerialized <- tryo {write(transactionRequestDetailsMapperCounterparty)(Serialization.formats(NoTypeHints))}
|
||||
transactionRequestBodyCounterparty.description,
|
||||
transactionRequestBodyCounterparty.charge_policy)
|
||||
transDetailsSerialized <- tryo {write(transactionRequestDetailsMapperCounterparty)(Serialization.formats(NoTypeHints))}
|
||||
createdTransactionRequest <- Connector.connector.vend.createTransactionRequestv210(u,
|
||||
viewId.value,
|
||||
viewId,
|
||||
fromAccount,
|
||||
toAccount,
|
||||
toCounterparty,
|
||||
transactionRequestType,
|
||||
transDetailsCounterpartyJson,
|
||||
chargePolicy,
|
||||
transDetailsResponseSerialized)
|
||||
transactionRequestBodyCounterparty,
|
||||
transDetailsSerialized,
|
||||
chargePolicy)
|
||||
} yield createdTransactionRequest
|
||||
|
||||
}
|
||||
case "SEPA" => {
|
||||
for {
|
||||
//For SEPA, Use the iban to find the toCounterparty and set up the toAccount
|
||||
transDetailsSEPAJson <- tryo {json.extract[TransactionRequestDetailsSEPAJSON]} ?~! {ErrorMessages.InvalidJsonFormat}
|
||||
transDetailsSEPAJson <- tryo {json.extract[TransactionRequestBodySEPAJSON]} ?~! {ErrorMessages.InvalidJsonFormat}
|
||||
toIban <- Full(transDetailsSEPAJson.to.iban)
|
||||
toCounterparty <- Connector.connector.vend.getCounterpartyByIban(toIban) ?~! {ErrorMessages.CounterpartyNotFoundByIban}
|
||||
isBeneficiary <- booleanToBox(toCounterparty.isBeneficiary == true, ErrorMessages.CounterpartyBeneficiaryPermit)
|
||||
@ -418,42 +417,41 @@ trait APIMethods210 {
|
||||
transactionRequestAccountJSON = TransactionRequestAccountJSON(toAccount.bankId.value, toAccount.accountId.value)
|
||||
chargePolicy = transDetailsSEPAJson.charge_policy
|
||||
chargePolicyIsValid<-tryo(assert(ChargePolicy.values.contains(ChargePolicy.withName(chargePolicy))))?~! {ErrorMessages.InvalidChargePolicy}
|
||||
transactionRequestDetailsSEPAResponseJSON = TransactionRequestDetailsMapperSEPAJSON(toIban.toString,
|
||||
transactionRequestDetailsSEPARMapperJSON = TransactionRequestDetailsMapperSEPAJSON(toIban.toString,
|
||||
transactionRequestAccountJSON,
|
||||
amountOfMoneyJSON,
|
||||
transDetailsSEPAJson.description,
|
||||
chargePolicy)
|
||||
|
||||
//Serialize the transResponseDetails data to String.
|
||||
transDetailsResponseSerialized <- tryo {write(transactionRequestDetailsSEPAResponseJSON)(Serialization.formats(NoTypeHints))}
|
||||
transDetailsSerialized <- tryo {write(transactionRequestDetailsSEPARMapperJSON)(Serialization.formats(NoTypeHints))}
|
||||
createdTransactionRequest <- Connector.connector.vend.createTransactionRequestv210(u,
|
||||
viewId.value,
|
||||
viewId,
|
||||
fromAccount,
|
||||
toAccount,
|
||||
toCounterparty,
|
||||
transactionRequestType,
|
||||
transDetailsSEPAJson,
|
||||
chargePolicy,
|
||||
transDetailsResponseSerialized)
|
||||
transDetailsSerialized,
|
||||
chargePolicy)
|
||||
} yield createdTransactionRequest
|
||||
}
|
||||
case "FREE_FORM" => {
|
||||
for {
|
||||
transDetailsFreeFormJson <- Full(json.extract[TransactionRequestDetailsFreeFormJSON])
|
||||
transactionRequestBodyFreeForm <- Full(json.extract[TransactionRequestBodyFreeFormJSON])
|
||||
// Following lines: just transfer the details body, add Bank_Id and Account_Id in the Detail part. This is for persistence and 'answerTransactionRequestChallenge'
|
||||
transactionRequestAccountJSON <- Full(TransactionRequestAccountJSON(fromAccount.bankId.value, fromAccount.accountId.value))
|
||||
// The FREE_FORM discription is empty, so make it "" in the following code
|
||||
transactionRequestDetailsFreeFormResponseJSON = TransactionRequestDetailsMapperFreeFormJSON(transactionRequestAccountJSON, amountOfMoneyJSON,transDetailsFreeFormJson.description)
|
||||
transDetailsResponseSerialized <- tryo {write(transactionRequestDetailsFreeFormResponseJSON)(Serialization.formats(NoTypeHints))}
|
||||
transactionRequestDetailsMapperFreeForm = TransactionRequestDetailsMapperFreeFormJSON(transactionRequestAccountJSON,
|
||||
amountOfMoneyJSON,
|
||||
transactionRequestBodyFreeForm.description)
|
||||
transDetailsSerialized <- tryo {write(transactionRequestDetailsMapperFreeForm)(Serialization.formats(NoTypeHints))}
|
||||
createdTransactionRequest <- Connector.connector.vend.createTransactionRequestv210(u,
|
||||
viewId.value,
|
||||
viewId,
|
||||
fromAccount,
|
||||
fromAccount,//in FREE_FORM, we only use toAccount == fromAccount
|
||||
new MappedCounterparty(), //in FREE_FORM, we only use toAccount, toCounterparty is empty
|
||||
transactionRequestType,
|
||||
transDetailsFreeFormJson,
|
||||
sharedChargePolicy.toString,
|
||||
transDetailsResponseSerialized)
|
||||
transactionRequestBodyFreeForm,
|
||||
transDetailsSerialized,
|
||||
sharedChargePolicy.toString)
|
||||
} yield
|
||||
createdTransactionRequest
|
||||
}
|
||||
|
||||
@ -69,47 +69,48 @@ case class IbanJson (val iban : String)
|
||||
|
||||
|
||||
//high level of four different kinds of transaction request types: FREE_FROM, SANDBOXTAN, COUNTERPATY and SEPA.
|
||||
//They share the same AmountOfMoney field,
|
||||
//They share the same AmountOfMoney and description fields
|
||||
//Note : in scala case-to-case inheritance is prohibited, so used trait instead
|
||||
trait TransactionRequestDetailsJSON {
|
||||
trait TransactionRequestCommonBodyJSON {
|
||||
val value : AmountOfMoneyJSON
|
||||
val description: String
|
||||
}
|
||||
|
||||
// the common parts of four types
|
||||
case class TransactionRequestDetailsCommonJSON(
|
||||
value: AmountOfMoneyJSON,
|
||||
description: String
|
||||
) extends TransactionRequestDetailsJSON
|
||||
// note: there is TransactionRequestCommonBodyJSON trait, so this case class call TransactionRequestBodyCommonJSON
|
||||
case class TransactionRequestBodyCommonJSON(
|
||||
value: AmountOfMoneyJSON,
|
||||
description: String
|
||||
) extends TransactionRequestCommonBodyJSON
|
||||
|
||||
// the data from endpoint, extract as valid JSON
|
||||
case class TransactionRequestDetailsSandBoxTanJSON(
|
||||
to: TransactionRequestAccountJSON,
|
||||
value: AmountOfMoneyJSON,
|
||||
description: String
|
||||
) extends TransactionRequestDetailsJSON
|
||||
case class TransactionRequestBodySandBoxTanJSON(
|
||||
to: TransactionRequestAccountJSON,
|
||||
value: AmountOfMoneyJSON,
|
||||
description: String
|
||||
) extends TransactionRequestCommonBodyJSON
|
||||
|
||||
// the data from endpoint, extract as valid JSON
|
||||
case class TransactionRequestDetailsCounterpartyJSON(
|
||||
to: CounterpartyIdJson,
|
||||
value: AmountOfMoneyJSON,
|
||||
description: String,
|
||||
charge_policy: String
|
||||
) extends TransactionRequestDetailsJSON
|
||||
case class TransactionRequestBodyCounterpartyJSON(
|
||||
to: CounterpartyIdJson,
|
||||
value: AmountOfMoneyJSON,
|
||||
description: String,
|
||||
charge_policy: String
|
||||
) extends TransactionRequestCommonBodyJSON
|
||||
|
||||
// the data from endpoint, extract as valid JSON
|
||||
case class TransactionRequestDetailsSEPAJSON(
|
||||
value: AmountOfMoneyJSON,
|
||||
to: IbanJson,
|
||||
description: String,
|
||||
charge_policy: String
|
||||
) extends TransactionRequestDetailsJSON
|
||||
case class TransactionRequestBodySEPAJSON(
|
||||
value: AmountOfMoneyJSON,
|
||||
to: IbanJson,
|
||||
description: String,
|
||||
charge_policy: String
|
||||
) extends TransactionRequestCommonBodyJSON
|
||||
|
||||
// Note: FreeForm is not used yet, the format maybe changed latter. the data from endpoint, extract as valid JSON
|
||||
case class TransactionRequestDetailsFreeFormJSON(
|
||||
value: AmountOfMoneyJSON,
|
||||
description: String
|
||||
) extends TransactionRequestDetailsJSON
|
||||
case class TransactionRequestBodyFreeFormJSON(
|
||||
value: AmountOfMoneyJSON,
|
||||
description: String
|
||||
) extends TransactionRequestCommonBodyJSON
|
||||
|
||||
|
||||
|
||||
@ -117,10 +118,10 @@ case class TransactionRequestDetailsFreeFormJSON(
|
||||
//And when call the "answerTransactionRequestChallenge" endpoint, it will use this mapper.mdetails to process further step
|
||||
// code : detailsJsonExtract = details.extract[TransactionRequestDetailsMapperJSON]
|
||||
case class TransactionRequestDetailsMapperJSON(
|
||||
to: TransactionRequestAccountJSON,
|
||||
value: AmountOfMoneyJSON,
|
||||
description: String
|
||||
) extends TransactionRequestDetailsJSON
|
||||
to: TransactionRequestAccountJSON,
|
||||
value: AmountOfMoneyJSON,
|
||||
description: String
|
||||
) extends TransactionRequestCommonBodyJSON
|
||||
|
||||
//Mapper means this part will be stored into mapper.mdetails
|
||||
//And when call the "answerTransactionRequestChallenge" endpoint, it will use this mapper.mdetails to process further step
|
||||
@ -131,7 +132,7 @@ case class TransactionRequestDetailsMapperCounterpartyJSON(
|
||||
value: AmountOfMoneyJSON,
|
||||
description: String,
|
||||
charge_policy: String
|
||||
) extends TransactionRequestDetailsJSON
|
||||
) extends TransactionRequestCommonBodyJSON
|
||||
|
||||
//Mapper means this part will be stored into mapper. This is just for prepare the data
|
||||
//And when call the "answerTransactionRequestChallenge" endpoint, it will use this mapper.mdetails to process further step
|
||||
@ -142,7 +143,7 @@ case class TransactionRequestDetailsMapperSEPAJSON(
|
||||
value: AmountOfMoneyJSON,
|
||||
description: String,
|
||||
charge_policy: String
|
||||
) extends TransactionRequestDetailsJSON
|
||||
) extends TransactionRequestCommonBodyJSON
|
||||
|
||||
|
||||
//Mapper means this part will be stored into mapper. This is just for prepare the data
|
||||
@ -152,7 +153,7 @@ case class TransactionRequestDetailsMapperFreeFormJSON(
|
||||
to: TransactionRequestAccountJSON,
|
||||
value: AmountOfMoneyJSON,
|
||||
description: String
|
||||
) extends TransactionRequestDetailsJSON
|
||||
) extends TransactionRequestCommonBodyJSON
|
||||
|
||||
case class TransactionRequestWithChargeJSON210(
|
||||
id: String,
|
||||
@ -297,7 +298,7 @@ case class CustomerJSONs(customers: List[CustomerJson])
|
||||
|
||||
case class CustomerCreditRatingJSON(rating: String, source: String)
|
||||
|
||||
//V210 added details and description feilds
|
||||
//V210 added details and description fields
|
||||
case class ProductJson(code : String,
|
||||
name : String,
|
||||
category: String,
|
||||
@ -309,7 +310,7 @@ case class ProductJson(code : String,
|
||||
meta : MetaJson)
|
||||
case class ProductsJson (products : List[ProductJson])
|
||||
|
||||
//V210 add bank_id feild and delete id
|
||||
//V210 add bank_id field and delete id
|
||||
case class BranchJsonPut(
|
||||
bank_id: String,
|
||||
name: String,
|
||||
|
||||
@ -211,11 +211,18 @@ trait Connector {
|
||||
* @param fromAccountUID The unique identifier of the account sending money
|
||||
* @param toAccountUID The unique identifier of the account receiving money
|
||||
* @param toCounterparty The unique identifier of the acounterparty receiving money
|
||||
* @param amt The amount of money to send ( > 0 )
|
||||
* @param amount The amount of money to send ( > 0 )
|
||||
* @param transactionRequestType user input: SEPA, SANDBOX_TAN, FREE_FORM, COUNTERPARTY
|
||||
* @return The id of the sender's new transaction,
|
||||
*/
|
||||
def makePaymentv200(initiator: User, fromAccountUID: BankAccountUID, toAccountUID: BankAccountUID, toCounterparty: CounterpartyTrait, amt: BigDecimal, description: String, transactionRequestType: TransactionRequestType, chargePolicy: String): Box[TransactionId] = {
|
||||
def makePaymentv200(initiator: User,
|
||||
fromAccountUID: BankAccountUID,
|
||||
toAccountUID: BankAccountUID,
|
||||
toCounterparty: CounterpartyTrait,
|
||||
amount: BigDecimal,
|
||||
description: String,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
chargePolicy: String): Box[TransactionId] = {
|
||||
for {
|
||||
// Note: These following guards are checked in AIP level (maybe some other function call it, so leave the guards here)
|
||||
fromAccount <- getBankAccount(fromAccountUID.bankId, fromAccountUID.accountId) ?~
|
||||
@ -227,21 +234,15 @@ trait Connector {
|
||||
// s"Cannot send payment to account with different currency (From ${fromAccount.currency} to ${toAccount.currency}"
|
||||
//})
|
||||
|
||||
// Note: These are guards. Values are calculated in makePaymentImpl
|
||||
rate <- tryo {
|
||||
fx.exchangeRate(fromAccount.currency, toAccount.currency)
|
||||
} ?~! {
|
||||
s"The requested currency conversion (${fromAccount.currency} to ${toAccount.currency}) is not supported."
|
||||
}
|
||||
notUsedHereConvertedAmount <- tryo {
|
||||
fx.convert(amt, rate)
|
||||
} ?~! {
|
||||
"Currency conversion failed."
|
||||
}
|
||||
isPositiveAmtToSend <- booleanToBox(amt > BigDecimal("0"), s"Can't send a payment with a value of 0 or less. ($amt)")
|
||||
// Note: These are guards. Values are calculated in makePaymentImpl
|
||||
rate <- tryo { fx.exchangeRate(fromAccount.currency, toAccount.currency)} ?~!
|
||||
{s"The requested currency conversion (${fromAccount.currency} to ${toAccount.currency}) is not supported."}
|
||||
notUsedHereConvertedAmount <- tryo { fx.convert(amount, rate) } ?~!
|
||||
{"Currency conversion failed."}
|
||||
isPositiveAmtToSend <- booleanToBox(amount > BigDecimal("0"), s"Can't send a payment with a value of 0 or less. ($amount)")
|
||||
//TODO: verify the amount fits with the currency -> e.g. 12.543 EUR not allowed, 10.00 JPY not allowed, 12.53 EUR allowed
|
||||
|
||||
transactionId <- makePaymentImpl(fromAccount, toAccount, toCounterparty, amt, description, transactionRequestType, chargePolicy)
|
||||
transactionId <- makePaymentImpl(fromAccount, toAccount, toCounterparty, amount, description, transactionRequestType, chargePolicy)
|
||||
} yield transactionId
|
||||
}
|
||||
|
||||
@ -389,21 +390,35 @@ trait Connector {
|
||||
result
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param initiator
|
||||
* @param viewId
|
||||
* @param fromAccount
|
||||
* @param toAccount
|
||||
* @param toCounterparty
|
||||
* @param transactionRequestType Support Types: SANDBOX_TAN, FREE_FORM, SEPA and COUNTERPARTY
|
||||
* @param transactionRequestCommonBody Body from http request: should have common fields
|
||||
* @param chargePolicy SHARED, SENDER, RECEIVER
|
||||
* @param detailsPlain This is the details / body of the request (contains all fields in the body)
|
||||
* @return Always create a new Transaction Request in mapper, and return all the fields
|
||||
*/
|
||||
|
||||
def createTransactionRequestv210(initiator: User,
|
||||
viewId: String,
|
||||
viewId: ViewId,
|
||||
fromAccount: BankAccount,
|
||||
toAccount: BankAccount,
|
||||
toCounterparty: CounterpartyTrait,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
details: TransactionRequestDetailsJSON,
|
||||
chargePolicy: String,
|
||||
detailsPlain: String): Box[TransactionRequest] = {
|
||||
transactionRequestCommonBody: TransactionRequestCommonBodyJSON,
|
||||
detailsPlain: String,
|
||||
chargePolicy: String): Box[TransactionRequest] = {
|
||||
|
||||
// Get the threshold for a challenge. i.e. over what value do we require an out of bounds security challenge to be sent?
|
||||
val challengeThreshold = getChallengeThreshold(fromAccount.bankId.value, fromAccount.accountId.value, viewId, transactionRequestType.value, details.value.currency, fromAccount.currency, initiator.name)
|
||||
val challengeThreshold = getChallengeThreshold(fromAccount.bankId.value, fromAccount.accountId.value, viewId.value, transactionRequestType.value, transactionRequestCommonBody.value.currency, fromAccount.currency, initiator.name)
|
||||
|
||||
// Set initial status
|
||||
val status = if (BigDecimal(details.value.amount) < BigDecimal(challengeThreshold.amount)) {
|
||||
val status = if (BigDecimal(transactionRequestCommonBody.value.amount) < BigDecimal(challengeThreshold.amount)) {
|
||||
// TODO Document this
|
||||
if ( Props.getLong("transaction_status_scheduler_delay").isEmpty )
|
||||
TransactionRequests.STATUS_COMPLETED
|
||||
@ -418,10 +433,19 @@ trait Connector {
|
||||
// For now, arbitrary charge value to demonstrate PSD2 charge transparency principle.
|
||||
// Eventually this would come from Transaction Type? 10 decimal places of scaling so can add small percentage per transaction.
|
||||
// TODO create a function for this getChargeLevel
|
||||
chargeValue <- tryo {(BigDecimal(details.value.amount) * 0.0001).setScale(10, BigDecimal.RoundingMode.HALF_UP).toDouble} ?~! s"could not create charge for ${details.value.amount}"
|
||||
charge = TransactionRequestCharge("Total charges for completed transaction", AmountOfMoney(details.value.currency, chargeValue.toString()))
|
||||
chargeValue <- tryo {(BigDecimal(transactionRequestCommonBody.value.amount) * 0.0001).setScale(10, BigDecimal.RoundingMode.HALF_UP).toDouble} ?~! s"could not create charge for ${transactionRequestCommonBody.value.amount}"
|
||||
charge = TransactionRequestCharge("Total charges for completed transaction", AmountOfMoney(transactionRequestCommonBody.value.currency, chargeValue.toString()))
|
||||
|
||||
transactionRequest <- createTransactionRequestImpl210(TransactionRequestId(java.util.UUID.randomUUID().toString), transactionRequestType, fromAccount, toAccount, toCounterparty, detailsPlain, status, charge, chargePolicy)
|
||||
transactionRequest <- createTransactionRequestImpl210(TransactionRequestId(java.util.UUID.randomUUID().toString),
|
||||
transactionRequestType,
|
||||
fromAccount,
|
||||
toAccount,
|
||||
toCounterparty,
|
||||
transactionRequestCommonBody,
|
||||
detailsPlain,
|
||||
status,
|
||||
charge,
|
||||
chargePolicy)
|
||||
} yield transactionRequest
|
||||
|
||||
//make sure we get something back
|
||||
@ -434,8 +458,8 @@ trait Connector {
|
||||
BankAccountUID(fromAccount.bankId, fromAccount.accountId),
|
||||
BankAccountUID(toAccount.bankId, toAccount.accountId),
|
||||
toCounterparty,
|
||||
BigDecimal(details.value.amount),
|
||||
details.description,
|
||||
BigDecimal(transactionRequestCommonBody.value.amount),
|
||||
transactionRequestCommonBody.description,
|
||||
transactionRequestType,
|
||||
chargePolicy)
|
||||
//set challenge to null, otherwise it have the default value "challenge": {"id": "","allowed_attempts": 0,"challenge_type": ""}
|
||||
@ -461,8 +485,30 @@ trait Connector {
|
||||
fromAccount : BankAccount, counterparty : BankAccount, body: TransactionRequestBody,
|
||||
status: String, charge: TransactionRequestCharge) : Box[TransactionRequest]
|
||||
|
||||
protected def createTransactionRequestImpl210(transactionRequestId: TransactionRequestId, transactionRequestType: TransactionRequestType, fromAccount: BankAccount, toAccount: BankAccount, toCounterparty: CounterpartyTrait, details: String, status: String, charge: TransactionRequestCharge, chargePolicy: String): Box[TransactionRequest]
|
||||
|
||||
/**
|
||||
*
|
||||
* @param transactionRequestId
|
||||
* @param transactionRequestType Support Types: SANDBOX_TAN, FREE_FORM, SEPA and COUNTERPARTY
|
||||
* @param fromAccount
|
||||
* @param toAccount
|
||||
* @param toCounterparty
|
||||
* @param transactionRequestCommonBody Body from http request: should have common fields:
|
||||
* @param details This is the details / body of the request (contains all fields in the body)
|
||||
* @param status "INITIATED" "PENDING" "FAILED" "COMPLETED"
|
||||
* @param charge
|
||||
* @param chargePolicy SHARED, SENDER, RECEIVER
|
||||
* @return Always create a new Transaction Request in mapper, and return all the fields
|
||||
*/
|
||||
protected def createTransactionRequestImpl210(transactionRequestId: TransactionRequestId,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
fromAccount: BankAccount,
|
||||
toAccount: BankAccount,
|
||||
toCounterparty: CounterpartyTrait,
|
||||
transactionRequestCommonBody: TransactionRequestCommonBodyJSON,
|
||||
details: String,
|
||||
status: String,
|
||||
charge: TransactionRequestCharge,
|
||||
chargePolicy: String): Box[TransactionRequest]
|
||||
|
||||
def saveTransactionRequestTransaction(transactionRequestId: TransactionRequestId, transactionId: TransactionId) = {
|
||||
//put connector agnostic logic here if necessary
|
||||
|
||||
@ -28,7 +28,7 @@ import java.util.{Date, Locale, UUID}
|
||||
|
||||
import code.accountholder.{AccountHolders, MapperAccountHolders$}
|
||||
import code.api.util.ErrorMessages
|
||||
import code.api.v2_1_0.{BranchJsonPost, BranchJsonPut}
|
||||
import code.api.v2_1_0.{BranchJsonPost, BranchJsonPut, TransactionRequestCommonBodyJSON}
|
||||
import code.branches.Branches.{Branch, BranchId}
|
||||
import code.branches.MappedBranch
|
||||
import code.fx.{FXRate, fx}
|
||||
@ -597,24 +597,43 @@ object KafkaMappedConnector extends Connector with Loggable {
|
||||
}
|
||||
|
||||
|
||||
protected override def makePaymentImpl(fromAccount: KafkaBankAccount, toAccount: KafkaBankAccount, toCounterparty: CounterpartyTrait, amt: BigDecimal, description: String, transactionRequestType: TransactionRequestType, chargePolicy: String): Box[TransactionId] = {
|
||||
val sentTransactionId = saveTransaction(fromAccount, toAccount, toCounterparty, -amt, description, transactionRequestType, chargePolicy)
|
||||
protected override def makePaymentImpl(fromAccount: KafkaBankAccount,
|
||||
toAccount: KafkaBankAccount,
|
||||
toCounterparty: CounterpartyTrait,
|
||||
amt: BigDecimal,
|
||||
description: String,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
chargePolicy: String): Box[TransactionId] = {
|
||||
|
||||
val sentTransactionId = saveTransaction(fromAccount,
|
||||
toAccount,
|
||||
toCounterparty,
|
||||
-amt,
|
||||
description,
|
||||
transactionRequestType,
|
||||
chargePolicy)
|
||||
|
||||
sentTransactionId
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Saves a transaction with amount @amt and counterparty @counterparty for account @account. Returns the id
|
||||
* Saves a transaction with amount @amount and counterparty @counterparty for account @account. Returns the id
|
||||
* of the saved transaction.
|
||||
*/
|
||||
private def saveTransaction(fromAccount: KafkaBankAccount, toAccount: KafkaBankAccount, toCounterparty: CounterpartyTrait, amt: BigDecimal, description: String, transactionRequestType: TransactionRequestType, chargePolicy: String) = {
|
||||
private def saveTransaction(fromAccount: KafkaBankAccount,
|
||||
toAccount: KafkaBankAccount,
|
||||
toCounterparty: CounterpartyTrait,
|
||||
amount: BigDecimal,
|
||||
description: String,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
chargePolicy: String) = {
|
||||
|
||||
val transactionTime = now
|
||||
val currency = fromAccount.currency
|
||||
|
||||
//update the balance of the account for which a transaction is being created
|
||||
//val newAccountBalance : Long = account.balance.toLong + Helper.convertToSmallestCurrencyUnits(amt, account.currency)
|
||||
//val newAccountBalance : Long = account.balance.toLong + Helper.convertToSmallestCurrencyUnits(amount, account.currency)
|
||||
//account.balance = newAccountBalance
|
||||
|
||||
val req: Map[String, String] = Map(
|
||||
@ -628,7 +647,7 @@ object KafkaMappedConnector extends Connector with Loggable {
|
||||
"accountId" -> fromAccount.accountId.value,
|
||||
"transactionRequestType" -> transactionRequestType.value,
|
||||
"transactionType" -> "AC",
|
||||
"amount" -> amt.toString,
|
||||
"amount" -> amount.toString,
|
||||
"currency" -> currency,
|
||||
"description" -> description,
|
||||
//Old data: other BankAccount(toAccount: BankAccount)simulate counterparty
|
||||
@ -702,8 +721,25 @@ object KafkaMappedConnector extends Connector with Loggable {
|
||||
|
||||
|
||||
//Note: now call the local mapper to store data
|
||||
protected override def createTransactionRequestImpl210(transactionRequestId: TransactionRequestId, transactionRequestType: TransactionRequestType, fromAccount: BankAccount, toAccount: BankAccount, toCounterparty: CounterpartyTrait, details: String, status: String, charge: TransactionRequestCharge, chargePolicy: String): Box[TransactionRequest] = {
|
||||
LocalMappedConnector.createTransactionRequestImpl210(transactionRequestId: TransactionRequestId, transactionRequestType: TransactionRequestType, fromAccount: BankAccount, toAccount: BankAccount, toCounterparty: CounterpartyTrait, details: String, status: String, charge: TransactionRequestCharge, chargePolicy: String)
|
||||
protected override def createTransactionRequestImpl210(transactionRequestId: TransactionRequestId,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
fromAccount: BankAccount,
|
||||
toAccount: BankAccount,
|
||||
toCounterparty: CounterpartyTrait,
|
||||
transactionRequestCommonBody: TransactionRequestCommonBodyJSON,
|
||||
details: String, status: String,
|
||||
charge: TransactionRequestCharge,
|
||||
chargePolicy: String): Box[TransactionRequest] = {
|
||||
|
||||
LocalMappedConnector.createTransactionRequestImpl210(transactionRequestId: TransactionRequestId,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
fromAccount: BankAccount, toAccount: BankAccount,
|
||||
toCounterparty: CounterpartyTrait,
|
||||
transactionRequestCommonBody: TransactionRequestCommonBodyJSON,
|
||||
details: String,
|
||||
status: String,
|
||||
charge: TransactionRequestCharge,
|
||||
chargePolicy: String)
|
||||
}
|
||||
//Note: now call the local mapper to store data
|
||||
override def saveTransactionRequestTransactionImpl(transactionRequestId: TransactionRequestId, transactionId: TransactionId): Box[Boolean] = {
|
||||
@ -1128,7 +1164,6 @@ object KafkaMappedConnector extends Connector with Loggable {
|
||||
} yield {
|
||||
// Create new transaction
|
||||
new Transaction(
|
||||
r.transactionId, // uuid:String
|
||||
TransactionId(r.transactionId), // id:TransactionId
|
||||
thisAccount, // thisAccount:BankAccount
|
||||
counterparty, // otherAccount:OtherBankAccount
|
||||
|
||||
@ -4,7 +4,7 @@ import java.text.SimpleDateFormat
|
||||
import java.util.{Date, TimeZone, UUID}
|
||||
|
||||
import code.accountholder.MapperAccountHolders$
|
||||
import code.api.v2_1_0.{BranchJsonPost, BranchJsonPut}
|
||||
import code.api.v2_1_0.{BranchJsonPost, BranchJsonPut, TransactionRequestCommonBodyJSON}
|
||||
import code.branches.Branches.{Branch, BranchId}
|
||||
import code.branches.MappedBranch
|
||||
import code.fx.{FXRate, fx}
|
||||
@ -256,7 +256,6 @@ private object LocalConnector extends Connector with Loggable {
|
||||
val balance = transaction.details.get.new_balance.get.amount.get
|
||||
|
||||
new Transaction(
|
||||
uuid,
|
||||
id,
|
||||
theAccount,
|
||||
otherAccount,
|
||||
@ -366,7 +365,13 @@ private object LocalConnector extends Connector with Loggable {
|
||||
account : BankAccount, counterparty : BankAccount, body: TransactionRequestBody,
|
||||
status: String, charge: TransactionRequestCharge) : Box[TransactionRequest] = ???
|
||||
|
||||
protected override def createTransactionRequestImpl210(transactionRequestId: TransactionRequestId, transactionRequestType: TransactionRequestType, account: BankAccount, toAccount: BankAccount, toCounterparty: CounterpartyTrait, details: String, status: String, charge: TransactionRequestCharge, chargePolicy: String): Box[TransactionRequest] = ???
|
||||
protected override def createTransactionRequestImpl210(transactionRequestId: TransactionRequestId,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
account: BankAccount, toAccount: BankAccount, toCounterparty: CounterpartyTrait,
|
||||
transactionRequestCommonBody: TransactionRequestCommonBodyJSON,
|
||||
details: String, status: String,
|
||||
charge: TransactionRequestCharge,
|
||||
chargePolicy: String): Box[TransactionRequest] = ???
|
||||
|
||||
override def saveTransactionRequestTransactionImpl(transactionRequestId: TransactionRequestId, transactionId: TransactionId) = ???
|
||||
override def saveTransactionRequestChallengeImpl(transactionRequestId: TransactionRequestId, challenge: TransactionRequestChallenge) = ???
|
||||
|
||||
@ -5,7 +5,7 @@ import java.util.{Date, UUID}
|
||||
import code.TransactionTypes.TransactionType.TransactionTypeProvider
|
||||
import code.accountholder.MapperAccountHolders$
|
||||
import code.api.util.ErrorMessages
|
||||
import code.api.v2_1_0.{BranchJsonPost, BranchJsonPut}
|
||||
import code.api.v2_1_0.{BranchJsonPost, BranchJsonPut, TransactionRequestCommonBodyJSON}
|
||||
import code.branches.Branches.{Branch, BranchId}
|
||||
import code.branches.MappedBranch
|
||||
import code.fx.{FXRate, MappedFXRate, fx}
|
||||
@ -385,16 +385,18 @@ object LocalMappedConnector extends Connector with Loggable {
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
Perform a payment (in the sandbox)
|
||||
Store one or more transactions
|
||||
*/
|
||||
override def makePaymentImpl(fromAccount: MappedBankAccount, toAccount: MappedBankAccount, toCounterparty: CounterpartyTrait, amt: BigDecimal, description: String, transactionRequestType: TransactionRequestType, chargePolicy: String): Box[TransactionId] = {
|
||||
|
||||
//we need to save a copy of this payment as a transaction in each of the accounts involved, with opposite amounts
|
||||
|
||||
|
||||
/**
|
||||
* Perform a payment (in the sandbox) Store one or more transactions
|
||||
*/
|
||||
override def makePaymentImpl(fromAccount: MappedBankAccount,
|
||||
toAccount: MappedBankAccount,
|
||||
toCounterparty: CounterpartyTrait,
|
||||
amount: BigDecimal,
|
||||
description: String,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
chargePolicy: String): Box[TransactionId] = {
|
||||
|
||||
// Note: These are guards. Values are calculated in makePaymentv200
|
||||
val rate = tryo {
|
||||
fx.exchangeRate(fromAccount.currency, toAccount.currency)
|
||||
} ?~! {
|
||||
@ -402,8 +404,8 @@ Store one or more transactions
|
||||
}
|
||||
|
||||
// Is it better to pass these into this function ?
|
||||
val fromTransAmt = -amt//from fromAccount balance should decrease
|
||||
val toTransAmt = fx.convert(amt, rate.get)
|
||||
val fromTransAmt = -amount//from fromAccount balance should decrease
|
||||
val toTransAmt = fx.convert(amount, rate.get)
|
||||
|
||||
//TODO: in FREE_FORM, fromAccount== toAccount, the following two method will have a bug, because of the database transaction. need an explicit commit to save data between two methods.
|
||||
// From
|
||||
@ -417,13 +419,13 @@ Store one or more transactions
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a transaction with @amt, @toAccount and @transactionRequestType for @fromAccount and @toCounterparty. <br>
|
||||
* Saves a transaction with @amount, @toAccount and @transactionRequestType for @fromAccount and @toCounterparty. <br>
|
||||
* Returns the id of the saved transactionId.<br>
|
||||
*/
|
||||
private def saveTransaction(fromAccount: MappedBankAccount,
|
||||
toAccount: BankAccount,
|
||||
toAccount: MappedBankAccount,
|
||||
toCounterparty: CounterpartyTrait,
|
||||
amt: BigDecimal,
|
||||
amount: BigDecimal,
|
||||
description: String,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
chargePolicy: String): Box[TransactionId] = {
|
||||
@ -433,7 +435,7 @@ Store one or more transactions
|
||||
|
||||
|
||||
//update the balance of the fromAccount for which a transaction is being created
|
||||
val newAccountBalance : Long = fromAccount.accountBalance.get + Helper.convertToSmallestCurrencyUnits(amt, fromAccount.currency)
|
||||
val newAccountBalance : Long = fromAccount.accountBalance.get + Helper.convertToSmallestCurrencyUnits(amount, fromAccount.currency)
|
||||
fromAccount.accountBalance(newAccountBalance).save()
|
||||
|
||||
val mappedTransaction = MappedTransaction.create
|
||||
@ -441,7 +443,7 @@ Store one or more transactions
|
||||
.bank(fromAccount.bankId.value)
|
||||
.account(fromAccount.accountId.value)
|
||||
.transactionType(transactionRequestType.value)
|
||||
.amount(Helper.convertToSmallestCurrencyUnits(amt, currency))
|
||||
.amount(Helper.convertToSmallestCurrencyUnits(amount, currency))
|
||||
.newAccountBalance(newAccountBalance)
|
||||
.currency(currency)
|
||||
.tStartDate(transactionTime)
|
||||
@ -494,14 +496,24 @@ Store one or more transactions
|
||||
Full(mappedTransactionRequest).flatMap(_.toTransactionRequest)
|
||||
}
|
||||
|
||||
override def createTransactionRequestImpl210(transactionRequestId: TransactionRequestId, transactionRequestType: TransactionRequestType, fromAccount: BankAccount,
|
||||
toAccount: BankAccount, toCounterparty: CounterpartyTrait,
|
||||
details: String, status: String, charge: TransactionRequestCharge, chargePolicy: String): Box[TransactionRequest] = {
|
||||
override def createTransactionRequestImpl210(transactionRequestId: TransactionRequestId,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
fromAccount: BankAccount,
|
||||
toAccount: BankAccount,
|
||||
toCounterparty: CounterpartyTrait,
|
||||
transactionRequestCommonBody: TransactionRequestCommonBodyJSON,
|
||||
details: String,
|
||||
status: String,
|
||||
charge: TransactionRequestCharge,
|
||||
chargePolicy: String): Box[TransactionRequest] = {
|
||||
|
||||
// Note: We don't save transaction_ids, status and challenge here.
|
||||
val mappedTransactionRequest = MappedTransactionRequest.create
|
||||
|
||||
//transaction request fields:
|
||||
.mTransactionRequestId(transactionRequestId.value)
|
||||
.mType(transactionRequestType.value)
|
||||
//transaction fields:
|
||||
.mStatus(status)
|
||||
.mStartDate(now)
|
||||
.mEndDate(now)
|
||||
@ -509,18 +521,15 @@ Store one or more transactions
|
||||
.mCharge_Amount(charge.value.amount)
|
||||
.mCharge_Currency(charge.value.currency)
|
||||
.mcharge_Policy(chargePolicy)
|
||||
//Body from http request: SANDBOX_TAN, FREE_FORM, SEPA and COUNTERPARTY should have the same following fields:
|
||||
// .mBody_Value_Currency (toAccount.currency)
|
||||
// .mBody_Value_Amount (toAccount.balance)
|
||||
// .mBody_Description (toAccount.balance)
|
||||
.mDetails(details) // This is the details / body of the request (contains all fields in the body)
|
||||
|
||||
//fromAccount fields
|
||||
.mFrom_BankId(fromAccount.bankId.value)
|
||||
.mFrom_AccountId(fromAccount.accountId.value)
|
||||
|
||||
//toAccount fields
|
||||
.mTo_BankId(toAccount.bankId.value)
|
||||
.mTo_AccountId(toAccount.accountId.value)
|
||||
|
||||
//toCounterparty fields
|
||||
.mName(toCounterparty.name)
|
||||
.mThisBankId(toCounterparty.thisBankId)
|
||||
@ -533,6 +542,13 @@ Store one or more transactions
|
||||
.mOtherBankRoutingAddress(toCounterparty.otherBankRoutingAddress)
|
||||
.mIsBeneficiary(toCounterparty.isBeneficiary)
|
||||
|
||||
//Body from http request: SANDBOX_TAN, FREE_FORM, SEPA and COUNTERPARTY should have the same following fields:
|
||||
.mBody_Value_Currency(transactionRequestCommonBody.value.currency)
|
||||
.mBody_Value_Amount(transactionRequestCommonBody.value.amount)
|
||||
.mBody_Description(transactionRequestCommonBody.description)
|
||||
.mDetails(details) // This is the details / body of the request (contains all fields in the body)
|
||||
|
||||
|
||||
.saveMe
|
||||
Full(mappedTransactionRequest).flatMap(_.toTransactionRequest)
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import java.util.{Date, Locale, Optional, Properties, UUID}
|
||||
|
||||
import code.accountholder.MapperAccountHolders$
|
||||
import code.api.util.ErrorMessages
|
||||
import code.api.v2_1_0.BranchJsonPost
|
||||
import code.api.v2_1_0.{BranchJsonPost, TransactionRequestCommonBodyJSON}
|
||||
import code.fx.{FXRate, fx}
|
||||
import code.branches.Branches.{Branch, BranchId}
|
||||
import code.branches.MappedBranch
|
||||
@ -737,8 +737,25 @@ private def saveTransaction(fromAccount: AccountType, toAccount: AccountType, am
|
||||
}
|
||||
|
||||
//Note: now call the local mapper to store data
|
||||
protected override def createTransactionRequestImpl210(transactionRequestId: TransactionRequestId, transactionRequestType: TransactionRequestType, fromAccount: BankAccount, toAccount: BankAccount, toCounterparty: CounterpartyTrait, details: String, status: String, charge: TransactionRequestCharge, chargePolicy: String): Box[TransactionRequest] = {
|
||||
LocalMappedConnector.createTransactionRequestImpl210(transactionRequestId: TransactionRequestId, transactionRequestType: TransactionRequestType, fromAccount: BankAccount, toAccount: BankAccount, toCounterparty: CounterpartyTrait, details: String, status: String, charge: TransactionRequestCharge, chargePolicy: String)
|
||||
protected override def createTransactionRequestImpl210(transactionRequestId: TransactionRequestId,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
fromAccount: BankAccount,
|
||||
toAccount: BankAccount,
|
||||
toCounterparty: CounterpartyTrait,
|
||||
transactionRequestCommonBody: TransactionRequestCommonBodyJSON,
|
||||
details: String, status: String,
|
||||
charge: TransactionRequestCharge,
|
||||
chargePolicy: String): Box[TransactionRequest] = {
|
||||
|
||||
LocalMappedConnector.createTransactionRequestImpl210(transactionRequestId: TransactionRequestId,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
fromAccount: BankAccount, toAccount: BankAccount,
|
||||
toCounterparty: CounterpartyTrait,
|
||||
transactionRequestCommonBody: TransactionRequestCommonBodyJSON,
|
||||
details: String,
|
||||
status: String,
|
||||
charge: TransactionRequestCharge,
|
||||
chargePolicy: String)
|
||||
}
|
||||
|
||||
override def saveTransactionRequestTransactionImpl(transactionRequestId: TransactionRequestId, transactionId: TransactionId): Box[Boolean] = {
|
||||
@ -1108,7 +1125,6 @@ private def saveTransaction(fromAccount: AccountType, toAccount: AccountType, am
|
||||
|
||||
// Create new transaction
|
||||
new Transaction(
|
||||
r.id, // uuid:String
|
||||
TransactionId(r.id), // id:TransactionId
|
||||
thisAccount, // thisAccount:BankAccount
|
||||
counterparty, // counterparty:Counterparty
|
||||
|
||||
@ -97,7 +97,7 @@ object ImporterAPI extends RestHelper with Loggable {
|
||||
JField("amount", JString(t.amount.toString)))))))
|
||||
|
||||
val transactionJson = {
|
||||
JObject(List(JField("obp_transaction_uuid", JString(t.uuid)),
|
||||
JObject(List(JField("obp_transaction_uuid", JString(t.id.value)),
|
||||
JField("this_account", thisAccJson),
|
||||
JField("other_account", otherAccJson),
|
||||
JField("details", detailsJson)))
|
||||
|
||||
@ -652,8 +652,6 @@ trait TransactionUUID {
|
||||
}
|
||||
|
||||
class Transaction(
|
||||
//A universally unique id
|
||||
val uuid : String,
|
||||
//id is unique for transactions of @thisAccount
|
||||
val id : TransactionId,
|
||||
val thisAccount : BankAccount,
|
||||
|
||||
@ -48,7 +48,6 @@ object Moderation {
|
||||
}
|
||||
|
||||
class ModeratedTransaction(
|
||||
val UUID : String,
|
||||
val id: TransactionId,
|
||||
val bankAccount: Moderated[ModeratedBankAccount],
|
||||
val otherBankAccount: Moderated[ModeratedOtherBankAccount],
|
||||
|
||||
@ -291,7 +291,6 @@ trait View {
|
||||
lazy val moderatedTransaction = {
|
||||
//transaction data
|
||||
val transactionId = transaction.id
|
||||
val transactionUUID = transaction.uuid
|
||||
val otherBankAccount = moderate(transaction.otherAccount)
|
||||
|
||||
//transation metadata
|
||||
@ -406,7 +405,6 @@ trait View {
|
||||
else ""
|
||||
|
||||
new ModeratedTransaction(
|
||||
UUID = transactionUUID,
|
||||
id = transactionId,
|
||||
bankAccount = moderatedAccount,
|
||||
otherBankAccount = otherBankAccount,
|
||||
|
||||
@ -16,12 +16,10 @@ class MappedTransaction extends LongKeyedMapper[MappedTransaction] with IdPK wit
|
||||
|
||||
object bank extends MappedString(this, 255)
|
||||
object account extends MappedString(this, 255)
|
||||
//Note: previous we used transactionUUID, the transactionId have the same function
|
||||
object transactionId extends MappedString(this, 255) {
|
||||
override def defaultValue = UUID.randomUUID().toString
|
||||
}
|
||||
//TODO: review the need for this
|
||||
// (why do we need transactionUUID and transactionId - which is a UUID?)
|
||||
object transactionUUID extends MappedUUID(this)
|
||||
object transactionType extends MappedString(this, 100)
|
||||
|
||||
//amount/new balance use the smallest unit of currency! e.g. cents, yen, pence, øre, etc.
|
||||
@ -46,7 +44,7 @@ class MappedTransaction extends LongKeyedMapper[MappedTransaction] with IdPK wit
|
||||
object counterpartyIban extends MappedString(this, 100)
|
||||
object counterpartyAccountKind extends MappedString(this, 40)
|
||||
|
||||
//The following are the fields from CounterpartyTrait, previence just save BankAccount to simulate the counterparty.
|
||||
//The following are the fields from CounterpartyTrait, previous just save BankAccount to simulate the counterparty.
|
||||
//Now we save the real Counterparty data
|
||||
//CP--> CounterParty
|
||||
object CPOtherBankId extends MappedString(this, 36)
|
||||
@ -131,7 +129,6 @@ class MappedTransaction extends LongKeyedMapper[MappedTransaction] with IdPK wit
|
||||
val otherAccount = createCounterparty(Some(dummyOtherBankAccount.metadata))
|
||||
|
||||
Some(new Transaction(
|
||||
transactionUUID.get,
|
||||
theTransactionId,
|
||||
account,
|
||||
otherAccount,
|
||||
|
||||
@ -47,15 +47,18 @@ class MappedTransactionRequest extends LongKeyedMapper[MappedTransactionRequest]
|
||||
object mBody_Value_Amount extends DefaultStringField(this)
|
||||
object mBody_Description extends DefaultStringField(this)
|
||||
// This is the details / body of the request (contains all fields in the body)
|
||||
// Note:this need to be a longer string, defaults is 2000, maybe not enough
|
||||
object mDetails extends DefaultStringField(this)
|
||||
|
||||
//fromAccount fields
|
||||
object mFrom_BankId extends DefaultStringField(this)
|
||||
object mFrom_AccountId extends DefaultStringField(this)
|
||||
|
||||
//toAccount fields
|
||||
object mTo_BankId extends DefaultStringField(this)
|
||||
object mTo_AccountId extends DefaultStringField(this)
|
||||
//toCounterparty fiels
|
||||
|
||||
//toCounterparty fields
|
||||
object mName extends DefaultStringField(this)
|
||||
object mThisBankId extends DefaultStringField(this)
|
||||
object mThisAccountId extends DefaultStringField(this)
|
||||
|
||||
@ -8,9 +8,8 @@ import code.accountholder.AccountHolders
|
||||
import code.model._
|
||||
import code.model.dataAccess._
|
||||
import net.liftweb.common.Box
|
||||
import net.liftweb.mapper.MetaMapper
|
||||
import net.liftweb.mapper.{By, MappedString, MetaMapper}
|
||||
import net.liftweb.util.Props
|
||||
import net.liftweb.mapper.{MappedString, MetaMapper}
|
||||
import net.liftweb.util.Helpers._
|
||||
import code.entitlement.{Entitlement, MappedEntitlement}
|
||||
import code.metadata.counterparties.{CounterpartyTrait, MappedCounterparty, MappedCounterpartyMetadata}
|
||||
@ -74,6 +73,10 @@ trait LocalMappedConnectorTestSetup extends TestConnectorSetupWithStandardPermis
|
||||
.accountLabel(randomString(4)).saveMe
|
||||
}
|
||||
|
||||
override protected def updateAccountCurrency(bankId: BankId, accountId : AccountId, currency : String) : BankAccount = {
|
||||
MappedBankAccount.find(By(MappedBankAccount.bank, bankId.value), By(MappedBankAccount.theAccountId, accountId.value)).get.accountCurrency(currency).saveMe()
|
||||
}
|
||||
|
||||
def addEntitlement(bankId: String, userId: String, roleName: String): Box[Entitlement] = {
|
||||
// Return a Box so we can handle errors later.
|
||||
val addEntitlement = MappedEntitlement.create
|
||||
|
||||
@ -13,6 +13,7 @@ trait TestConnectorSetup {
|
||||
protected def createBank(id : String) : Bank
|
||||
protected def createAccount(bankId: BankId, accountId : AccountId, currency : String) : BankAccount
|
||||
protected def createTransaction(account : BankAccount, startDate : Date, finishDate : Date)
|
||||
protected def updateAccountCurrency(bankId: BankId, accountId : AccountId, currency : String) : BankAccount
|
||||
|
||||
protected def createCounterparty(bankId: String, accountId: String, accountRoutingAddress: String, otherAccountRoutingScheme: String, isBeneficiary: Boolean, counterpartyId: String): CounterpartyTrait
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ package code.api.v1_3_0
|
||||
import java.util.Date
|
||||
|
||||
import code.api.util.APIUtil.OAuth._
|
||||
import code.api.v2_1_0.BranchJsonPost
|
||||
import code.api.v2_1_0.{BranchJsonPost, TransactionRequestCommonBodyJSON}
|
||||
import code.api.{DefaultConnectorTestSetup, DefaultUsers, ServerSetup}
|
||||
import code.bankconnectors.{Connector, OBPQueryParam}
|
||||
import code.branches.Branches.{Branch, BranchId}
|
||||
@ -16,7 +16,7 @@ import code.model.dataAccess.ResourceUser
|
||||
import code.transactionrequests.TransactionRequests._
|
||||
import net.liftweb.common.{Box, Empty, Failure, Full, Loggable}
|
||||
import code.products.Products.{Product, ProductCode}
|
||||
import code.transactionrequests.{TransactionRequestTypeCharge}
|
||||
import code.transactionrequests.TransactionRequestTypeCharge
|
||||
class PhysicalCardsTest extends ServerSetup with DefaultUsers with DefaultConnectorTestSetup {
|
||||
|
||||
implicit val dateFormats = net.liftweb.json.DefaultFormats
|
||||
@ -140,7 +140,14 @@ class PhysicalCardsTest extends ServerSetup with DefaultUsers with DefaultConne
|
||||
status: String, charge: TransactionRequestCharge) : Box[TransactionRequest] = {
|
||||
Failure("not supported")
|
||||
}
|
||||
protected override def createTransactionRequestImpl210(transactionRequestId: TransactionRequestId, transactionRequestType: TransactionRequestType, account: BankAccount, toAccount: BankAccount, toCounterparty: CounterpartyTrait, details: String, status: String, charge: TransactionRequestCharge, chargePolicy: String): Box[TransactionRequest] = {
|
||||
protected override def createTransactionRequestImpl210(transactionRequestId: TransactionRequestId,
|
||||
transactionRequestType: TransactionRequestType,
|
||||
account: BankAccount, toAccount: BankAccount,
|
||||
toCounterparty: CounterpartyTrait,
|
||||
transactionRequestCommonBody: TransactionRequestCommonBodyJSON,
|
||||
details: String, status: String,
|
||||
charge: TransactionRequestCharge,
|
||||
chargePolicy: String): Box[TransactionRequest] = {
|
||||
Failure("not supported")
|
||||
}
|
||||
override def saveTransactionRequestTransactionImpl(transactionRequestId: TransactionRequestId, transactionId: TransactionId) = ???
|
||||
|
||||
@ -45,6 +45,8 @@ class TransactionRequestsTest extends ServerSetupWithTestData with DefaultUsers
|
||||
this.fromCurrency = fromCurrency
|
||||
this.toCurrency = toCurrency
|
||||
this.amt = BigDecimal(amt)
|
||||
updateAccountCurrency(bankId, accountId2, toCurrency)
|
||||
toAccount = getToAccount
|
||||
}
|
||||
|
||||
createAccountAndOwnerView(Some(authuser1), bankId, accountId1, fromCurrency)
|
||||
@ -91,9 +93,9 @@ class TransactionRequestsTest extends ServerSetupWithTestData with DefaultUsers
|
||||
//For Counterpart local mapper, the mOtherAccountRoutingScheme='OBP' and mOtherBankRoutingScheme = 'OBP'
|
||||
val counterPartyCounterparty = createCounterparty(bankId.value, accountId2.value, "IBAN", "OBP", true, UUID.randomUUID.toString);
|
||||
|
||||
var transactionRequestBodySEPA = TransactionRequestDetailsSEPAJSON(bodyValue, IbanJson(counterPartySEPA.otherAccountRoutingAddress), discription, sharedChargePolicy)
|
||||
var transactionRequestBodySEPA = TransactionRequestBodySEPAJSON(bodyValue, IbanJson(counterPartySEPA.otherAccountRoutingAddress), discription, sharedChargePolicy)
|
||||
|
||||
var transactionRequestBodyCounterparty = TransactionRequestDetailsCounterpartyJSON(CounterpartyIdJson(counterPartyCounterparty.counterpartyId), bodyValue, discription, sharedChargePolicy)
|
||||
var transactionRequestBodyCounterparty = TransactionRequestBodyCounterpartyJSON(CounterpartyIdJson(counterPartyCounterparty.counterpartyId), bodyValue, discription, sharedChargePolicy)
|
||||
|
||||
def setAnswerTransactionRequest(challengeId: String = this.challengeId, transRequestId: String = this.transRequestId) = {
|
||||
this.challengeId = challengeId
|
||||
@ -221,6 +223,8 @@ class TransactionRequestsTest extends ServerSetupWithTestData with DefaultUsers
|
||||
var convertedAmount = fx.convert(amt, rate)
|
||||
var fromAccountBalance = getFromAccount.balance
|
||||
var toAccountBalance = getToAccount.balance
|
||||
toAccount = getToAccount
|
||||
fromAccount = getFromAccount
|
||||
|
||||
|
||||
if (finishedTranscation ) {
|
||||
@ -230,14 +234,23 @@ class TransactionRequestsTest extends ServerSetupWithTestData with DefaultUsers
|
||||
fromAccountBalance should equal((beforeFromBalance+amt))
|
||||
And("No transaction, it should be the same as before ")
|
||||
transactionCount(fromAccount, toAccount) should equal(totalTransactionsBefore+2)
|
||||
} else{
|
||||
} else if(transactionRequestTypeInput.equals("SANDBOX_TAN")){
|
||||
Then("check that the balances have been properly decreased/increased (since we handle that logic for sandbox accounts at least) ")
|
||||
fromAccountBalance should equal((beforeFromBalance - amt))
|
||||
And("the account receiving the payment should have a new balance plus the amount paid")
|
||||
toAccountBalance should equal(beforeToBalance + convertedAmount)
|
||||
And("there should now be 2 new transactions in the database (one for the sender, one for the receiver")
|
||||
transactionCount(fromAccount, toAccount) should equal(totalTransactionsBefore + 2)
|
||||
} else{
|
||||
Then("check that the balances have been properly decreased/increased (since we handle that logic for sandbox accounts at least) ")
|
||||
fromAccountBalance should equal((beforeFromBalance - amt))
|
||||
And("the account receiving the payment should have a new balance plus the amount paid")
|
||||
//TODO for now, sepa, counterparty can not clear the toAccount and toAccount Currency so just test the fromAccount
|
||||
//toAccountBalance should equal(beforeToBalance + convertedAmount)
|
||||
And("there should now be 2 new transactions in the database (one for the sender, one for the receiver")
|
||||
transactionCount(fromAccount, toAccount) should equal(totalTransactionsBefore + 2)
|
||||
}
|
||||
|
||||
} else {
|
||||
Then("No transaction, it should be the same as before ")
|
||||
fromAccountBalance should equal((beforeFromBalance))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user