11package code .api .v6_0_0
22
3- import code .api .{ APIFailureNewStyle , DirectLogin , ObpApiFailure }
4- import code .api .v6_0_0 . JSONFactory600
3+ import code .accountattribute . AccountAttributeX
4+ import code .api .{ DirectLogin , ObpApiFailure }
55import code .api .ResourceDocs1_4_0 .SwaggerDefinitionsJSON ._
66import code .api .util .APIUtil ._
7- import code .api .util .ApiRole .{ CanCreateEntitlementAtOneBank , CanReadDynamicResourceDocsAtOneBank , canCreateBank , canCreateRateLimits , canDeleteRateLimits , canReadCallLimits , canUpdateRateLimits }
7+ import code .api .util .ApiRole ._
88import code .api .util .ApiTag ._
99import code .api .util .ErrorMessages .{$UserNotLoggedIn , InvalidDateFormat , InvalidJsonFormat , UnknownError , _ }
1010import code .api .util .FutureUtil .EndpointContext
11- import code .api .util .{APIUtil , ErrorMessages , NewStyle , RateLimitingUtil }
1211import code .api .util .NewStyle .HttpCode
12+ import code .api .util .{APIUtil , ErrorMessages , NewStyle , RateLimitingUtil }
13+ import code .api .v3_0_0 .JSONFactory300
1314import code .api .v4_0_0 .CallLimitPostJsonV400
1415import code .api .v4_0_0 .JSONFactory400 .createCallsLimitJson
15- import code .api .v5_0_0 .{ JSONFactory500 , PostBankJson500 }
16+ import code .api .v5_0_0 .JSONFactory500
1617import code .api .v6_0_0 .JSONFactory600 .{createActiveCallLimitsJsonV600 , createCallLimitJsonV600 , createCurrentUsageJson }
1718import code .bankconnectors .LocalMappedConnectorInternal
1819import code .bankconnectors .LocalMappedConnectorInternal ._
1920import code .entitlement .Entitlement
21+ import code .model ._
2022import code .ratelimiting .RateLimitingDI
2123import code .util .Helper
2224import code .util .Helper .SILENCE_IS_GOLDEN
@@ -25,11 +27,10 @@ import com.github.dwickern.macros.NameOf.nameOf
2527import com .openbankproject .commons .ExecutionContext .Implicits .global
2628import com .openbankproject .commons .model ._
2729import com .openbankproject .commons .util .{ApiVersion , ScannedApiVersion }
28- import net .liftweb .common .{Box , Empty , Full }
30+ import net .liftweb .common .{Empty , Full }
2931import net .liftweb .http .rest .RestHelper
3032
3133import java .text .SimpleDateFormat
32- import java .util .Date
3334import scala .collection .immutable .{List , Nil }
3435import scala .collection .mutable .ArrayBuffer
3536import scala .concurrent .Future
@@ -51,6 +52,102 @@ trait APIMethods600 {
5152 val codeContext = CodeContext (staticResourceDocs, apiRelations)
5253
5354
55+ staticResourceDocs += ResourceDoc (
56+ createTransactionRequestHold,
57+ implementedInApiVersion,
58+ nameOf(createTransactionRequestHold),
59+ " POST" ,
60+ " /banks/BANK_ID/accounts/ACCOUNT_ID/owner/transaction-request-types/HOLD/transaction-requests" ,
61+ " Create Transaction Request (HOLD)" ,
62+ s """
63+ |
64+ |Create a transaction request to move funds from the account to its Holding Account.
65+ |If the Holding Account does not exist, it will be created automatically.
66+ |
67+ | ${transactionRequestGeneralText}
68+ |
69+ """ .stripMargin,
70+ transactionRequestBodyHoldJsonV600,
71+ transactionRequestWithChargeJSON400,
72+ List (
73+ $UserNotLoggedIn ,
74+ $BankNotFound ,
75+ $BankAccountNotFound ,
76+ InsufficientAuthorisationToCreateTransactionRequest ,
77+ InvalidTransactionRequestType ,
78+ InvalidJsonFormat ,
79+ NotPositiveAmount ,
80+ InvalidTransactionRequestCurrency ,
81+ TransactionDisabled ,
82+ UnknownError
83+ ),
84+ List (apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2)
85+ )
86+
87+ lazy val createTransactionRequestHold : OBPEndpoint = {
88+ case " banks" :: BankId (bankId) :: " accounts" :: AccountId (accountId) :: ViewId (viewId) :: " transaction-request-types" ::
89+ " HOLD" :: " transaction-requests" :: Nil JsonPost json -> _ =>
90+ cc => implicit val ec = EndpointContext (Some (cc))
91+ val transactionRequestType = TransactionRequestType (" HOLD" )
92+ LocalMappedConnectorInternal .createTransactionRequest(bankId, accountId, viewId , transactionRequestType, json)
93+ }
94+
95+ // --- GET Holding Account by Parent ---
96+ staticResourceDocs += ResourceDoc (
97+ getHoldingAccountByReleaser,
98+ implementedInApiVersion,
99+ nameOf(getHoldingAccountByReleaser),
100+ " GET" ,
101+ " /banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/holding-accounts" ,
102+ " Get Holding Accounts By Releaser" ,
103+ s """
104+ |
105+ |Return the first Holding Account linked to the given releaser account via account attribute `RELEASER_ACCOUNT_ID`.
106+ |Response is wrapped in a list and includes account attributes.
107+ |
108+ """ .stripMargin,
109+ EmptyBody ,
110+ moderatedCoreAccountsJsonV300,
111+ List (
112+ $UserNotLoggedIn ,
113+ $BankNotFound ,
114+ $BankAccountNotFound ,
115+ $UserNoPermissionAccessView ,
116+ UnknownError
117+ ),
118+ List (apiTagAccount)
119+ )
120+
121+ lazy val getHoldingAccountByReleaser : OBPEndpoint = {
122+ case " banks" :: BankId (bankId) :: " accounts" :: AccountId (accountId) :: ViewId (viewId) :: " holding-accounts" :: Nil JsonGet _ =>
123+ cc => implicit val ec = EndpointContext (Some (cc))
124+ for {
125+ (user @ Full (u), _, _, view, callContext) <- SS .userBankAccountView
126+ // Find accounts by attribute RELEASER_ACCOUNT_ID
127+ (accountIdsBox, callContext) <- AccountAttributeX .accountAttributeProvider.vend.getAccountIdsByParams(bankId, Map (" RELEASER_ACCOUNT_ID" -> List (accountId.value))) map { ids => (ids, callContext) }
128+ accountIds = accountIdsBox.getOrElse(Nil )
129+ // load the first holding account
130+ holdingOpt <- {
131+ def firstHolding (ids : List [String ]): Future [Option [BankAccount ]] = ids match {
132+ case Nil => Future .successful(None )
133+ case id :: tail =>
134+ NewStyle .function.getBankAccount(bankId, AccountId (id), callContext).flatMap { case (acc, cc) =>
135+ if (acc.accountType == " HOLDING" ) Future .successful(Some (acc)) else firstHolding(tail)
136+ }
137+ }
138+ firstHolding(accountIds)
139+ }
140+ holding <- NewStyle .function.tryons($BankAccountNotFound , 404 , callContext) { holdingOpt.get }
141+ moderatedAccount <- Future { holding.moderatedBankAccount(view, BankIdAccountId (holding.bankId, holding.accountId), user, callContext) } map {
142+ x => unboxFullOrFail(x, callContext, UnknownError )
143+ }
144+ (attributes, callContext) <- NewStyle .function.getAccountAttributesByAccount(bankId, holding.accountId, callContext)
145+ } yield {
146+ val accountsJson = JSONFactory300 .createFirehoseCoreBankAccountJSON(List (moderatedAccount), Some (attributes))
147+ (accountsJson, HttpCode .`200`(callContext))
148+ }
149+ }
150+
54151 staticResourceDocs += ResourceDoc (
55152 getCurrentCallsLimit,
56153 implementedInApiVersion,
0 commit comments