diff --git a/src/main/scala/code/api/STET/v1_4/AISPApi.scala b/src/main/scala/code/api/STET/v1_4/AISPApi.scala index 7cf0bcbe9..ecdc37944 100644 --- a/src/main/scala/code/api/STET/v1_4/AISPApi.scala +++ b/src/main/scala/code/api/STET/v1_4/AISPApi.scala @@ -22,6 +22,7 @@ import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future import code.api.STET.v1_4.OBP_STET_1_4 import code.api.util.ApiTag +import code.api.STET.v1_4.JSONFactory_STET_1_4._ object APIMethods_AISPApi extends RestHelper { val apiVersion = OBP_STET_1_4.apiVersion @@ -117,7 +118,47 @@ The TPP sends a request to the ASPSP for retrieving the list of the PSU payment """, json.parse(""""""), - json.parse(""""""), + json.parse("""{ + | "accounts": [ + | { + | "resourceId": "Alias1", + | "bicFi": "BNKAFRPPXXX", + | "name": "Compte de Mr et Mme Dupont", + | "usage": "PRIV", + | "cashAccountType": "CACC", + | "currency": "EUR", + | "psuStatus": "Co-account Holder", + | "_links": { + | "balances": { + | "href": "v1/accounts/Alias1/balances" + | }, + | "transactions": { + | "href": "v1/accounts/Alias1/transactions" + | } + | } + | } + | ], + | "_links": { + | "self": { + | "href": "v1/accounts?page=2" + | }, + | "first": { + | "href": "v1/accounts" + | }, + | "last": { + | "href": "v1/accounts?page=last", + | "templated": true + | }, + | "next": { + | "href": "v1/accounts?page=3", + | "templated": true + | }, + | "prev": { + | "href": "v1/accounts", + | "templated": true + | } + | } + |}""".stripMargin), List(UserNotLoggedIn, UnknownError), Catalogs(notCore, notPSD2, notOBWG), ApiTag("AISP") :: apiTagMockedData :: Nil @@ -125,12 +166,23 @@ The TPP sends a request to the ASPSP for retrieving the list of the PSU payment lazy val accountsGet : OBPEndpoint = { case "accounts" :: Nil JsonGet _ => { - cc => + cc => for { (Full(u), callContext) <- authorizeEndpoint(UserNotLoggedIn, cc) - } yield { - (NotImplemented, callContext) - } + + _ <- Helper.booleanToFuture(failMsg= DefaultBankIdNotSet ) {defaultBankId != "DEFAULT_BANK_ID_NOT_SET"} + + bankId = BankId(defaultBankId) + + (_, callContext) <- NewStyle.function.getBank(bankId, callContext) + + availablePrivateAccounts <- Views.views.vend.getPrivateBankAccountsFuture(u, bankId) + + Full(accounts) <- {Connector.connector.vend.getBankAccountsFuture(availablePrivateAccounts,callContext)} + + } yield { + (createTransactionListJSON(accounts), callContext) + } } } diff --git a/src/main/scala/code/api/STET/v1_4/JSONFactory_SETE_1_4.scala b/src/main/scala/code/api/STET/v1_4/JSONFactory_SETE_1_4.scala new file mode 100644 index 000000000..cfc589bd5 --- /dev/null +++ b/src/main/scala/code/api/STET/v1_4/JSONFactory_SETE_1_4.scala @@ -0,0 +1,162 @@ +package code.api.STET.v1_4 + +import java.util.Date + +import code.api.util.APIUtil +import code.api.v2_1_0.IbanJson +import code.model.{BankAccount, CoreAccount, ModeratedBankAccount, ModeratedTransaction} +import code.transactionrequests.TransactionRequests.TransactionRequest + +import scala.collection.immutable.List + +object JSONFactory_STET_1_4 { + + implicit val formats = net.liftweb.json.DefaultFormats + + trait links + case class Balances(balances: String) extends links + case class Transactions(trasactions: String) extends links + case class ViewAccount(viewAccount: String) extends links + case class CoreAccountJsonV1( + resourceId: String, + bicFi: String, + currency: String, + accountType: String, + cashAccountType: String, + name: String, + usage: String="PRIV", + psuStatus: String="Co-account Holder", + ) + case class Href(href: String) extends links + + case class Self(self: Href= Href("v1/accounts?page=2")) extends links + + case class First(self: Href= Href("v1/accounts")) extends links + + case class Last( + href: Href= Href("v1/accounts?page=last"), + templated: Boolean = true + ) extends links + + case class Next( + href: Href= Href("v1/accounts?page=3"), + templated: Boolean = true + ) extends links + + case class Prev( + href: Href= Href("v1/accounts"), + templated: Boolean = true + ) extends links + + case class AccountsJsonV1( + accounts: List[CoreAccountJsonV1], + _links: List[links] + ) + + case class AmountOfMoneyV1( + currency : String, + content : String + ) + case class ClosingBookedBody( + amount : AmountOfMoneyV1, + date: String //eg: “2017-10-25”, this is not a valid datetime (not java.util.Date) + ) + case class ExpectedBody( + amount : AmountOfMoneyV1, + lastActionDateTime: Date + ) + case class AccountBalance( + closingBooked: ClosingBookedBody, + expected: ExpectedBody + ) + case class AccountBalances(`balances`: List[AccountBalance]) + + case class TransactionsJsonV1( + transactions_booked: List[TransactionJsonV1], + transactions_pending: List[TransactionJsonV1], + _links: List[ViewAccount] + ) + + case class TransactionJsonV1( + transactionId: String, + creditorName: String, + creditorAccount: IbanJson, + amount: AmountOfMoneyV1, + bookingDate: Date, + valueDate: Date, + remittanceInformationUnstructured: String + ) + + def createTransactionListJSON(accounts: List[BankAccount]): AccountsJsonV1 = + AccountsJsonV1( + accounts =accounts.map( + account => CoreAccountJsonV1( + resourceId = account.accountId.value, + bicFi = account.swift_bic.getOrElse(account.iban.getOrElse("")), + currency = account.currency, + accountType = account.accountType, + cashAccountType = "CACC", + name = account.accountHolder) + ), + _links=List(Self(), First(), Last(), Next(), Prev()) + ) + + def createAccountBalanceJSON(moderatedAccount: ModeratedBankAccount, transactionRequests: List[TransactionRequest]) = { + // get the latest end_date of `COMPLETED` transactionRequests + val latestCompletedEndDate = transactionRequests.sortBy(_.end_date).reverse.filter(_.status == "COMPLETED").map(_.end_date).headOption.getOrElse(null) + + //get the latest end_date of !`COMPLETED` transactionRequests + val latestUncompletedEndDate = transactionRequests.sortBy(_.end_date).reverse.filter(_.status != "COMPLETED").map(_.end_date).headOption.getOrElse(null) + + // get the SUM of the amount of all !`COMPLETED` transactionRequests + val sumOfAllUncompletedTransactionrequests = transactionRequests.filter(_.status != "COMPLETED").map(_.body.value.amount).map(BigDecimal(_)).sum + // sum of the unCompletedTransactions and the account.balance is the current expectd amount: + val sumOfAll = (BigDecimal(moderatedAccount.balance) + sumOfAllUncompletedTransactionrequests).toString() + + AccountBalances( + AccountBalance( + closingBooked = ClosingBookedBody( + amount = AmountOfMoneyV1(currency = moderatedAccount.currency.getOrElse(""), content = moderatedAccount.balance), + date = APIUtil.DateWithDayFormat.format(latestCompletedEndDate) + ), + expected = ExpectedBody( + amount = AmountOfMoneyV1(currency = moderatedAccount.currency.getOrElse(""), + content = sumOfAll), + lastActionDateTime = latestUncompletedEndDate) + ) :: Nil + ) + } + + def createTransactionJSON(transaction : ModeratedTransaction) : TransactionJsonV1 = { + TransactionJsonV1( + transactionId = transaction.id.value, + creditorName = "", + creditorAccount = IbanJson(APIUtil.stringOptionOrNull(transaction.bankAccount.get.iban)), + amount = AmountOfMoneyV1(APIUtil.stringOptionOrNull(transaction.currency), transaction.amount.get.toString()), + bookingDate = transaction.startDate.get, + valueDate = transaction.finishDate.get, + remittanceInformationUnstructured = APIUtil.stringOptionOrNull(transaction.description) + ) + } + + def createTransactionFromRequestJSON(transactionRequest : TransactionRequest) : TransactionJsonV1 = { + TransactionJsonV1( + transactionId = transactionRequest.id.value, + creditorName = transactionRequest.name, + creditorAccount = IbanJson(transactionRequest.from.account_id), + amount = AmountOfMoneyV1(transactionRequest.charge.value.currency, transactionRequest.charge.value.amount), + bookingDate = transactionRequest.start_date, + valueDate = transactionRequest.end_date, + remittanceInformationUnstructured = transactionRequest.body.description + ) + } + + def createTransactionsJson(transactions: List[ModeratedTransaction], transactionRequests: List[TransactionRequest]) : TransactionsJsonV1 = { + TransactionsJsonV1( + transactions_booked =transactions.map(createTransactionJSON), + transactions_pending =transactionRequests.filter(_.status!="COMPLETED").map(createTransactionFromRequestJSON), + _links = ViewAccount(s"/${OBP_STET_1_4.version}/accounts/${transactionRequests.head.from.account_id}/balances")::Nil + ) + } + +}