FINERACT-706: Interoperation Mojaloop integration 1.0.1
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
//Request URI:
|
||||
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/bulkTransactions
|
||||
|
||||
//Response Body:
|
||||
{
|
||||
"bulkTransactionId": "11436b17-c690-4a30-8505-42a2c4eafb9d" // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//Request URI:
|
||||
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/bulkTransactions
|
||||
//GET paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/bulkTransactions/11436b17-c690-4a30-8505-42a2c4eafb9d
|
||||
|
||||
//Response URI:
|
||||
//PUT <FSPIOP-Callback>/interoperation/bulkTransactions/11436b17-c690-4a30-8505-42a2c4eafb9d
|
||||
|
||||
//Header:
|
||||
//X-Tenant-Identifier: T111
|
||||
|
||||
//Response Body:
|
||||
{
|
||||
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
|
||||
"completedTimestamp": "2017-11-16T04:15:35.513+01:00", // optional, ISO 8601
|
||||
"bulkTransferState": "COMPLETED", // mandatory, Enum of String(1..32): RECEIVED, PENDING, ACCEPTED, PROCESSING, COMPLETED, REJECTED
|
||||
"individualTransferResults": [ // mandatory, (1..1000)
|
||||
{
|
||||
"transferId": "11436b17-c690-4a30-8505-42a2c4eafb9d", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
"completedTimestamp": "2017-11-16T04:15:35.513+01:00", // optional, ISO 8601
|
||||
"transferState": "COMMITTED"// mandatory, Enum of String(1..32): RECEIVED, RESERVED, COMMITTED, ABORTED
|
||||
},
|
||||
{
|
||||
"transferId": "11436b17-c690-4a30-8505-42a2c4eafb9d", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
"completedTimestamp": "2017-11-16T04:15:35.513+01:00", // optional, ISO 8601
|
||||
"transferState": "COMMITTED"// mandatory, Enum of String(1..32): RECEIVED, RESERVED, COMMITTED, ABORTED
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
//Request URI:
|
||||
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/bulkTransactions
|
||||
// HTTP/1.1
|
||||
|
||||
//Request Header:
|
||||
//Accept: application/vnd.interoperability.quotes+json;version=1
|
||||
//Content-Type: application/vnd.interoperability.quotes+json;version=1.0
|
||||
//Content-Length: 975
|
||||
//Date: Tue, 15 Nov 2017 10: 13:40 GMT
|
||||
//Origin: http://www.example.com
|
||||
//X-Tenant-Identifier: T111
|
||||
|
||||
//Request Body:
|
||||
{
|
||||
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
|
||||
"payer": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "something" // optional, String(1..128)
|
||||
}
|
||||
},
|
||||
"amountType": "RECEIVE", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
|
||||
"individualTransfers": [ // mandatory, (1..1000)
|
||||
{
|
||||
"payee": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "IN93116000060000000012345671", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "nothing" // optional, String(1..128)
|
||||
}
|
||||
},
|
||||
"amount": { // mandatory
|
||||
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
|
||||
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
|
||||
}
|
||||
},
|
||||
{
|
||||
"payee": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "IN93116000060000000012345672", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "nothing" // optional, String(1..128)
|
||||
}
|
||||
},
|
||||
"amount": { // mandatory
|
||||
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
|
||||
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
|
||||
}
|
||||
}
|
||||
],
|
||||
"transactionType": { // mandatory
|
||||
"scenario": "TRANSFER", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
|
||||
"initiator": "PAYER", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
|
||||
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
|
||||
},
|
||||
"note": "From Mats", // optional, String(1..128)
|
||||
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
//Request URI:
|
||||
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/transactions
|
||||
// HTTP/1.1
|
||||
|
||||
//Request Header:
|
||||
//Accept: application/vnd.interoperability.quotes+json;version=1
|
||||
//Content-Type: application/vnd.interoperability.quotes+json;version=1.0
|
||||
//Content-Length: 975
|
||||
//Date: Tue, 15 Nov 2017 10: 13:40 GMT
|
||||
//Origin: http://www.example.com
|
||||
//FSPIOP-Callback: http://www.client-server.com/demo
|
||||
//FSPIOP-Notification: http://www.client-server.com/demo
|
||||
//X-Tenant-Identifier: T111
|
||||
|
||||
//Request Body:
|
||||
{
|
||||
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
|
||||
"payee": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "something" // optional, String(1..128)
|
||||
},
|
||||
"merchantClassificationCode": "" // optional, String(1..4 digits)
|
||||
},
|
||||
"payer": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "IN4550000000058398257466", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "nothing", // optional, String(1..128)
|
||||
"fspId": "BankNrOne" // optional, String(1..32)
|
||||
}
|
||||
},
|
||||
"amountType": "RECEIVE", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
|
||||
"amount": { // mandatory
|
||||
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
|
||||
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
|
||||
},
|
||||
"transactionType": { // mandatory
|
||||
"scenario": "PAYMENT", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
|
||||
"initiator": "PAYER", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
|
||||
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
|
||||
},
|
||||
"note": "From Mats", // optional, String(1..128)
|
||||
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
//Request URI:
|
||||
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/transactions
|
||||
// HTTP/1.1
|
||||
|
||||
//Request Header:
|
||||
//Accept: application/vnd.interoperability.quotes+json;version=1
|
||||
//Content-Type: application/vnd.interoperability.quotes+json;version=1.0
|
||||
//Content-Length: 975
|
||||
//Date: Tue, 15 Nov 2017 10: 13:40 GMT
|
||||
//Origin: http://www.example.com
|
||||
//X-Tenant-Identifier: T111
|
||||
|
||||
//Request Body:
|
||||
{
|
||||
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
|
||||
"payee": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "something" // optional, String(1..128)
|
||||
}
|
||||
},
|
||||
"payer": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "MSISDN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "+12345678901", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "nothing" // optional, String(1..128)
|
||||
}
|
||||
},
|
||||
"amountType": "SEND", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
|
||||
"amount": { // mandatory
|
||||
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
|
||||
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
|
||||
},
|
||||
"transactionType": { // mandatory
|
||||
"scenario": "TRANSFER", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
|
||||
"initiator": "PAYEE", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
|
||||
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
|
||||
},
|
||||
"note": "From Mats", // optional, String(1..128)
|
||||
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
//Request URI:
|
||||
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/transactions
|
||||
// HTTP/1.1
|
||||
|
||||
//Request Header:
|
||||
//Accept: application/vnd.interoperability.quotes+json;version=1
|
||||
//Content-Type: application/vnd.interoperability.quotes+json;version=1.0
|
||||
//Content-Length: 975
|
||||
//Date: Tue, 15 Nov 2017 10: 13:40 GMT
|
||||
//Origin: http://www.example.com
|
||||
//X-Tenant-Identifier: T111
|
||||
|
||||
//Request Body:
|
||||
{
|
||||
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
|
||||
"payee": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "MSISDN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "+12345678901", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "nothing" // optional, String(1..128)
|
||||
}
|
||||
},
|
||||
"payer": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "something" // optional, String(1..128)
|
||||
}
|
||||
},
|
||||
"amountType": "SEND", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
|
||||
"amount": { // mandatory
|
||||
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
|
||||
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
|
||||
},
|
||||
"transactionType": { // mandatory
|
||||
"scenario": "TRANSFER", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
|
||||
"initiator": "PAYER", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
|
||||
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
|
||||
},
|
||||
"note": "From Mats", // optional, String(1..128)
|
||||
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
//Request URI:
|
||||
//POST <FSPIOP-Notification>/channel/quotes/notification
|
||||
//HTTP/1.1
|
||||
//X-Tenant-Identifier: T111
|
||||
|
||||
//Request Body:
|
||||
{
|
||||
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
|
||||
"transactionId": "11436b17-c690-4a30-8505-42a2c4eafb9d", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
"requestId": "18e43330-187e-11e9-ab14-d663bd873d93", // optional, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
"quoteId": "61058cea-187e-11e9-ab14-d663bd873d93", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
"payee": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "MSISDN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "12345678901", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "nothing", // optional, String(1..128)
|
||||
"fspId": "BankNrOne" // optional, String(1..32)
|
||||
}
|
||||
},
|
||||
"payer": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "something" // optional, String(1..128)
|
||||
},
|
||||
"name": "" // optional, String(1..128) ^(?!\s*$)[\w .,'-]{1,128}$
|
||||
},
|
||||
"amountType": "SEND", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
|
||||
"amount": {
|
||||
"amount": "100",
|
||||
"currency": "USD"
|
||||
},
|
||||
"transferAmount": {
|
||||
"amount": "99",
|
||||
"currency": "USD"
|
||||
},
|
||||
"fspFee": { // optional
|
||||
"amount": "1", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
|
||||
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
|
||||
},
|
||||
"fspCommission": { // optional
|
||||
"amount": "0", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
|
||||
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
|
||||
},
|
||||
"transactionRole": "PAYEE",
|
||||
"transactionType": { // mandatory
|
||||
"scenario": "TRANSFER", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
|
||||
"initiator": "PAYER", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
|
||||
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
|
||||
},
|
||||
"note": "From Mats", // optional, String(1..128)
|
||||
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//Request URI:
|
||||
//POST <FSPIOP-Notification>/channel/quotes/notification
|
||||
// HTTP/1.1
|
||||
//X-Tenant-Identifier: T111
|
||||
|
||||
//Request Body:
|
||||
{
|
||||
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
|
||||
"transactionId": "11436b17-c690-4a30-8505-42a2c4eafb9d", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
"requestId": "18e43330-187e-11e9-ab14-d663bd873d93", // optional, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
"quoteId": "61058cea-187e-11e9-ab14-d663bd873d93", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
"payee": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "MSISDN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "+12345678901", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "nothing", // optional, String(1..128)
|
||||
"fspId": "BankNrOne" // optional, String(1..32)
|
||||
},
|
||||
"name": "" // optional, String(1..128) ^(?!\s*$)[\w .,'-]{1,128}$
|
||||
},
|
||||
"payer": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "something" // optional, String(1..128)
|
||||
}
|
||||
},
|
||||
"amountType": "SEND", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
|
||||
"amount": { // mandatory
|
||||
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
|
||||
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
|
||||
},
|
||||
"transferAmount": {
|
||||
"amount": "99",
|
||||
"currency": "USD"
|
||||
},
|
||||
"payeeReceiveAmount": {
|
||||
"amount": "100",
|
||||
"currency": "USD"
|
||||
},
|
||||
"fspFee": { // optional
|
||||
"amount": "1", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
|
||||
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
|
||||
},
|
||||
"fspCommission": { // optional
|
||||
"amount": "0", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
|
||||
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
|
||||
},
|
||||
"transactionRole": "PAYER",
|
||||
"transactionType": { // mandatory
|
||||
"scenario": "TRANSFER", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
|
||||
"initiator": "PAYEE", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
|
||||
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
|
||||
},
|
||||
"note": "From Mats", // optional, String(1..128)
|
||||
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//Request URI:
|
||||
//POST <FSPIOP-Notification>/channel/transactions/{transactionId}/notification
|
||||
// HTTP/1.1
|
||||
//X-Tenant-Identifier: T111
|
||||
|
||||
//Request Body:
|
||||
{
|
||||
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
|
||||
"transactionId": "11436b17-c690-4a30-8505-42a2c4eafb9d", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
"requestId": "18e43330-187e-11e9-ab14-d663bd873d93", // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
"payee": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "MSISDN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "+12345678901", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "nothing", // optional, String(1..128)
|
||||
"fspId": "BankNrOne" // optional, String(1..32)
|
||||
},
|
||||
"name": "" // optional, String(1..128) ^(?!\s*$)[\w .,'-]{1,128}$
|
||||
},
|
||||
"payer": { // mandatory
|
||||
"partyIdInfo": { // mandatory
|
||||
"partyIdType": "IBAN", // mandatory, constant, type: Enum of String(1..32): MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
|
||||
"partyIdentifier": "IN93116000060000000012345676", // mandatory, String(1..128)
|
||||
"partySubIdOrType": "something" // optional, String(1..128)
|
||||
}
|
||||
},
|
||||
"amountType": "SEND", // mandatory, constant, type: Enum of String(1..32): SEND, RECEIVE
|
||||
"amount": { // mandatory
|
||||
"amount": "100", // mandatory, Number(22, 4) ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$
|
||||
"currency": "IDR" // mandatory, ISO 4217 (Rupee)
|
||||
},
|
||||
"transactionType": { // mandatory
|
||||
"scenario": "TRANSFER", // mandatory, constant, type: Enum of String(1..32): DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
|
||||
"initiator": "PAYEE", // mandatory, constant, type: Enum of String(1..32): PAYER, PAYEE
|
||||
"initiatorType": "CONSUMER" // mandatory, constant, type: Enum of String(1..32): CONSUMER, AGENT, BUSINESS, DEVICE
|
||||
},
|
||||
"note": "From Mats", // optional, String(1..128)
|
||||
"expiration": "2017-11-15T22:17:28.985-01:00" // optional, ISO 8601
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
//Request URI:
|
||||
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/transactions
|
||||
|
||||
//Response Body:
|
||||
{
|
||||
"transactionId": "11436b17-c690-4a30-8505-42a2c4eafb9d" // mandatory, UUID String(36) ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
//Request URI:
|
||||
//POST paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/transactions
|
||||
//GET paymenthub-schema:// payment-hub-domain:payment-hub-port/channel/transactions/11436b17-c690-4a30-8505-42a2c4eafb9d
|
||||
|
||||
//Response URI:
|
||||
//PUT <FSPIOP-Callback>/interoperation/transactions/11436b17-c690-4a30-8505-42a2c4eafb9d
|
||||
|
||||
//Header:
|
||||
//X-Tenant-Identifier: T111
|
||||
|
||||
//Response Body:
|
||||
{
|
||||
"clientRefId": "0f4f8eb4-1d83-11e9-ab14-d663bd873d93", // String(1..36)
|
||||
"completedTimestamp": "2017-11-16T04:15:35.513+01:00", // optional, ISO 8601
|
||||
"transferState": "COMMITTED" // mandatory, Enum of String(1..32): RECEIVED, RESERVED, COMMITTED, ABORTED
|
||||
}
|
||||
@@ -134,6 +134,7 @@ rat {
|
||||
'**/docs/system-architecture/**/*.xml',
|
||||
'**/bootstrap-3.0.0/assets/application.js',
|
||||
'**/system-architecture/js/plugins.js',
|
||||
'**/docs/interoperation/specification/json/*.json',
|
||||
|
||||
//Apache License
|
||||
'**/bootstrap-3.0.0/assets/less.js',
|
||||
|
||||
@@ -94,7 +94,8 @@ dependencies {
|
||||
|
||||
[group: 'io.swagger', name: 'swagger-jersey-jaxrs', version: '1.5.15'],
|
||||
[group: 'org.springframework', name:'spring-jms'],
|
||||
[group: 'org.apache.activemq', name: 'activemq-broker']
|
||||
[group: 'org.apache.activemq', name: 'activemq-broker'],
|
||||
[group: 'javax.validation', name: 'validation-api', version: '2.0.0.Final']
|
||||
)
|
||||
|
||||
testCompile 'junit:junit:4.11',
|
||||
|
||||
@@ -93,7 +93,8 @@ dependencies {
|
||||
|
||||
[group: 'io.swagger', name: 'swagger-jersey-jaxrs', version: '1.5.15'],
|
||||
[group: 'org.springframework', name:'spring-jms'],
|
||||
[group: 'org.apache.activemq', name: 'activemq-broker']
|
||||
[group: 'org.apache.activemq', name: 'activemq-broker'],
|
||||
[group: 'javax.validation', name: 'validation-api', version: '2.0.0.Final']
|
||||
)
|
||||
|
||||
testCompile 'junit:junit:4.11',
|
||||
|
||||
+10
-1
@@ -46,7 +46,9 @@ import com.jayway.restassured.specification.ResponseSpecification;
|
||||
@SuppressWarnings("unchecked")
|
||||
public class Utils {
|
||||
|
||||
public static final String TENANT_IDENTIFIER = "tenantIdentifier=default";
|
||||
public static final String TENANT_PARAM_NAME = "tenantIdentifier";
|
||||
public static final String DEFAULT_TENANT = "default";
|
||||
public static final String TENANT_IDENTIFIER = TENANT_PARAM_NAME + '=' + DEFAULT_TENANT;
|
||||
|
||||
public static final String TENANT_TIME_ZONE = "Asia/Kolkata";
|
||||
|
||||
@@ -113,6 +115,13 @@ public class Utils {
|
||||
return (T) from(json).get(jsonAttributeToGetBack);
|
||||
}
|
||||
|
||||
public static <T> T performServerDelete(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||
final String deleteURL, final String jsonBodyToSend, final String jsonAttributeToGetBack) {
|
||||
final String json = given().spec(requestSpec).body(jsonBodyToSend).expect().spec(responseSpec).log().ifError().when()
|
||||
.delete(deleteURL).andReturn().asString();
|
||||
return (T) (jsonAttributeToGetBack == null ? json : from(json).get(jsonAttributeToGetBack));
|
||||
}
|
||||
|
||||
public static String convertDateToURLFormat(final String dateToBeConvert) {
|
||||
final SimpleDateFormat oldFormat = new SimpleDateFormat("dd MMMMMM yyyy", Locale.US);
|
||||
final SimpleDateFormat newFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
|
||||
+15
-14
@@ -27,6 +27,7 @@ import org.apache.fineract.integrationtests.common.Utils;
|
||||
import com.google.gson.Gson;
|
||||
import com.jayway.restassured.specification.RequestSpecification;
|
||||
import com.jayway.restassured.specification.ResponseSpecification;
|
||||
import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public class ChargesHelper {
|
||||
@@ -87,24 +88,20 @@ public class ChargesHelper {
|
||||
}
|
||||
|
||||
public static String getSavingsActivationFeeJSON() {
|
||||
final HashMap<String, Object> map = populateDefaultsForSavings();
|
||||
map.put("chargeTimeType", CHARGE_SAVINGS_ACTIVATION_FEE);
|
||||
String chargesCreateJson = new Gson().toJson(map);
|
||||
System.out.println(chargesCreateJson);
|
||||
return chargesCreateJson;
|
||||
return getSavingsJSON(amount, currencyCode, ChargeTimeType.SAVINGS_ACTIVATION);
|
||||
}
|
||||
|
||||
public static String getSavingsNoActivityFeeJSON() {
|
||||
final HashMap<String, Object> map = populateDefaultsForSavings();
|
||||
map.put("chargeTimeType", CHARGE_SAVINGS_NO_ACTIVITY_FEE);
|
||||
String chargesCreateJson = new Gson().toJson(map);
|
||||
System.out.println(chargesCreateJson);
|
||||
return chargesCreateJson;
|
||||
return getSavingsJSON(amount, currencyCode, ChargeTimeType.SAVINGS_NOACTIVITY_FEE);
|
||||
}
|
||||
|
||||
public static String getSavingsWithdrawalFeeJSON() {
|
||||
final HashMap<String, Object> map = populateDefaultsForSavings();
|
||||
map.put("chargeTimeType", CHARGE_WITHDRAWAL_FEE);
|
||||
return getSavingsJSON(amount, currencyCode, ChargeTimeType.WITHDRAWAL_FEE);
|
||||
}
|
||||
|
||||
public static String getSavingsJSON(String amount, String currencyCode, ChargeTimeType timeType) {
|
||||
final HashMap<String, Object> map = populateDefaultsForSavings(amount.toString(), currencyCode);
|
||||
map.put("chargeTimeType", timeType.getValue());
|
||||
String chargesCreateJson = new Gson().toJson(map);
|
||||
System.out.println(chargesCreateJson);
|
||||
return chargesCreateJson;
|
||||
@@ -147,12 +144,16 @@ public class ChargesHelper {
|
||||
}
|
||||
|
||||
public static HashMap<String, Object> populateDefaultsForSavings() {
|
||||
return populateDefaultsForSavings(amount, currencyCode);
|
||||
}
|
||||
|
||||
public static HashMap<String, Object> populateDefaultsForSavings(String amount, String currencyCode) {
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("active", ChargesHelper.active);
|
||||
map.put("amount", ChargesHelper.amount);
|
||||
map.put("amount", amount);
|
||||
map.put("chargeAppliesTo", ChargesHelper.CHARGE_APPLIES_TO_SAVINGS);
|
||||
map.put("chargeCalculationType", ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT);
|
||||
map.put("currencyCode", ChargesHelper.currencyCode);
|
||||
map.put("currencyCode", currencyCode);
|
||||
map.put("locale", CommonConstants.locale);
|
||||
map.put("monthDayFormat", ChargesHelper.monthDayFormat);
|
||||
map.put("name", Utils.randomNameGenerator("Charge_Savings_", 6));
|
||||
|
||||
+21
-4
@@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
@@ -102,9 +103,21 @@ public class SavingsAccountHelper {
|
||||
}
|
||||
|
||||
public Integer applyForSavingsApplicationOnDate(final Integer ID, final Integer savingsProductID, final String accountType,
|
||||
final String submittedOnDate) {
|
||||
final String submittedOnDate) {
|
||||
return applyForSavingsApplicationOnDate(ID, savingsProductID, accountType, null, false, submittedOnDate);
|
||||
}
|
||||
|
||||
public Integer applyForSavingsApplicationWithExternalId(final Integer ID, final Integer savingsProductID, final String accountType,
|
||||
String externalId, boolean withdrawalFeeForTransfers) {
|
||||
return applyForSavingsApplicationOnDate(ID, savingsProductID, accountType, externalId, withdrawalFeeForTransfers, CREATED_DATE);
|
||||
}
|
||||
|
||||
public Integer applyForSavingsApplicationOnDate(final Integer ID, final Integer savingsProductID, final String accountType,
|
||||
String externalId, boolean withdrawalFeeForTransfers, final String submittedOnDate) {
|
||||
System.out.println("--------------------------------APPLYING FOR SAVINGS APPLICATION--------------------------------");
|
||||
final String savingsApplicationJSON = new SavingsApplicationTestBuilder() //
|
||||
.withExternalId(externalId) //
|
||||
.withWithdrawalFeeForTransfers(withdrawalFeeForTransfers) //
|
||||
.withSubmittedOnDate(submittedOnDate) //
|
||||
.build(ID.toString(), savingsProductID.toString(), accountType);
|
||||
return Utils.performServerPost(this.requestSpec, this.responseSpec, SAVINGS_ACCOUNT_URL + "?" + Utils.TENANT_IDENTIFIER,
|
||||
@@ -247,9 +260,13 @@ public class SavingsAccountHelper {
|
||||
}
|
||||
|
||||
public Integer addChargesForSavings(final Integer savingsId, final Integer chargeId, boolean addDueDate) {
|
||||
return addChargesForSavings(savingsId, chargeId, addDueDate, BigDecimal.valueOf(100));
|
||||
}
|
||||
|
||||
public Integer addChargesForSavings(final Integer savingsId, final Integer chargeId, boolean addDueDate, BigDecimal amount) {
|
||||
System.out.println("--------------------------------- ADD CHARGES FOR SAVINGS --------------------------------");
|
||||
return (Integer) performSavingActions(SAVINGS_ACCOUNT_URL + "/" + savingsId + "/charges?" + Utils.TENANT_IDENTIFIER,
|
||||
getPeriodChargeRequestJSON(chargeId, addDueDate), CommonConstants.RESPONSE_RESOURCE_ID);
|
||||
getPeriodChargeRequestJSON(chargeId, addDueDate, amount), CommonConstants.RESPONSE_RESOURCE_ID);
|
||||
}
|
||||
|
||||
public Integer payCharge(final Integer chargeId, final Integer savingsId, String amount, String dueDate) {
|
||||
@@ -561,10 +578,10 @@ public class SavingsAccountHelper {
|
||||
getCloseAccountPostInterestJSON(withdrawBalance, closedOnDate), jsonAttributeToGetBack);
|
||||
}
|
||||
|
||||
private String getPeriodChargeRequestJSON(Integer chargeId, boolean addDueDate) {
|
||||
private String getPeriodChargeRequestJSON(Integer chargeId, boolean addDueDate, BigDecimal amount) {
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("chargeId", chargeId);
|
||||
map.put("amount", 100);
|
||||
map.put("amount", amount);
|
||||
map.put("feeOnMonthDay", "15 January");
|
||||
map.put("locale", CommonConstants.locale);
|
||||
map.put("monthDayFormat", "dd MMMM");
|
||||
|
||||
+15
@@ -29,6 +29,9 @@ public class SavingsApplicationTestBuilder {
|
||||
|
||||
private String submittedOnDate = "";
|
||||
|
||||
private String externalId;
|
||||
private boolean withdrawalFeeForTransfers;
|
||||
|
||||
private HashMap<String, String> addParams = null;
|
||||
|
||||
private List<HashMap<String, Object>> datatables = null;
|
||||
@@ -45,6 +48,8 @@ public class SavingsApplicationTestBuilder {
|
||||
map.put("productId", savingsProductId);
|
||||
map.put("locale", LOCALE);
|
||||
map.put("submittedOnDate", this.submittedOnDate);
|
||||
map.put("externalId", this.externalId);
|
||||
map.put("withdrawalFeeForTransfers", this.withdrawalFeeForTransfers);
|
||||
if (addParams != null && addParams.size() > 0) {
|
||||
map.putAll(addParams);
|
||||
}
|
||||
@@ -61,6 +66,16 @@ public class SavingsApplicationTestBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SavingsApplicationTestBuilder withExternalId(final String externalId) {
|
||||
this.externalId = externalId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SavingsApplicationTestBuilder withWithdrawalFeeForTransfers(boolean withdrawalFeeForTransfers) {
|
||||
this.withdrawalFeeForTransfers = withdrawalFeeForTransfers;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SavingsApplicationTestBuilder withParams(HashMap<String, String> params) {
|
||||
this.addParams = params;
|
||||
return this;
|
||||
|
||||
+12
-1
@@ -20,6 +20,7 @@ package org.apache.fineract.integrationtests.common.savings;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -78,7 +79,7 @@ public class SavingsProductHelper {
|
||||
private String lockinPeriodFrequency = "0";
|
||||
private String withdrawalFeeForTransfers = "true";
|
||||
private String lockingPeriodFrequencyType = DAYS;
|
||||
private final String currencyCode = USD;
|
||||
private String currencyCode = USD;
|
||||
private final String interestCalculationDaysInYearType = DAYS_365;
|
||||
private Account[] accountList = null;
|
||||
private String minBalanceForInterestCalculation = null;
|
||||
@@ -231,6 +232,16 @@ public class SavingsProductHelper {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SavingsProductHelper withCurrencyCode(String currency) {
|
||||
this.currencyCode = currency;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SavingsProductHelper withNominalAnnualInterestRate(BigDecimal interestRate) {
|
||||
this.nominalAnnualInterestRate = interestRate.toString();
|
||||
return this;
|
||||
}
|
||||
|
||||
private Map<String, String> getAccountMappingForCashBased() {
|
||||
final Map<String, String> map = new HashMap<>();
|
||||
if (accountList != null) {
|
||||
|
||||
+356
@@ -0,0 +1,356 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.integrationtests.interoperation;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.jayway.restassured.path.json.JsonPath;
|
||||
import com.jayway.restassured.specification.RequestSpecification;
|
||||
import com.jayway.restassured.specification.ResponseSpecification;
|
||||
import org.apache.fineract.integrationtests.common.Utils;
|
||||
import org.apache.fineract.interoperation.domain.InteropAmountType;
|
||||
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
|
||||
import org.apache.fineract.interoperation.domain.InteropInitiatorType;
|
||||
import org.apache.fineract.interoperation.domain.InteropTransactionRole;
|
||||
import org.apache.fineract.interoperation.domain.InteropTransactionScenario;
|
||||
import org.apache.fineract.interoperation.domain.InteropTransferActionType;
|
||||
import org.apache.fineract.interoperation.util.InteropUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
public class InteropHelper {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(InteropTest.class);
|
||||
|
||||
private static final String BASE_URL = "/fineract-provider/api/v1/interoperation";
|
||||
private static final String HEALTH_URL = BASE_URL + "/health";
|
||||
private static final String PARTIES_URL = BASE_URL + "/parties";
|
||||
private static final String TRANSACTIONS_URL = BASE_URL + "/transactions";
|
||||
private static final String REQUESTS_URL_PARAM = "requests";
|
||||
private static final String REQUESTS_URL = BASE_URL + '/' + REQUESTS_URL_PARAM;
|
||||
private static final String QUOTES_URL_PARAM = "quotes";
|
||||
private static final String QUOTES_URL = BASE_URL + '/' + QUOTES_URL_PARAM;
|
||||
private static final String TRANSFERS_URL_PARAM = "transfers";
|
||||
private static final String TRANSFERS_URL = BASE_URL + '/' + TRANSFERS_URL_PARAM;
|
||||
private static final String PARAM_TRANSFER_ACTION = "action";
|
||||
static final String PARAM_ACTION_STATE = "state";
|
||||
static final String PARAM_ACCOUNT_BALANCE = "accountBalance";
|
||||
|
||||
private static final String NOTE = "Integration test";
|
||||
|
||||
private final RequestSpecification requestSpec;
|
||||
private ResponseSpecification responseSpec;
|
||||
private final String tenantId;
|
||||
private final String accountExternalId;
|
||||
private final String transactionCode;
|
||||
private final String currency;
|
||||
private final BigDecimal amount;
|
||||
private final BigDecimal fee;
|
||||
|
||||
public InteropHelper(RequestSpecification requestSpec, ResponseSpecification responseSpec, String tenantId,
|
||||
String accountExternalId, String transactionCode, String currency, BigDecimal amount, BigDecimal fee) {
|
||||
this.requestSpec = requestSpec;
|
||||
this.responseSpec = responseSpec;
|
||||
this.tenantId = tenantId;
|
||||
this.accountExternalId = accountExternalId;
|
||||
this.transactionCode = transactionCode;
|
||||
this.currency = currency;
|
||||
this.amount = amount;
|
||||
this.fee = fee;
|
||||
}
|
||||
|
||||
public InteropHelper(RequestSpecification requestSpec, ResponseSpecification responseSpec, String accountExternalId, String transactionCode) {
|
||||
this(requestSpec, responseSpec, Utils.DEFAULT_TENANT, accountExternalId, transactionCode, "TZS", BigDecimal.TEN, BigDecimal.ONE);
|
||||
}
|
||||
|
||||
public InteropHelper(RequestSpecification requestSpec, ResponseSpecification responseSpec) {
|
||||
this(requestSpec, responseSpec, UUID.randomUUID().toString(), UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
public RequestSpecification getRequestSpec() {
|
||||
return requestSpec;
|
||||
}
|
||||
|
||||
public ResponseSpecification getResponseSpec() {
|
||||
return responseSpec;
|
||||
}
|
||||
|
||||
void setResponseSpec(ResponseSpecification responseSpec) {
|
||||
this.responseSpec = responseSpec;
|
||||
}
|
||||
|
||||
public String getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
public String getAccountExternalId() {
|
||||
return accountExternalId;
|
||||
}
|
||||
|
||||
public String getTransactionCode() {
|
||||
return transactionCode;
|
||||
}
|
||||
|
||||
public String getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public BigDecimal getFee() {
|
||||
return fee;
|
||||
}
|
||||
|
||||
BigDecimal getTransferAmount() {
|
||||
return fee == null ? amount : amount.add(fee);
|
||||
}
|
||||
|
||||
private String buildUrl(String url) {
|
||||
return url + '?' + Utils.TENANT_PARAM_NAME + '=' + tenantId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return response json
|
||||
*/
|
||||
public String getHealth() {
|
||||
String url = buildUrl(HEALTH_URL);
|
||||
log.debug("Calling Interoperable GET Health: " + url);
|
||||
|
||||
String response = Utils.performServerGet(requestSpec, responseSpec, url, null);
|
||||
log.debug("Response Interoperable GET Health: " + response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return response 'accountId' attribute
|
||||
*/
|
||||
public String getParty(InteropIdentifierType idType, String idValue) {
|
||||
String url = buildUrl(PARTIES_URL + '/' + idType + '/' + idValue);
|
||||
log.debug("Calling Interoperable GET Party: " + url);
|
||||
|
||||
String response = Utils.performServerGet(requestSpec, responseSpec, url, null);
|
||||
log.debug("Response Interoperable GET Party: " + response);
|
||||
return getJsonAttribute(response, InteropUtil.PARAM_ACCOUNT_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return response 'accountId' attribute
|
||||
*/
|
||||
public String postParty(InteropIdentifierType idType, String idValue) {
|
||||
String url = buildUrl(PARTIES_URL + '/' + idType + '/' + idValue);
|
||||
String request = buildPartiesJson();
|
||||
log.debug("Calling Interoperable POST Party: " + url + ", body: " + request);
|
||||
|
||||
String response = Utils.performServerPost(requestSpec, responseSpec, url, request, null);
|
||||
log.debug("Response Interoperable POST Party: " + response);
|
||||
return getJsonAttribute(response, InteropUtil.PARAM_ACCOUNT_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return response 'accountId' attribute
|
||||
*/
|
||||
public String deleteParty(InteropIdentifierType idType, String idValue) {
|
||||
String url = buildUrl(PARTIES_URL + '/' + idType + '/' + idValue);
|
||||
String request = buildPartiesJson();
|
||||
log.debug("Calling Interoperable DELETE Party: " + url + ", body: " + request);
|
||||
|
||||
String response = Utils.performServerDelete(requestSpec, responseSpec, url, request, null);
|
||||
log.debug("Response Interoperable DELETE Party: " + response);
|
||||
return getJsonAttribute(response, InteropUtil.PARAM_ACCOUNT_ID);
|
||||
}
|
||||
|
||||
private String buildPartiesJson() {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put(InteropUtil.PARAM_ACCOUNT_ID, accountExternalId);
|
||||
return new Gson().toJson(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return response 'requestCode' attribute
|
||||
*/
|
||||
public String getTransactionRequest(String requestCode) {
|
||||
String url = buildUrl(TRANSACTIONS_URL + '/' + transactionCode + '/' + REQUESTS_URL_PARAM + '/' + requestCode);
|
||||
log.debug("Calling Interoperable GET Request: " + url);
|
||||
|
||||
String response = Utils.performServerGet(requestSpec, responseSpec, url, null);
|
||||
log.debug("Response Interoperable GET Request: " + response);
|
||||
return getJsonAttribute(response, InteropUtil.PARAM_REQUEST_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param role PAYEE role is not valid for transaction request
|
||||
* @return response json
|
||||
*/
|
||||
public String postTransactionRequest(String requestCode, InteropTransactionRole role) {
|
||||
String url = buildUrl(REQUESTS_URL);
|
||||
String request = buildTransactionRequestJson(requestCode, role);
|
||||
log.debug("Calling Interoperable POST Request: " + url + ", body: " + request);
|
||||
|
||||
String response = Utils.performServerPost(requestSpec, responseSpec, url, request, null);
|
||||
log.debug("Response Interoperable POST Request: " + response);
|
||||
return response;
|
||||
}
|
||||
|
||||
private String buildTransactionRequestJson(String requestCode, InteropTransactionRole role) {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put(InteropUtil.PARAM_TRANSACTION_CODE, transactionCode);
|
||||
map.put(InteropUtil.PARAM_REQUEST_CODE, requestCode);
|
||||
map.put(InteropUtil.PARAM_ACCOUNT_ID, accountExternalId);
|
||||
map.put(InteropUtil.PARAM_TRANSACTION_ROLE, role);
|
||||
|
||||
HashMap<String, Object> amountMap = new HashMap<>();
|
||||
amountMap.put(InteropUtil.PARAM_AMOUNT, amount.toString());
|
||||
amountMap.put(InteropUtil.PARAM_CURRENCY, currency);
|
||||
map.put(InteropUtil.PARAM_AMOUNT, amountMap);
|
||||
|
||||
HashMap<String, Object> typeMap = new HashMap<>();
|
||||
typeMap.put(InteropUtil.PARAM_SCENARIO, InteropTransactionScenario.PAYMENT);
|
||||
typeMap.put(InteropUtil.PARAM_INITIATOR, InteropTransactionRole.PAYEE);
|
||||
typeMap.put(InteropUtil.PARAM_INITIATOR_TYPE, InteropInitiatorType.CONSUMER);
|
||||
map.put(InteropUtil.PARAM_TRANSACTION_TYPE, typeMap);
|
||||
|
||||
return new Gson().toJson(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return response 'quoteCode' attribute
|
||||
*/
|
||||
public String getQuote(String quoteCode) {
|
||||
String url = buildUrl(TRANSACTIONS_URL + '/' + transactionCode + '/' + QUOTES_URL_PARAM + '/' + quoteCode);
|
||||
log.debug("Calling Interoperable GET Quote: " + url);
|
||||
|
||||
String response = Utils.performServerGet(requestSpec, responseSpec, url, null);
|
||||
log.debug("Response Interoperable GET Quote: " + response);
|
||||
return getJsonAttribute(response, InteropUtil.PARAM_QUOTE_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return response json
|
||||
*/
|
||||
public String postQuote(String quoteCode, InteropTransactionRole role) {
|
||||
String url = buildUrl(QUOTES_URL);
|
||||
String request = buildQuoteJson(quoteCode, role);
|
||||
log.debug("Calling Interoperable POST Quote: " + url + ", body: " + request);
|
||||
|
||||
String response = Utils.performServerPost(requestSpec, responseSpec, url, request, null);
|
||||
log.debug("Response Interoperable POST Quote: " + response);
|
||||
return response;
|
||||
}
|
||||
|
||||
private String buildQuoteJson(String quoteCode, InteropTransactionRole role) {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put(InteropUtil.PARAM_TRANSACTION_CODE, transactionCode);
|
||||
map.put(InteropUtil.PARAM_QUOTE_CODE, quoteCode);
|
||||
map.put(InteropUtil.PARAM_ACCOUNT_ID, accountExternalId);
|
||||
map.put(InteropUtil.PARAM_TRANSACTION_ROLE, role);
|
||||
map.put(InteropUtil.PARAM_AMOUNT_TYPE, InteropAmountType.RECEIVE);
|
||||
map.put(InteropUtil.PARAM_NOTE, NOTE);
|
||||
|
||||
HashMap<String, Object> amountMap = new HashMap<>();
|
||||
amountMap.put(InteropUtil.PARAM_AMOUNT, amount.toString());
|
||||
amountMap.put(InteropUtil.PARAM_CURRENCY, currency);
|
||||
map.put(InteropUtil.PARAM_AMOUNT, amountMap);
|
||||
|
||||
HashMap<String, Object> typeMap = new HashMap<>();
|
||||
typeMap.put(InteropUtil.PARAM_SCENARIO, InteropTransactionScenario.PAYMENT);
|
||||
typeMap.put(InteropUtil.PARAM_INITIATOR, InteropTransactionRole.PAYER);
|
||||
typeMap.put(InteropUtil.PARAM_INITIATOR_TYPE, InteropInitiatorType.CONSUMER);
|
||||
map.put(InteropUtil.PARAM_TRANSACTION_TYPE, typeMap);
|
||||
|
||||
return new Gson().toJson(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return response 'transferCode' attribute
|
||||
*/
|
||||
public String getTransfer(String transferCode) {
|
||||
String url = buildUrl(TRANSACTIONS_URL + '/' + transactionCode + '/' + TRANSFERS_URL_PARAM + '/' + transferCode);
|
||||
log.debug("Calling Interoperable GET Transfer: " + url);
|
||||
|
||||
String response = Utils.performServerGet(requestSpec, responseSpec, url, null);
|
||||
log.debug("Response Interoperable GET Transfer: " + response);
|
||||
return getJsonAttribute(response, InteropUtil.PARAM_TRANSFER_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return response json
|
||||
*/
|
||||
public String prepareTransfer(String transferCode) {
|
||||
return postTransfer(transferCode, InteropTransferActionType.PREPARE, InteropTransactionRole.PAYER);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return response json
|
||||
*/
|
||||
public String createTransfer(String transferCode, InteropTransactionRole role) {
|
||||
return postTransfer(transferCode, InteropTransferActionType.CREATE, role);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return response json
|
||||
*/
|
||||
public String postTransfer(String transferCode, InteropTransferActionType action, InteropTransactionRole role) {
|
||||
String url = buildUrl(TRANSFERS_URL) + '&' + PARAM_TRANSFER_ACTION + '=' + action;
|
||||
String request = buildTransferJson(transferCode, role);
|
||||
log.debug("Calling Interoperable POST Transfer: " + url + ", body: " + request);
|
||||
|
||||
String response = Utils.performServerPost(requestSpec, responseSpec, url, request, null);
|
||||
log.debug("Response Interoperable POST Transfer: " + response);
|
||||
return response;
|
||||
}
|
||||
|
||||
private String buildTransferJson(String transferCode, InteropTransactionRole role) {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put(InteropUtil.PARAM_TRANSACTION_CODE, transactionCode);
|
||||
map.put(InteropUtil.PARAM_TRANSFER_CODE, transferCode);
|
||||
map.put(InteropUtil.PARAM_ACCOUNT_ID, accountExternalId);
|
||||
map.put(InteropUtil.PARAM_TRANSACTION_ROLE, role);
|
||||
map.put(InteropUtil.PARAM_NOTE, NOTE);
|
||||
|
||||
HashMap<String, Object> amountMap = new HashMap<>();
|
||||
amountMap.put(InteropUtil.PARAM_AMOUNT, amount.toString());
|
||||
amountMap.put(InteropUtil.PARAM_CURRENCY, currency);
|
||||
map.put(InteropUtil.PARAM_AMOUNT, amountMap);
|
||||
|
||||
if (role.isWithdraw()) {
|
||||
HashMap<String, Object> feeMap = new HashMap<>();
|
||||
feeMap.put(InteropUtil.PARAM_AMOUNT, fee.toString());
|
||||
feeMap.put(InteropUtil.PARAM_CURRENCY, currency);
|
||||
map.put(InteropUtil.PARAM_FSP_FEE, feeMap);
|
||||
}
|
||||
|
||||
HashMap<String, Object> typeMap = new HashMap<>();
|
||||
typeMap.put(InteropUtil.PARAM_SCENARIO, InteropTransactionScenario.PAYMENT);
|
||||
typeMap.put(InteropUtil.PARAM_INITIATOR, InteropTransactionRole.PAYER);
|
||||
typeMap.put(InteropUtil.PARAM_INITIATOR_TYPE, InteropInitiatorType.CONSUMER);
|
||||
map.put(InteropUtil.PARAM_TRANSACTION_TYPE, typeMap);
|
||||
|
||||
return new Gson().toJson(map);
|
||||
}
|
||||
|
||||
public static String getJsonAttribute(String json, String attrName) {
|
||||
return JsonPath.from(json).get(attrName);
|
||||
}
|
||||
}
|
||||
+289
@@ -0,0 +1,289 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.integrationtests.interoperation;
|
||||
|
||||
import com.jayway.restassured.builder.RequestSpecBuilder;
|
||||
import com.jayway.restassured.builder.ResponseSpecBuilder;
|
||||
import com.jayway.restassured.http.ContentType;
|
||||
import com.jayway.restassured.internal.path.ObjectConverter;
|
||||
import com.jayway.restassured.path.json.JsonPath;
|
||||
import com.jayway.restassured.specification.RequestSpecification;
|
||||
import com.jayway.restassured.specification.ResponseSpecification;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.apache.fineract.integrationtests.common.Utils;
|
||||
import org.apache.fineract.integrationtests.common.accounting.Account;
|
||||
import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
|
||||
import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
|
||||
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
|
||||
import org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
|
||||
import org.apache.fineract.integrationtests.common.savings.SavingsStatusChecker;
|
||||
import org.apache.fineract.interoperation.domain.InteropActionState;
|
||||
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
|
||||
import org.apache.fineract.interoperation.domain.InteropTransactionRole;
|
||||
import org.apache.fineract.interoperation.util.InteropUtil;
|
||||
import org.apache.fineract.interoperation.util.MathUtil;
|
||||
import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsApiConstants;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper.ACCOUNT_TYPE_INDIVIDUAL;
|
||||
import static org.apache.fineract.integrationtests.interoperation.InteropHelper.PARAM_ACCOUNT_BALANCE;
|
||||
|
||||
public class InteropTest {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(InteropTest.class);
|
||||
|
||||
private final static String MIN_INTEREST_CALCULATON_BALANCE = null;
|
||||
private final static String MIN_REQUIRED_BALANCE = null;
|
||||
private final static String MIN_OPENING_BALANCE = "100000.0";
|
||||
private final static boolean ENFORCE_MIN_REQUIRED_BALANCE = false;
|
||||
private final static MathContext MATHCONTEXT = new MathContext(12, RoundingMode.HALF_EVEN);
|
||||
|
||||
private RequestSpecification requestSpec;
|
||||
private ResponseSpecification responseSpec;
|
||||
private ResponseSpecification responseClientErrorSpec;
|
||||
private ResponseSpecification responseErrorSpec;
|
||||
|
||||
private AccountHelper accountHelper;
|
||||
private SavingsAccountHelper savingsAccountHelper;
|
||||
private InteropHelper interopHelper;
|
||||
|
||||
private Integer clientId;
|
||||
private Integer savingsProductId;
|
||||
private Integer savingsId;
|
||||
private Integer chargeId;
|
||||
private String requestCode;
|
||||
private String quoteCode;
|
||||
private String transferCode;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
Utils.initializeRESTAssured();
|
||||
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||
|
||||
responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||
responseClientErrorSpec = new ResponseSpecBuilder().expectStatusCode(400).build();
|
||||
responseErrorSpec = new ResponseSpecBuilder().expectStatusCode(500).build();
|
||||
|
||||
String savingsExternalId = UUID.randomUUID().toString();
|
||||
String transactionCode = UUID.randomUUID().toString();
|
||||
|
||||
accountHelper = new AccountHelper(this.requestSpec, this.responseSpec);
|
||||
savingsAccountHelper = new SavingsAccountHelper(requestSpec, responseSpec);
|
||||
interopHelper = new InteropHelper(requestSpec, responseSpec, savingsExternalId, transactionCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInteroperation() {
|
||||
createClient();
|
||||
createSavingsProduct();
|
||||
createCharge();
|
||||
openSavingsAccount();
|
||||
|
||||
testParties();
|
||||
testRequests();
|
||||
testQuotes();
|
||||
testTransfers();
|
||||
}
|
||||
|
||||
private void createClient() {
|
||||
clientId = ClientHelper.createClient(requestSpec, responseSpec);
|
||||
Assert.assertNotNull(clientId);
|
||||
}
|
||||
|
||||
private void createSavingsProduct() {
|
||||
log.debug("------------------------------ Create Interoperable Saving Product ---------------------------------------");
|
||||
|
||||
Account[] accounts = {accountHelper.createAssetAccount(), accountHelper.createIncomeAccount(), accountHelper.createExpenseAccount(),
|
||||
accountHelper.createLiabilityAccount()};
|
||||
|
||||
SavingsProductHelper savingsProductHelper = new SavingsProductHelper();
|
||||
final String savingsProductJSON = savingsProductHelper
|
||||
.withCurrencyCode(interopHelper.getCurrency())
|
||||
.withNominalAnnualInterestRate(BigDecimal.ZERO)
|
||||
.withInterestCompoundingPeriodTypeAsDaily()
|
||||
.withInterestPostingPeriodTypeAsMonthly()
|
||||
.withInterestCalculationPeriodTypeAsDailyBalance()
|
||||
.withMinBalanceForInterestCalculation(MIN_INTEREST_CALCULATON_BALANCE)
|
||||
.withMinRequiredBalance(MIN_REQUIRED_BALANCE)
|
||||
.withEnforceMinRequiredBalance(Boolean.toString(ENFORCE_MIN_REQUIRED_BALANCE))
|
||||
.withMinimumOpenningBalance(MIN_OPENING_BALANCE)
|
||||
.withAccountingRuleAsCashBased(accounts)
|
||||
.build();
|
||||
savingsProductId = SavingsProductHelper.createSavingsProduct(savingsProductJSON, requestSpec, responseSpec);
|
||||
Assert.assertNotNull(savingsProductId);
|
||||
|
||||
log.debug("Sucessfully created Interoperable Saving Product (id: " + savingsProductId + ")");
|
||||
}
|
||||
|
||||
private void createCharge() {
|
||||
chargeId = ChargesHelper.createCharges(requestSpec, responseSpec, ChargesHelper.getSavingsJSON(interopHelper.getFee().toString(),
|
||||
interopHelper.getCurrency(), ChargeTimeType.WITHDRAWAL_FEE));
|
||||
Assert.assertNotNull(chargeId);
|
||||
}
|
||||
|
||||
private void openSavingsAccount() {
|
||||
log.debug("------------------------------ Create Interoperable Saving Account ---------------------------------------");
|
||||
savingsId = savingsAccountHelper.applyForSavingsApplicationWithExternalId(clientId, savingsProductId, ACCOUNT_TYPE_INDIVIDUAL, interopHelper.getAccountExternalId(), true);
|
||||
Assert.assertNotNull(savingsId);
|
||||
|
||||
HashMap savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(requestSpec, responseSpec, savingsId);
|
||||
SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap);
|
||||
|
||||
savingsStatusHashMap = savingsAccountHelper.approveSavings(savingsId);
|
||||
SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
|
||||
|
||||
savingsStatusHashMap = savingsAccountHelper.activateSavings(savingsId);
|
||||
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
|
||||
|
||||
if (chargeId != null) {
|
||||
savingsAccountHelper.addChargesForSavings(savingsId, chargeId, false, interopHelper.getFee());
|
||||
}
|
||||
|
||||
log.debug("Sucessfully created Interoperable Saving Account (id: " + savingsId + ")");
|
||||
}
|
||||
|
||||
private void testParties() {
|
||||
String idValue = UUID.randomUUID().toString();
|
||||
String accountId = interopHelper.postParty(InteropIdentifierType.MSISDN, idValue);
|
||||
Assert.assertEquals(interopHelper.getAccountExternalId(), accountId);
|
||||
|
||||
interopHelper.setResponseSpec(responseErrorSpec);
|
||||
accountId = interopHelper.postParty(InteropIdentifierType.MSISDN, idValue);
|
||||
Assert.assertNull(accountId);
|
||||
interopHelper.setResponseSpec(responseSpec);
|
||||
|
||||
accountId = interopHelper.getParty(InteropIdentifierType.MSISDN, idValue);
|
||||
Assert.assertEquals(interopHelper.getAccountExternalId(), accountId);
|
||||
|
||||
accountId = interopHelper.deleteParty(InteropIdentifierType.MSISDN, idValue);
|
||||
Assert.assertEquals(interopHelper.getAccountExternalId(), accountId);
|
||||
|
||||
interopHelper.setResponseSpec(responseErrorSpec);
|
||||
accountId = interopHelper.getParty(InteropIdentifierType.MSISDN, idValue);
|
||||
Assert.assertNull(accountId);
|
||||
interopHelper.setResponseSpec(responseSpec);
|
||||
}
|
||||
|
||||
private void testRequests() {
|
||||
requestCode = UUID.randomUUID().toString();
|
||||
String response = interopHelper.postTransactionRequest(requestCode, InteropTransactionRole.PAYER);
|
||||
JsonPath json = JsonPath.from(response);
|
||||
Assert.assertEquals(requestCode, json.getString(InteropUtil.PARAM_REQUEST_CODE));
|
||||
Assert.assertEquals(InteropActionState.ACCEPTED.toString(), json.getString(InteropHelper.PARAM_ACTION_STATE));
|
||||
|
||||
interopHelper.setResponseSpec(responseClientErrorSpec);
|
||||
interopHelper.postTransactionRequest(requestCode, InteropTransactionRole.PAYEE);
|
||||
interopHelper.setResponseSpec(responseSpec);
|
||||
}
|
||||
|
||||
private void testQuotes() {
|
||||
// payer
|
||||
quoteCode = UUID.randomUUID().toString();
|
||||
String response = interopHelper.postQuote(quoteCode, InteropTransactionRole.PAYER);
|
||||
JsonPath json = JsonPath.from(response);
|
||||
Assert.assertEquals(quoteCode, json.getString(InteropUtil.PARAM_QUOTE_CODE));
|
||||
Assert.assertEquals(InteropActionState.ACCEPTED.toString(), json.getString(InteropHelper.PARAM_ACTION_STATE));
|
||||
|
||||
Map<Object, Object> fee = json.getMap(InteropUtil.PARAM_FSP_FEE);
|
||||
Assert.assertNotNull(fee);
|
||||
BigDecimal feeAmount = ObjectConverter.convertObjectTo(fee.get(InteropUtil.PARAM_AMOUNT), BigDecimal.class);
|
||||
Assert.assertTrue("Quote fee expected: " + interopHelper.getFee() + ", actual: " + feeAmount, MathUtil.isEqualTo(interopHelper.getFee(), feeAmount));
|
||||
Assert.assertEquals(interopHelper.getCurrency(), fee.get(InteropUtil.PARAM_CURRENCY));
|
||||
|
||||
// payee
|
||||
response = interopHelper.postQuote(quoteCode, InteropTransactionRole.PAYEE);
|
||||
json = JsonPath.from(response);
|
||||
Assert.assertEquals(quoteCode, json.getString(InteropUtil.PARAM_QUOTE_CODE));
|
||||
Assert.assertEquals(InteropActionState.ACCEPTED.toString(), json.getString(InteropHelper.PARAM_ACTION_STATE));
|
||||
|
||||
fee = json.getMap(InteropUtil.PARAM_FSP_FEE);
|
||||
if (fee != null) {
|
||||
feeAmount = ObjectConverter.convertObjectTo(fee.get(InteropUtil.PARAM_AMOUNT), BigDecimal.class);
|
||||
Assert.assertTrue("PAYEE Quote fee expected: " + BigDecimal.ZERO + ", actual: " + feeAmount, MathUtil.isZero(feeAmount));
|
||||
}
|
||||
}
|
||||
|
||||
private void testTransfers() {
|
||||
String savings = (String) savingsAccountHelper.getSavingsAccountDetail(savingsId, null);
|
||||
JsonPath savingsJson = JsonPath.from(savings);
|
||||
BigDecimal onHold = ObjectConverter.convertObjectTo(savingsJson.get(SavingsApiConstants.savingsAmountOnHold), BigDecimal.class);
|
||||
BigDecimal balance = ObjectConverter.convertObjectTo(savingsJson.get(PARAM_ACCOUNT_BALANCE), BigDecimal.class);
|
||||
|
||||
transferCode = UUID.randomUUID().toString();
|
||||
String response = interopHelper.prepareTransfer(transferCode);
|
||||
JsonPath json = JsonPath.from(response);
|
||||
Assert.assertEquals(transferCode, json.getString(InteropUtil.PARAM_TRANSFER_CODE));
|
||||
Assert.assertEquals(InteropActionState.ACCEPTED.toString(), json.getString(InteropHelper.PARAM_ACTION_STATE));
|
||||
|
||||
// prepare
|
||||
savings = (String) savingsAccountHelper.getSavingsAccountDetail(savingsId, null);
|
||||
log.debug("Response Interoperable GET Saving: " + savings);
|
||||
savingsJson = JsonPath.from(savings);
|
||||
BigDecimal onHold2 = ObjectConverter.convertObjectTo(savingsJson.get(SavingsApiConstants.savingsAmountOnHold), BigDecimal.class);
|
||||
BigDecimal balance2 = ObjectConverter.convertObjectTo(savingsJson.get(PARAM_ACCOUNT_BALANCE), BigDecimal.class);
|
||||
|
||||
BigDecimal transferAmount = interopHelper.getTransferAmount();
|
||||
BigDecimal expectedHold = MathUtil.add(onHold, transferAmount, MATHCONTEXT);
|
||||
Assert.assertTrue("On hold amount expected: " + expectedHold + ", actual: " + onHold2, MathUtil.isEqualTo(expectedHold, onHold2));
|
||||
BigDecimal expectedBalance = MathUtil.subtract(balance, transferAmount, MATHCONTEXT);
|
||||
Assert.assertTrue("Balance amount expected: " + expectedBalance + ", actual: " + balance2, MathUtil.isEqualTo(expectedBalance, balance2));
|
||||
|
||||
// payer
|
||||
response = interopHelper.createTransfer(transferCode, InteropTransactionRole.PAYER);
|
||||
json = JsonPath.from(response);
|
||||
Assert.assertEquals(transferCode, json.getString(InteropUtil.PARAM_TRANSFER_CODE));
|
||||
Assert.assertEquals(InteropActionState.ACCEPTED.toString(), json.getString(InteropHelper.PARAM_ACTION_STATE));
|
||||
|
||||
savings = (String) savingsAccountHelper.getSavingsAccountDetail(savingsId, null);
|
||||
log.debug("Response Interoperable GET Saving: " + savings);
|
||||
savingsJson = JsonPath.from(savings);
|
||||
BigDecimal onHold3 = ObjectConverter.convertObjectTo(savingsJson.get(SavingsApiConstants.savingsAmountOnHold), BigDecimal.class);
|
||||
BigDecimal balance3 = ObjectConverter.convertObjectTo(savingsJson.get(PARAM_ACCOUNT_BALANCE), BigDecimal.class);
|
||||
Assert.assertTrue("On hold amount expected: " + onHold + ", actual: " + onHold3, MathUtil.isEqualTo(onHold, onHold3));
|
||||
Assert.assertTrue("Balance amount expected: " + expectedBalance + ", actual: " + balance3, MathUtil.isEqualTo(expectedBalance, balance3));
|
||||
|
||||
// payee
|
||||
response = interopHelper.createTransfer(transferCode, InteropTransactionRole.PAYEE);
|
||||
json = JsonPath.from(response);
|
||||
Assert.assertEquals(transferCode, json.getString(InteropUtil.PARAM_TRANSFER_CODE));
|
||||
Assert.assertEquals(InteropActionState.ACCEPTED.toString(), json.getString(InteropHelper.PARAM_ACTION_STATE));
|
||||
|
||||
savings = (String) savingsAccountHelper.getSavingsAccountDetail(savingsId, null);
|
||||
log.debug("Response Interoperable GET Saving: " + savings);
|
||||
savingsJson = JsonPath.from(savings);
|
||||
BigDecimal onHold4 = ObjectConverter.convertObjectTo(savingsJson.get(SavingsApiConstants.savingsAmountOnHold), BigDecimal.class);
|
||||
BigDecimal balance4 = ObjectConverter.convertObjectTo(savingsJson.get(PARAM_ACCOUNT_BALANCE), BigDecimal.class);
|
||||
expectedBalance = MathUtil.subtract(balance, interopHelper.getFee(), MATHCONTEXT);
|
||||
Assert.assertTrue("On hold amount expected: " + onHold + ", actual: " + onHold4, MathUtil.isEqualTo(onHold, onHold4));
|
||||
Assert.assertTrue("Balance amount expected: " + expectedBalance + ", actual: " + balance4, MathUtil.isEqualTo(balance, balance4));
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -118,7 +118,7 @@ public class CommandProcessingResult implements Serializable {
|
||||
this.subResourceId = subResourceId;
|
||||
}
|
||||
|
||||
private CommandProcessingResult(final Long resourceId, final Long officeId, final Long commandId, final Map<String, Object> changesOnly) {
|
||||
protected CommandProcessingResult(final Long resourceId, final Long officeId, final Long commandId, final Map<String, Object> changesOnly) {
|
||||
if (resourceId != null) {
|
||||
this.resourceIdentifier = resourceId.toString();
|
||||
} else {
|
||||
|
||||
+12
@@ -51,6 +51,18 @@ public class DataValidatorBuilder {
|
||||
return new DataValidatorBuilder(this.dataValidationErrors).resource(this.resource);
|
||||
}
|
||||
|
||||
public void merge(DataValidatorBuilder other) {
|
||||
dataValidationErrors.addAll(other.dataValidationErrors);
|
||||
}
|
||||
|
||||
public boolean hasError() {
|
||||
return !dataValidationErrors.isEmpty();
|
||||
}
|
||||
|
||||
public List<ApiParameterError> getDataValidationErrors() {
|
||||
return dataValidationErrors;
|
||||
}
|
||||
|
||||
public DataValidatorBuilder resource(final String resource) {
|
||||
this.resource = resource;
|
||||
return this;
|
||||
|
||||
+16
-6
@@ -22,6 +22,7 @@ import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -82,7 +83,7 @@ public class FromJsonHelper {
|
||||
return this.gsonConverter.toJson(object);
|
||||
}
|
||||
|
||||
public void checkForUnsupportedParameters(final Type typeOfMap, final String json, final Set<String> supportedParams) {
|
||||
public void checkForUnsupportedParameters(final Type typeOfMap, final String json, final Collection<String> supportedParams) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Map<String, Object> requestMap = this.gsonConverter.fromJson(json, typeOfMap);
|
||||
@@ -97,7 +98,7 @@ public class FromJsonHelper {
|
||||
if (!unsupportedParameterList.isEmpty()) { throw new UnsupportedParameterException(unsupportedParameterList); }
|
||||
}
|
||||
|
||||
public void checkForUnsupportedParameters(final JsonObject object, final Set<String> supportedParams) {
|
||||
public void checkForUnsupportedParameters(final JsonObject object, final Collection<String> supportedParams) {
|
||||
if (object == null) { throw new InvalidParameterException(); }
|
||||
|
||||
final Set<Entry<String, JsonElement>> entries = object.entrySet();
|
||||
@@ -196,17 +197,26 @@ public class FromJsonHelper {
|
||||
}
|
||||
|
||||
public LocalDate extractLocalDateNamed(final String parameterName, final JsonElement element) {
|
||||
return this.helperDelegator.extractLocalDateNamed(parameterName, element, new HashSet<String>());
|
||||
return this.helperDelegator.extractLocalDateNamed(parameterName, element, new HashSet<>());
|
||||
}
|
||||
|
||||
public LocalDateTime extractLocalTimeNamed(final String parameterName, final JsonElement element) {
|
||||
return this.helperDelegator.extractLocalTimeNamed(parameterName, element, new HashSet<String>());
|
||||
return this.helperDelegator.extractLocalTimeNamed(parameterName, element, new HashSet<>());
|
||||
}
|
||||
|
||||
|
||||
public LocalDateTime extractLocalTimeNamed(final String parameterName, final JsonElement element, final String dateFormat,
|
||||
final Locale locale) {
|
||||
return this.helperDelegator.extractLocalTimeNamed(parameterName, element, dateFormat, locale, new HashSet<>());
|
||||
}
|
||||
|
||||
public LocalDateTime extractLocalTimeNamed(final String parameterName, final JsonElement element, String timeFormat) {
|
||||
return this.helperDelegator.extractLocalTimeNamed(parameterName, element, timeFormat, new HashSet<>());
|
||||
}
|
||||
|
||||
public LocalDate extractLocalDateNamed(final String parameterName, final JsonElement element, final String dateFormat,
|
||||
final Locale locale) {
|
||||
return this.helperDelegator.extractLocalDateNamed(parameterName, element.getAsJsonObject(), dateFormat, locale,
|
||||
new HashSet<String>());
|
||||
new HashSet<>());
|
||||
}
|
||||
|
||||
public LocalDate extractLocalDateNamed(final String parameterName, final JsonElement element,
|
||||
|
||||
+14
-4
@@ -378,15 +378,25 @@ public class JsonParserHelper {
|
||||
|
||||
if (element.isJsonObject()) {
|
||||
final JsonObject object = element.getAsJsonObject();
|
||||
value = extractLocalTimeNamed(parameterName, element, extractTimeFormatParameter(object), parametersPassedInCommand);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
final String timeFormat = extractTimeFormatParameter(object);
|
||||
public LocalDateTime extractLocalTimeNamed(final String parameterName, final JsonElement element, String timeFormat,
|
||||
final Set<String> parametersPassedInCommand) {
|
||||
|
||||
LocalDateTime value = null;
|
||||
|
||||
if (element.isJsonObject()) {
|
||||
final JsonObject object = element.getAsJsonObject();
|
||||
final Locale clientApplicationLocale = extractLocaleParameter(object);
|
||||
value = extractLocalTimeNamed(parameterName, object, timeFormat, clientApplicationLocale, parametersPassedInCommand);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public LocalDateTime extractLocalTimeNamed(final String parameterName, final JsonObject element, final String timeFormat,
|
||||
|
||||
public LocalDateTime extractLocalTimeNamed(final String parameterName, final JsonElement element, final String timeFormat,
|
||||
final Locale clientApplicationLocale, final Set<String> parametersPassedInCommand) {
|
||||
LocalDateTime value = null;
|
||||
String timeValueAsString=null;
|
||||
@@ -419,7 +429,7 @@ public class JsonParserHelper {
|
||||
return value;
|
||||
}
|
||||
|
||||
public LocalDate extractLocalDateNamed(final String parameterName, final JsonObject element, final String dateFormat,
|
||||
public LocalDate extractLocalDateNamed(final String parameterName, final JsonElement element, final String dateFormat,
|
||||
final Locale clientApplicationLocale, final Set<String> parametersPassedInCommand) {
|
||||
LocalDate value = null;
|
||||
if (element.isJsonObject()) {
|
||||
|
||||
+317
@@ -0,0 +1,317 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.api;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.interoperation.data.InteropIdentifierRequestData;
|
||||
import org.apache.fineract.interoperation.data.InteropIdentifierResponseData;
|
||||
import org.apache.fineract.interoperation.data.InteropQuoteRequestData;
|
||||
import org.apache.fineract.interoperation.data.InteropQuoteResponseData;
|
||||
import org.apache.fineract.interoperation.data.InteropTransactionRequestData;
|
||||
import org.apache.fineract.interoperation.data.InteropTransactionRequestResponseData;
|
||||
import org.apache.fineract.interoperation.data.InteropTransferRequestData;
|
||||
import org.apache.fineract.interoperation.data.InteropTransferResponseData;
|
||||
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
|
||||
import org.apache.fineract.interoperation.domain.InteropTransferActionType;
|
||||
import org.apache.fineract.interoperation.service.InteropService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ENTITY_NAME_QUOTE;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ENTITY_NAME_REQUEST;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ROOT_PATH;
|
||||
|
||||
@Path("/interoperation") //api/v1/
|
||||
@Component
|
||||
@Scope
|
||||
@Api(value = ROOT_PATH, description = "")
|
||||
public class InteropApiResource {
|
||||
|
||||
private PlatformSecurityContext context;
|
||||
private ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
|
||||
private DefaultToApiJsonSerializer<CommandProcessingResult> jsonSerializer;
|
||||
|
||||
private InteropService interopService;
|
||||
private PortfolioCommandSourceWritePlatformService commandsSourceService;
|
||||
|
||||
@Autowired
|
||||
public InteropApiResource(PlatformSecurityContext context,
|
||||
ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
DefaultToApiJsonSerializer<CommandProcessingResult> defaultToApiJsonSerializer,
|
||||
InteropService interopService,
|
||||
PortfolioCommandSourceWritePlatformService portfolioCommandSourceWritePlatformService) {
|
||||
this.context = context;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.jsonSerializer = defaultToApiJsonSerializer;
|
||||
this.interopService = interopService;
|
||||
this.commandsSourceService = portfolioCommandSourceWritePlatformService;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Path("health")
|
||||
@ApiOperation(value = "Query Interoperation Health Request", httpMethod = "GET", notes = "")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK")})
|
||||
public String health(@Context UriInfo uriInfo) {
|
||||
return "OK";
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Path("parties/{idType}/{idValue}")
|
||||
@ApiOperation(value = "Query Interoperation Account by secondary identifier", httpMethod = "GET", notes = "")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = InteropIdentifierResponseData.class)})
|
||||
public String getAccountByIdentifier(@PathParam("idType") @ApiParam(value = "idType") InteropIdentifierType idType,
|
||||
@PathParam("idValue") @ApiParam(value = "idValue") String idValue,
|
||||
@Context UriInfo uriInfo) {
|
||||
InteropIdentifierResponseData result = interopService.getAccountByIdentifier(idType, idValue, null);
|
||||
ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return jsonSerializer.serialize(settings, result);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Path("parties/{idType}/{idValue}/{subIdOrType}")
|
||||
@ApiOperation(value = "Query Interoperation Account by secondary identifier", httpMethod = "GET", notes = "")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = InteropIdentifierResponseData.class)})
|
||||
public String getAccountByIdentifier(@PathParam("idType") @ApiParam(value = "idType") InteropIdentifierType idType,
|
||||
@PathParam("idValue") @ApiParam(value = "idValue") String idValue,
|
||||
@PathParam("subIdOrType") @ApiParam(value = "subIdOrType") String subIdOrType,
|
||||
@Context UriInfo uriInfo) {
|
||||
InteropIdentifierResponseData result = interopService.getAccountByIdentifier(idType, idValue, subIdOrType);
|
||||
ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return jsonSerializer.serialize(settings, result);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Path("parties/{idType}/{idValue}")
|
||||
@ApiOperation(value = "Interoperation Identifier registration", httpMethod = "POST", notes = "")
|
||||
@ApiImplicitParams({@ApiImplicitParam(value = "body", required = true, paramType = "body", dataType = "body", format = "body",
|
||||
dataTypeClass = InteropIdentifierRequestData.class)})
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = InteropIdentifierResponseData.class)})
|
||||
public String registerAccountIdentifier(@PathParam("idType") @ApiParam(value = "idType") InteropIdentifierType idType,
|
||||
@PathParam("idValue") @ApiParam(value = "idValue") String idValue,
|
||||
@ApiParam(hidden = true) String identifierJson, @Context UriInfo uriInfo)
|
||||
throws Throwable {
|
||||
CommandWrapper commandRequest = new InteropWrapperBuilder().registerAccountIdentifier(idType, idValue, null).withJson(identifierJson).build();
|
||||
|
||||
InteropIdentifierResponseData result = (InteropIdentifierResponseData) commandsSourceService.logCommandSource(commandRequest);
|
||||
ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return jsonSerializer.serialize(settings, result);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Path("parties/{idType}/{idValue}/{subIdOrType}")
|
||||
@ApiOperation(value = "Interoperation Identifier registration", httpMethod = "POST", notes = "")
|
||||
@ApiImplicitParams({@ApiImplicitParam(value = "body", required = true, paramType = "body", dataType = "body", format = "body",
|
||||
dataTypeClass = InteropIdentifierRequestData.class)})
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = InteropIdentifierResponseData.class)})
|
||||
public String registerAccountIdentifier(@PathParam("idType") @ApiParam(value = "idType") InteropIdentifierType idType,
|
||||
@PathParam("idValue") @ApiParam(value = "idValue") String idValue,
|
||||
@PathParam("subIdOrType") @ApiParam(value = "subIdOrType") String subIdOrType,
|
||||
@ApiParam(hidden = true) String identifierJson, @Context UriInfo uriInfo)
|
||||
throws Throwable {
|
||||
CommandWrapper commandRequest = new InteropWrapperBuilder().registerAccountIdentifier(idType, idValue, subIdOrType).withJson(identifierJson).build();
|
||||
|
||||
InteropIdentifierResponseData result = (InteropIdentifierResponseData) commandsSourceService.logCommandSource(commandRequest);
|
||||
ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return jsonSerializer.serialize(settings, result);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Path("parties/{idType}/{idValue}")
|
||||
@ApiOperation(value = "Allow Interoperation Identifier registration", httpMethod = "DELETE", notes = "")
|
||||
@ApiImplicitParams({@ApiImplicitParam(value = "body", required = true, paramType = "body", dataType = "body", format = "body",
|
||||
dataTypeClass = InteropIdentifierRequestData.class)})
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = InteropIdentifierResponseData.class)})
|
||||
public String deleteAccountIdentifier(@PathParam("idType") @ApiParam(value = "idType") InteropIdentifierType idType,
|
||||
@PathParam("idValue") @ApiParam(value = "idValue") String idValue,
|
||||
@Context UriInfo uriInfo)
|
||||
throws Throwable {
|
||||
CommandWrapper commandRequest = new InteropWrapperBuilder().deleteAccountIdentifier(idType, idValue, null).build();
|
||||
|
||||
InteropIdentifierResponseData result = (InteropIdentifierResponseData) commandsSourceService.logCommandSource(commandRequest);
|
||||
ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return jsonSerializer.serialize(settings, result);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Path("parties/{idType}/{idValue}/{subIdOrType}")
|
||||
@ApiOperation(value = "Allow Interoperation Identifier registration", httpMethod = "DELETE", notes = "")
|
||||
@ApiImplicitParams({@ApiImplicitParam(value = "body", required = true, paramType = "body", dataType = "body", format = "body",
|
||||
dataTypeClass = InteropIdentifierRequestData.class)})
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = InteropIdentifierResponseData.class)})
|
||||
public String deleteAccountIdentifier(@PathParam("idType") @ApiParam(value = "idType") InteropIdentifierType idType,
|
||||
@PathParam("idValue") @ApiParam(value = "idValue") String idValue,
|
||||
@PathParam("subIdOrType") @ApiParam(value = "subIdOrType") String subIdOrType,
|
||||
@Context UriInfo uriInfo)
|
||||
throws Throwable {
|
||||
CommandWrapper commandRequest = new InteropWrapperBuilder().deleteAccountIdentifier(idType, idValue, subIdOrType).build();
|
||||
|
||||
InteropIdentifierResponseData result = (InteropIdentifierResponseData) commandsSourceService.logCommandSource(commandRequest);
|
||||
ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return jsonSerializer.serialize(settings, result);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Path("transactions/{transactionCode}/requests/{requestCode}")
|
||||
@ApiOperation(value = "Query Interoperation Transaction Request", httpMethod = "GET", notes = "")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = InteropTransactionRequestResponseData.class)})
|
||||
public String getTransactionRequest(@PathParam("transactionCode") @ApiParam(value = "transactionCode") String transactionCode,
|
||||
@PathParam("requestCode") @ApiParam(value = "requestCode") String requestCode, @Context UriInfo uriInfo) {
|
||||
context.authenticatedUser().validateHasReadPermission(ENTITY_NAME_REQUEST);
|
||||
|
||||
InteropTransactionRequestResponseData result = interopService.getTransactionRequest(transactionCode, requestCode);
|
||||
ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return jsonSerializer.serialize(settings, result);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Path("requests")
|
||||
@ApiOperation(value = "Allow Interoperation Transaction Request", httpMethod = "POST", notes = "")
|
||||
@ApiImplicitParams({@ApiImplicitParam(value = "body", required = true, paramType = "body", dataType = "body", format = "body",
|
||||
dataTypeClass = InteropTransactionRequestData.class)})
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = InteropTransactionRequestResponseData.class)})
|
||||
public String createTransactionRequest(@ApiParam(hidden = true) String quotesJson, @Context UriInfo uriInfo) {
|
||||
CommandWrapper commandRequest = new InteropWrapperBuilder().createTransactionRequest().withJson(quotesJson).build();
|
||||
|
||||
InteropTransactionRequestResponseData result = (InteropTransactionRequestResponseData) commandsSourceService.logCommandSource(commandRequest);
|
||||
ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return jsonSerializer.serialize(settings, result);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Path("transactions/{transactionCode}/quotes/{quoteCode}")
|
||||
@ApiOperation(value = "Query Interoperation Quote", httpMethod = "GET", notes = "")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = InteropQuoteResponseData.class)})
|
||||
public String getQuote(@PathParam("transactionCode") @ApiParam(value = "transactionCode") String transactionCode,
|
||||
@PathParam("quoteCode") @ApiParam(value = "quoteCode") String quoteCode,
|
||||
@Context UriInfo uriInfo) {
|
||||
context.authenticatedUser().validateHasReadPermission(ENTITY_NAME_QUOTE);
|
||||
|
||||
InteropQuoteResponseData result = interopService.getQuote(transactionCode, quoteCode);
|
||||
ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return this.jsonSerializer.serialize(settings, result);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Path("quotes")
|
||||
@ApiOperation(value = "Calculate Interoperation Quote", httpMethod = "POST", notes = "")
|
||||
@ApiImplicitParams({@ApiImplicitParam(value = "body", required = true, paramType = "body", dataType = "body", format = "body",
|
||||
dataTypeClass = InteropQuoteRequestData.class)})
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = InteropQuoteResponseData.class)})
|
||||
public String createQuote(@ApiParam(hidden = true) String quotesJson, @Context UriInfo uriInfo) {
|
||||
CommandWrapper commandRequest = new InteropWrapperBuilder().createQuotes().withJson(quotesJson).build();
|
||||
|
||||
InteropQuoteResponseData result = (InteropQuoteResponseData) commandsSourceService.logCommandSource(commandRequest);
|
||||
ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return jsonSerializer.serialize(settings, result);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Path("transactions/{transactionCode}/transfers/{transferCode}")
|
||||
@ApiOperation(value = "Query Interoperation Transfer", httpMethod = "GET", notes = "")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = InteropTransferResponseData.class)})
|
||||
public String getTransfer(@PathParam("transactionCode") @ApiParam(value = "transactionCode") String transactionCode,
|
||||
@PathParam("transferCode") @ApiParam(value = "transferCode") String transferCode,
|
||||
@Context UriInfo uriInfo) {
|
||||
context.authenticatedUser().validateHasReadPermission(ENTITY_NAME_QUOTE);
|
||||
|
||||
InteropTransferResponseData result = interopService.getTransfer(transactionCode, transferCode);
|
||||
ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return this.jsonSerializer.serialize(settings, result);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Path("transfers")
|
||||
@ApiOperation(value = "Prepare Interoperation Transfer", httpMethod = "POST", notes = "")
|
||||
@ApiImplicitParams({@ApiImplicitParam(value = "body", required = true, paramType = "body", dataType = "body", format = "body",
|
||||
dataTypeClass = InteropTransferRequestData.class)})
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = InteropTransferResponseData.class)})
|
||||
public String performTransfer(@QueryParam("action") @ApiParam(value = "action") String action,
|
||||
@ApiParam(hidden = true) String quotesJson, @Context UriInfo uriInfo) {
|
||||
CommandWrapper commandRequest = new InteropWrapperBuilder().performTransfer(InteropTransferActionType.valueOf(action)).withJson(quotesJson).build();
|
||||
|
||||
InteropTransferResponseData result = (InteropTransferResponseData) commandsSourceService.logCommandSource(commandRequest);
|
||||
ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return jsonSerializer.serialize(settings, result);
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.api;
|
||||
|
||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
|
||||
import org.apache.fineract.interoperation.domain.InteropTransferActionType;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ENTITY_NAME_IDENTIFIER;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ENTITY_NAME_QUOTE;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ENTITY_NAME_REQUEST;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ENTITY_NAME_TRANSFER;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ROOT_PATH;
|
||||
|
||||
public class InteropWrapperBuilder {
|
||||
|
||||
private String actionName;
|
||||
private String entityName;
|
||||
private String href;
|
||||
private String json = "{}";
|
||||
|
||||
public CommandWrapper build() {
|
||||
return new CommandWrapper(null, null, null, null, null, actionName, entityName, null, null, href, json, null, null,
|
||||
null, null, null);
|
||||
}
|
||||
|
||||
public InteropWrapperBuilder withJson(final String json) {
|
||||
this.json = json;
|
||||
return this;
|
||||
}
|
||||
|
||||
public InteropWrapperBuilder registerAccountIdentifier(InteropIdentifierType idType, String idValue, String subIdOrType) {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = ENTITY_NAME_IDENTIFIER;
|
||||
this.href = "/" + ROOT_PATH + "/parties/" + idType + "/" + idValue + "/" + (subIdOrType == null ? " " : subIdOrType);
|
||||
return this;
|
||||
}
|
||||
|
||||
public InteropWrapperBuilder deleteAccountIdentifier(InteropIdentifierType idType, String idValue, String subIdOrType) {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = ENTITY_NAME_IDENTIFIER;
|
||||
this.href = "/" + ROOT_PATH + "/parties/" + idType + "/" + idValue + "/" + (subIdOrType == null ? " " : subIdOrType);
|
||||
return this;
|
||||
}
|
||||
|
||||
public InteropWrapperBuilder createTransactionRequest() {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = ENTITY_NAME_REQUEST;
|
||||
this.href = "/" + ROOT_PATH + "/requests";
|
||||
return this;
|
||||
}
|
||||
|
||||
public InteropWrapperBuilder createQuotes() {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = ENTITY_NAME_QUOTE;
|
||||
this.href = "/" + ROOT_PATH + "/quotes";
|
||||
return this;
|
||||
}
|
||||
|
||||
public InteropWrapperBuilder performTransfer(InteropTransferActionType action) {
|
||||
this.actionName = action.name();
|
||||
this.entityName = ENTITY_NAME_TRANSFER;
|
||||
this.href = "/" + ROOT_PATH + "/transfers";
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.PARAM_KEY;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.PARAM_VALUE;
|
||||
|
||||
public class ExtensionData {
|
||||
|
||||
public static final String[] PARAMS = {PARAM_KEY, PARAM_VALUE};
|
||||
|
||||
@NotNull
|
||||
private final String key;
|
||||
|
||||
private String value;
|
||||
|
||||
public ExtensionData(String key, String value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static ExtensionData validateAndParse(DataValidatorBuilder dataValidator, JsonObject element, FromJsonHelper jsonHelper) {
|
||||
if (element == null)
|
||||
return null;
|
||||
|
||||
jsonHelper.checkForUnsupportedParameters(element, Arrays.asList(PARAMS));
|
||||
|
||||
String key = jsonHelper.extractStringNamed(PARAM_KEY, element);
|
||||
DataValidatorBuilder dataValidatorCopy = dataValidator.reset().parameter(PARAM_KEY).value(key).notBlank();
|
||||
|
||||
String value = jsonHelper.extractStringNamed(PARAM_VALUE, element);
|
||||
|
||||
dataValidator.merge(dataValidatorCopy);
|
||||
return dataValidator.hasError() ? null : new ExtensionData(key, value);
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.PARAM_LATITUDE;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.PARAM_LONGITUDE;
|
||||
|
||||
public class GeoCodeData {
|
||||
|
||||
public static final String[] PARAMS = {PARAM_LATITUDE, PARAM_LONGITUDE};
|
||||
|
||||
@NotNull
|
||||
private final String latitude;
|
||||
@NotNull
|
||||
private final String longitude;
|
||||
|
||||
public GeoCodeData(String latitude, String longitude) {
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
public String getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public String getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public static GeoCodeData validateAndParse(DataValidatorBuilder dataValidator, JsonObject element, FromJsonHelper jsonHelper) {
|
||||
if (element == null)
|
||||
return null;
|
||||
|
||||
jsonHelper.checkForUnsupportedParameters(element, Arrays.asList(PARAMS));
|
||||
|
||||
String latitude = jsonHelper.extractStringNamed(PARAM_LATITUDE, element);
|
||||
DataValidatorBuilder dataValidatorCopy = dataValidator.reset().parameter(PARAM_LATITUDE).value(latitude).notBlank();
|
||||
|
||||
String longitude = jsonHelper.extractStringNamed(PARAM_LONGITUDE, element);
|
||||
dataValidatorCopy = dataValidatorCopy.reset().parameter(PARAM_LONGITUDE).value(longitude).notBlank();
|
||||
|
||||
dataValidator.merge(dataValidatorCopy);
|
||||
return dataValidator.hasError() ? null : new GeoCodeData(latitude, longitude);
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.bval.constraints.NotEmpty;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
|
||||
import org.apache.fineract.interoperation.domain.InteropTransactionRole;
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.*;
|
||||
|
||||
public class InteropIdentifierRequestData {
|
||||
|
||||
static final String[] PARAMS = {PARAM_ACCOUNT_ID};
|
||||
|
||||
@NotEmpty
|
||||
private final InteropIdentifierType idType;
|
||||
@NotEmpty
|
||||
private final String idValue;
|
||||
|
||||
private final String subIdOrType;
|
||||
|
||||
@NotEmpty
|
||||
private final String accountId;
|
||||
|
||||
public InteropIdentifierRequestData(@NotNull InteropIdentifierType idType, @NotNull String idValue, String subIdOrType, String accountId) {
|
||||
this.idType = idType;
|
||||
this.idValue = idValue;
|
||||
this.subIdOrType = subIdOrType;
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public InteropIdentifierType getIdType() {
|
||||
return idType;
|
||||
}
|
||||
|
||||
public String getIdValue() {
|
||||
return idValue;
|
||||
}
|
||||
|
||||
public String getSubIdOrType() {
|
||||
return subIdOrType;
|
||||
}
|
||||
|
||||
public String getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public static InteropIdentifierRequestData validateAndParse(final DataValidatorBuilder dataValidator, @NotNull InteropIdentifierType idType,
|
||||
@NotNull String idValue, String subIdOrType, JsonObject element,
|
||||
FromJsonHelper jsonHelper) {
|
||||
if (element == null)
|
||||
return null;
|
||||
|
||||
jsonHelper.checkForUnsupportedParameters(element, Arrays.asList(PARAMS));
|
||||
|
||||
String accountId = jsonHelper.extractStringNamed(PARAM_ACCOUNT_ID, element);
|
||||
DataValidatorBuilder dataValidatorCopy = dataValidator.reset().parameter(PARAM_ACCOUNT_ID).value(accountId).notBlank();
|
||||
|
||||
dataValidator.merge(dataValidatorCopy);
|
||||
return dataValidator.hasError() ? null : new InteropIdentifierRequestData(idType, idValue, subIdOrType, accountId);
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import org.apache.bval.constraints.NotEmpty;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Map;
|
||||
|
||||
public class InteropIdentifierResponseData extends CommandProcessingResult {
|
||||
|
||||
@NotEmpty
|
||||
private String accountId;
|
||||
|
||||
|
||||
protected InteropIdentifierResponseData(Long resourceId, Long officeId, Long commandId, Map<String, Object> changesOnly, @NotNull String accountId) {
|
||||
super(resourceId, officeId, commandId, changesOnly);
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
protected static InteropIdentifierResponseData build(Long resourceId, Long officeId, Long commandId, Map<String, Object> changesOnly, @NotNull String accountId) {
|
||||
return new InteropIdentifierResponseData(resourceId, officeId, commandId, changesOnly, accountId);
|
||||
}
|
||||
|
||||
protected static InteropIdentifierResponseData build(Long commandId, @NotNull String accountId) {
|
||||
return build(null, null, commandId, null, accountId);
|
||||
}
|
||||
|
||||
public static InteropIdentifierResponseData build(@NotNull String accountId) {
|
||||
return build(null, accountId);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
protected void setAccountId(String accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.interoperation.domain.InteropAmountType;
|
||||
import org.apache.fineract.interoperation.domain.InteropTransactionRole;
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.*;
|
||||
|
||||
public class InteropQuoteRequestData extends InteropRequestData {
|
||||
|
||||
static final String[] PARAMS = {PARAM_TRANSACTION_CODE, PARAM_REQUEST_CODE, PARAM_ACCOUNT_ID, PARAM_AMOUNT, PARAM_TRANSACTION_TYPE,
|
||||
PARAM_TRANSACTION_ROLE, PARAM_NOTE, PARAM_GEO_CODE, PARAM_EXPIRATION, PARAM_EXTENSION_LIST, PARAM_QUOTE_CODE,
|
||||
PARAM_AMOUNT_TYPE, PARAM_FEES, PARAM_LOCALE, PARAM_DATE_FORMAT};
|
||||
@NotNull
|
||||
private final String quoteCode;
|
||||
@NotNull
|
||||
private final InteropAmountType amountType;
|
||||
|
||||
private final MoneyData fees; // only for disclosed Payer fees on the Payee side
|
||||
|
||||
public InteropQuoteRequestData(@NotNull String transactionCode, String requestCode, @NotNull String accountId, @NotNull MoneyData amount,
|
||||
@NotNull InteropTransactionRole transactionRole, @NotNull InteropTransactionTypeData transactionType,
|
||||
String note, GeoCodeData geoCode, LocalDateTime expiration, List<ExtensionData> extensionList,
|
||||
@NotNull String quoteCode, @NotNull InteropAmountType amountType, MoneyData fees) {
|
||||
super(transactionCode, requestCode, accountId, amount, transactionRole, transactionType, note, geoCode, expiration, extensionList);
|
||||
this.quoteCode = quoteCode;
|
||||
this.amountType = amountType;
|
||||
this.fees = fees;
|
||||
}
|
||||
|
||||
public InteropQuoteRequestData(@NotNull String transactionCode, @NotNull String accountId, @NotNull InteropAmountType amountType,
|
||||
@NotNull MoneyData amount, @NotNull InteropTransactionRole transactionRole, @NotNull InteropTransactionTypeData transactionType,
|
||||
@NotNull String quoteCode) {
|
||||
this(transactionCode, null, accountId, amount, transactionRole, transactionType, null, null, null, null, quoteCode,
|
||||
amountType, null);
|
||||
}
|
||||
|
||||
private InteropQuoteRequestData(@NotNull InteropRequestData other, @NotNull String quoteCode, @NotNull InteropAmountType amountType,
|
||||
MoneyData fees) {
|
||||
this(other.getTransactionCode(), other.getRequestCode(), other.getAccountId(), other.getAmount(), other.getTransactionRole(),
|
||||
other.getTransactionType(), other.getNote(), other.getGeoCode(), other.getExpiration(), other.getExtensionList(),
|
||||
quoteCode, amountType, fees);
|
||||
}
|
||||
|
||||
public String getQuoteCode() {
|
||||
return quoteCode;
|
||||
}
|
||||
|
||||
public InteropAmountType getAmountType() {
|
||||
return amountType;
|
||||
}
|
||||
|
||||
public MoneyData getFees() {
|
||||
return fees;
|
||||
}
|
||||
|
||||
public void normalizeAmounts(@NotNull MonetaryCurrency currency) {
|
||||
super.normalizeAmounts(currency);
|
||||
if (fees != null)
|
||||
fees.normalizeAmount(currency);
|
||||
}
|
||||
|
||||
public static InteropQuoteRequestData validateAndParse(final DataValidatorBuilder dataValidator, JsonObject element, FromJsonHelper jsonHelper) {
|
||||
if (element == null)
|
||||
return null;
|
||||
|
||||
jsonHelper.checkForUnsupportedParameters(element, Arrays.asList(PARAMS));
|
||||
|
||||
InteropRequestData interopRequestData = InteropRequestData.validateAndParse(dataValidator, element, jsonHelper);
|
||||
|
||||
String quoteCode = jsonHelper.extractStringNamed(PARAM_QUOTE_CODE, element);
|
||||
DataValidatorBuilder dataValidatorCopy = dataValidator.reset().parameter(PARAM_QUOTE_CODE).value(quoteCode).notBlank();
|
||||
|
||||
String amountTypeString = jsonHelper.extractStringNamed(PARAM_AMOUNT_TYPE, element);
|
||||
dataValidatorCopy = dataValidatorCopy.reset().parameter(PARAM_AMOUNT_TYPE).value(amountTypeString).notBlank();
|
||||
InteropAmountType amountType = InteropAmountType.valueOf(amountTypeString);
|
||||
|
||||
JsonObject feesElement = jsonHelper.extractJsonObjectNamed(PARAM_FEES, element);
|
||||
dataValidator.merge(dataValidatorCopy);
|
||||
MoneyData fees = MoneyData.validateAndParse(dataValidator, feesElement, jsonHelper);
|
||||
|
||||
String transactionRoleString = jsonHelper.extractStringNamed(PARAM_TRANSACTION_ROLE, element);
|
||||
dataValidatorCopy = dataValidator.reset().parameter(PARAM_TRANSACTION_ROLE).value(transactionRoleString).notNull();
|
||||
|
||||
JsonObject transactionTypeElement = jsonHelper.extractJsonObjectNamed(PARAM_TRANSACTION_TYPE, element);
|
||||
dataValidatorCopy = dataValidatorCopy.reset().parameter(PARAM_TRANSACTION_TYPE).value(transactionTypeElement).notNull();
|
||||
|
||||
dataValidator.merge(dataValidatorCopy);
|
||||
return dataValidator.hasError() ? null : new InteropQuoteRequestData(interopRequestData, quoteCode, amountType, fees);
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import org.apache.fineract.interoperation.domain.InteropActionState;
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class InteropQuoteResponseData extends InteropResponseData {
|
||||
|
||||
@NotNull
|
||||
private final String quoteCode;
|
||||
|
||||
private MoneyData fspFee;
|
||||
|
||||
private MoneyData fspCommission;
|
||||
|
||||
|
||||
private InteropQuoteResponseData(Long resourceId, Long officeId, Long commandId, Map<String, Object> changesOnly,
|
||||
@NotNull String transactionCode, @NotNull InteropActionState state, LocalDateTime expiration,
|
||||
List<ExtensionData> extensionList, @NotNull String quoteCode, MoneyData fspFee, MoneyData fspCommission) {
|
||||
super(resourceId, officeId, commandId, changesOnly, transactionCode, state, expiration, extensionList);
|
||||
this.quoteCode = quoteCode;
|
||||
this.fspFee = fspFee;
|
||||
this.fspCommission = fspCommission;
|
||||
}
|
||||
|
||||
public static InteropQuoteResponseData build(Long commandId, @NotNull String transactionCode, @NotNull InteropActionState state,
|
||||
LocalDateTime expiration, List<ExtensionData> extensionList, @NotNull String quoteCode,
|
||||
MoneyData fspFee, MoneyData fspCommission) {
|
||||
return new InteropQuoteResponseData(null, null, commandId, null, transactionCode, state, expiration, extensionList,
|
||||
quoteCode, fspFee, fspCommission);
|
||||
}
|
||||
|
||||
public static InteropQuoteResponseData build(@NotNull String transactionCode, @NotNull InteropActionState state, LocalDateTime expiration,
|
||||
List<ExtensionData> extensionList, @NotNull String quoteCode, MoneyData fspFee,
|
||||
MoneyData fspCommission) {
|
||||
return build(null, transactionCode, state, expiration, extensionList, quoteCode, fspFee, fspCommission);
|
||||
}
|
||||
|
||||
public static InteropQuoteResponseData build(Long commandId, @NotNull String transactionCode, @NotNull InteropActionState state,
|
||||
@NotNull String quoteCode) {
|
||||
return build(commandId, transactionCode, state, null, null, quoteCode, null, null);
|
||||
}
|
||||
|
||||
public static InteropQuoteResponseData build(@NotNull String transactionCode, @NotNull InteropActionState state, @NotNull String quoteCode) {
|
||||
return build(null, transactionCode, state, quoteCode);
|
||||
}
|
||||
|
||||
public String getQuoteCode() {
|
||||
return quoteCode;
|
||||
}
|
||||
|
||||
public MoneyData getFspFee() {
|
||||
return fspFee;
|
||||
}
|
||||
|
||||
public void setFspFee(MoneyData fspFee) {
|
||||
this.fspFee = fspFee;
|
||||
}
|
||||
|
||||
public MoneyData getFspCommission() {
|
||||
return fspCommission;
|
||||
}
|
||||
|
||||
public void setFspCommission(MoneyData fspCommission) {
|
||||
this.fspCommission = fspCommission;
|
||||
}
|
||||
}
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.interoperation.domain.InteropTransactionRole;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.*;
|
||||
|
||||
public class InteropRequestData {
|
||||
|
||||
@NotNull
|
||||
private final String transactionCode;
|
||||
|
||||
private final String requestCode;
|
||||
@NotNull
|
||||
private final String accountId;
|
||||
@NotNull
|
||||
private final MoneyData amount;
|
||||
@NotNull
|
||||
private final InteropTransactionRole transactionRole;
|
||||
|
||||
private final InteropTransactionTypeData transactionType;
|
||||
|
||||
private String note;
|
||||
|
||||
private GeoCodeData geoCode;
|
||||
|
||||
private LocalDateTime expiration;
|
||||
|
||||
private List<ExtensionData> extensionList;
|
||||
|
||||
protected InteropRequestData(@NotNull String transactionCode, String requestCode, @NotNull String accountId, @NotNull MoneyData amount,
|
||||
@NotNull InteropTransactionRole transactionRole, InteropTransactionTypeData transactionType, String note,
|
||||
GeoCodeData geoCode, LocalDateTime expiration, List<ExtensionData> extensionList) {
|
||||
this.transactionCode = transactionCode;
|
||||
this.requestCode = requestCode;
|
||||
this.accountId = accountId;
|
||||
this.amount = amount;
|
||||
this.transactionType = transactionType;
|
||||
this.transactionRole = transactionRole;
|
||||
this.note = note;
|
||||
this.geoCode = geoCode;
|
||||
this.expiration = expiration;
|
||||
this.extensionList = extensionList;
|
||||
}
|
||||
|
||||
protected InteropRequestData(@NotNull String transactionCode, @NotNull String accountId, @NotNull MoneyData amount, @NotNull InteropTransactionRole transactionRole) {
|
||||
this(transactionCode, null, accountId, amount, transactionRole, null, null, null, null, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getTransactionCode() {
|
||||
return transactionCode;
|
||||
}
|
||||
|
||||
public String getRequestCode() {
|
||||
return requestCode;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MoneyData getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public InteropTransactionTypeData getTransactionType() {
|
||||
return transactionType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public InteropTransactionRole getTransactionRole() {
|
||||
return transactionRole;
|
||||
}
|
||||
|
||||
public String getNote() {
|
||||
return note;
|
||||
}
|
||||
|
||||
public void setNote(String note) {
|
||||
this.note = note;
|
||||
}
|
||||
|
||||
public GeoCodeData getGeoCode() {
|
||||
return geoCode;
|
||||
}
|
||||
|
||||
public void setGeoCode(GeoCodeData geoCode) {
|
||||
this.geoCode = geoCode;
|
||||
}
|
||||
|
||||
public LocalDateTime getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
|
||||
public LocalDate getExpirationLocalDate() {
|
||||
return expiration == null ? null : expiration.toLocalDate();
|
||||
}
|
||||
|
||||
public void setExpiration(LocalDateTime expiration) {
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
||||
public List<ExtensionData> getExtensionList() {
|
||||
return extensionList;
|
||||
}
|
||||
|
||||
public void setExtensionList(List<ExtensionData> extensionList) {
|
||||
this.extensionList = extensionList;
|
||||
}
|
||||
|
||||
public void normalizeAmounts(@NotNull MonetaryCurrency currency) {
|
||||
amount.normalizeAmount(currency);
|
||||
}
|
||||
|
||||
public static InteropRequestData validateAndParse(final DataValidatorBuilder dataValidator, JsonObject element, FromJsonHelper jsonHelper) {
|
||||
if (element == null)
|
||||
return null;
|
||||
|
||||
String transactionCode = jsonHelper.extractStringNamed(PARAM_TRANSACTION_CODE, element);
|
||||
DataValidatorBuilder dataValidatorCopy = dataValidator.reset().parameter(PARAM_TRANSACTION_CODE).value(transactionCode).notBlank();
|
||||
|
||||
String requestCode = jsonHelper.extractStringNamed(PARAM_REQUEST_CODE, element);
|
||||
|
||||
String accountId = jsonHelper.extractStringNamed(PARAM_ACCOUNT_ID, element);
|
||||
dataValidatorCopy = dataValidatorCopy.reset().parameter(PARAM_ACCOUNT_ID).value(accountId).notBlank();
|
||||
|
||||
JsonObject moneyElement = jsonHelper.extractJsonObjectNamed(PARAM_AMOUNT, element);
|
||||
dataValidatorCopy = dataValidatorCopy.reset().parameter(PARAM_AMOUNT).value(moneyElement).notNull();
|
||||
dataValidator.merge(dataValidatorCopy);
|
||||
MoneyData amount = MoneyData.validateAndParse(dataValidator, moneyElement, jsonHelper);
|
||||
|
||||
JsonObject transactionTypeElement = jsonHelper.extractJsonObjectNamed(PARAM_TRANSACTION_TYPE, element);
|
||||
InteropTransactionTypeData transactionType = InteropTransactionTypeData.validateAndParse(dataValidator, transactionTypeElement, jsonHelper);
|
||||
|
||||
String transactionRoleString = jsonHelper.extractStringNamed(PARAM_TRANSACTION_ROLE, element);
|
||||
InteropTransactionRole transactionRole = transactionRoleString == null ? InteropTransactionRole.PAYER : InteropTransactionRole.valueOf(transactionRoleString);
|
||||
|
||||
String note = jsonHelper.extractStringNamed(PARAM_NOTE, element);
|
||||
|
||||
JsonObject geoCodeElement = jsonHelper.extractJsonObjectNamed(PARAM_GEO_CODE, element);
|
||||
GeoCodeData geoCode = GeoCodeData.validateAndParse(dataValidator, geoCodeElement, jsonHelper);
|
||||
|
||||
String locale = jsonHelper.extractStringNamed(PARAM_LOCALE, element);
|
||||
LocalDateTime expiration = locale == null
|
||||
? jsonHelper.extractLocalTimeNamed(PARAM_EXPIRATION, element, ISO8601_DATE_TIME_FORMAT, DEFAULT_LOCALE)
|
||||
: jsonHelper.extractLocalTimeNamed(PARAM_EXPIRATION, element); // PARAM_DATE_FORMAT also must be set
|
||||
|
||||
JsonArray extensionArray = jsonHelper.extractJsonArrayNamed(PARAM_EXTENSION_LIST, element);
|
||||
ArrayList<ExtensionData> extensionList = null;
|
||||
if (extensionArray != null) {
|
||||
extensionList = new ArrayList<>(extensionArray.size());
|
||||
for (JsonElement jsonElement : extensionArray) {
|
||||
if (jsonElement.isJsonObject())
|
||||
extensionList.add(ExtensionData.validateAndParse(dataValidator, jsonElement.getAsJsonObject(), jsonHelper));
|
||||
}
|
||||
}
|
||||
|
||||
return dataValidator.hasError() ? null : new InteropRequestData(transactionCode, requestCode, accountId, amount,
|
||||
transactionRole, transactionType, note, geoCode, expiration, extensionList);
|
||||
}
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.interoperation.domain.InteropActionState;
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.beans.Transient;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class InteropResponseData extends CommandProcessingResult {
|
||||
|
||||
public static final String ISO_DATE_TIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ssZ";
|
||||
// public static final SimpleDateFormat ISO_DATE_TIME_FORMATTER = new SimpleDateFormat(ISO_DATE_TIME_PATTERN); // TODO: not synchronized
|
||||
public static DateTimeFormatter ISO_DATE_TIME_FORMATTER = DateTimeFormat.forPattern(ISO_DATE_TIME_PATTERN);
|
||||
|
||||
@NotNull
|
||||
private final String transactionCode;
|
||||
|
||||
@NotNull
|
||||
private final InteropActionState state;
|
||||
|
||||
private final String expiration;
|
||||
|
||||
private final List<ExtensionData> extensionList;
|
||||
|
||||
|
||||
protected InteropResponseData(Long resourceId, Long officeId, Long commandId, Map<String, Object> changesOnly, @NotNull String transactionCode,
|
||||
@NotNull InteropActionState state, LocalDateTime expiration, List<ExtensionData> extensionList) {
|
||||
super(resourceId, officeId, commandId, changesOnly);
|
||||
this.transactionCode = transactionCode;
|
||||
this.state = state;
|
||||
this.expiration = format(expiration);
|
||||
this.extensionList = extensionList;
|
||||
}
|
||||
|
||||
protected static InteropResponseData build(Long commandId, @NotNull String transactionCode, @NotNull InteropActionState state,
|
||||
LocalDateTime expiration, List<ExtensionData> extensionList) {
|
||||
return new InteropResponseData(null, null, commandId, null, transactionCode, state, expiration, extensionList);
|
||||
}
|
||||
|
||||
public static InteropResponseData build(@NotNull String transactionCode, @NotNull InteropActionState state,
|
||||
LocalDateTime expiration, List<ExtensionData> extensionList) {
|
||||
return build(null, transactionCode, state, expiration, extensionList);
|
||||
}
|
||||
|
||||
public static InteropResponseData build(Long commandId, @NotNull String transactionCode, @NotNull InteropActionState state) {
|
||||
return build(commandId, transactionCode, state, null, null);
|
||||
}
|
||||
|
||||
public static InteropResponseData build(@NotNull String transactionCode, @NotNull InteropActionState state) {
|
||||
return build(null, transactionCode, state);
|
||||
}
|
||||
|
||||
public String getTransactionCode() {
|
||||
return transactionCode;
|
||||
}
|
||||
|
||||
public InteropActionState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public String getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
|
||||
@Transient
|
||||
public LocalDateTime getExpirationDate() {
|
||||
return parse(expiration);
|
||||
}
|
||||
|
||||
public List<ExtensionData> getExtensionList() {
|
||||
return extensionList;
|
||||
}
|
||||
|
||||
protected static LocalDateTime parse(String date) {
|
||||
return date == null ? null : LocalDateTime.parse(date, ISO_DATE_TIME_FORMATTER);
|
||||
}
|
||||
|
||||
protected static String format(LocalDateTime date) {
|
||||
return date == null ? null : date.toString(ISO_DATE_TIME_FORMATTER);
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.interoperation.domain.InteropTransactionRole;
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.*;
|
||||
|
||||
public class InteropTransactionRequestData extends InteropRequestData {
|
||||
|
||||
static final String[] PARAMS = {PARAM_TRANSACTION_CODE, PARAM_REQUEST_CODE, PARAM_ACCOUNT_ID, PARAM_AMOUNT, PARAM_TRANSACTION_ROLE,
|
||||
PARAM_TRANSACTION_TYPE, PARAM_NOTE, PARAM_GEO_CODE, PARAM_EXPIRATION, PARAM_EXTENSION_LIST, PARAM_LOCALE, PARAM_DATE_FORMAT};
|
||||
|
||||
|
||||
public InteropTransactionRequestData(@NotNull String transactionCode, @NotNull String requestCode, @NotNull String accountId,
|
||||
@NotNull MoneyData amount, @NotNull InteropTransactionTypeData transactionType, String note,
|
||||
GeoCodeData geoCode, LocalDateTime expiration, List<ExtensionData> extensionList) {
|
||||
super(transactionCode, requestCode, accountId, amount, InteropTransactionRole.PAYER, transactionType, note, geoCode, expiration, extensionList);
|
||||
}
|
||||
|
||||
public InteropTransactionRequestData(@NotNull String transactionCode, @NotNull String requestCode, @NotNull String accountId,
|
||||
@NotNull MoneyData amount, @NotNull InteropTransactionTypeData transactionType) {
|
||||
this(transactionCode, requestCode, accountId, amount, transactionType, null, null, null, null);
|
||||
}
|
||||
|
||||
private InteropTransactionRequestData(InteropRequestData other) {
|
||||
this(other.getTransactionCode(), other.getRequestCode(), other.getAccountId(), other.getAmount(), other.getTransactionType(),
|
||||
other.getNote(), other.getGeoCode(), other.getExpiration(), other.getExtensionList());
|
||||
}
|
||||
|
||||
public static InteropTransactionRequestData validateAndParse(final DataValidatorBuilder dataValidator, JsonObject element, FromJsonHelper jsonHelper) {
|
||||
if (element == null)
|
||||
return null;
|
||||
|
||||
jsonHelper.checkForUnsupportedParameters(element, Arrays.asList(PARAMS));
|
||||
|
||||
InteropRequestData interopRequestData = InteropRequestData.validateAndParse(dataValidator, element, jsonHelper);
|
||||
|
||||
DataValidatorBuilder dataValidatorCopy = dataValidator.reset().parameter(PARAM_REQUEST_CODE).value(interopRequestData.getRequestCode()).notNull();
|
||||
dataValidatorCopy = dataValidatorCopy.reset().parameter(PARAM_TRANSACTION_TYPE).value(interopRequestData.getTransactionType()).notNull();
|
||||
dataValidatorCopy = dataValidatorCopy.reset().parameter(PARAM_TRANSACTION_ROLE).value(interopRequestData.getTransactionRole()).ignoreIfNull()
|
||||
.isOneOfTheseValues(InteropTransactionRole.PAYER);
|
||||
|
||||
dataValidator.merge(dataValidatorCopy);
|
||||
return dataValidator.hasError() ? null : new InteropTransactionRequestData(interopRequestData);
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import org.apache.fineract.interoperation.domain.InteropActionState;
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class InteropTransactionRequestResponseData extends InteropResponseData {
|
||||
|
||||
@NotNull
|
||||
private final String requestCode;
|
||||
|
||||
|
||||
private InteropTransactionRequestResponseData(Long resourceId, Long officeId, Long commandId, Map<String, Object> changesOnly,
|
||||
@NotNull String transactionCode, @NotNull InteropActionState state, LocalDateTime expiration,
|
||||
List<ExtensionData> extensionList, @NotNull String requestCode) {
|
||||
super(resourceId, officeId, commandId, changesOnly, transactionCode, state, expiration, extensionList);
|
||||
this.requestCode = requestCode;
|
||||
}
|
||||
|
||||
public static InteropTransactionRequestResponseData build(Long commandId, @NotNull String transactionCode, @NotNull InteropActionState state,
|
||||
LocalDateTime expiration, List<ExtensionData> extensionList, @NotNull String requestCode) {
|
||||
return new InteropTransactionRequestResponseData(null, null, commandId, null, transactionCode, state, expiration, extensionList, requestCode);
|
||||
}
|
||||
|
||||
public static InteropTransactionRequestResponseData build(@NotNull String transactionCode, @NotNull InteropActionState state,
|
||||
LocalDateTime expiration, List<ExtensionData> extensionList, @NotNull String requestCode) {
|
||||
return build(null, transactionCode, state, expiration, extensionList, requestCode);
|
||||
}
|
||||
|
||||
public static InteropTransactionRequestResponseData build(Long commandId, @NotNull String transactionCode, @NotNull InteropActionState state,
|
||||
@NotNull String requestCode) {
|
||||
return build(commandId, transactionCode, state, null, null, requestCode);
|
||||
}
|
||||
|
||||
public static InteropTransactionRequestResponseData build(@NotNull String transactionCode, @NotNull InteropActionState state,
|
||||
@NotNull String requestCode) {
|
||||
return build(null, transactionCode, state, requestCode);
|
||||
}
|
||||
|
||||
public String getRequestCode() {
|
||||
return requestCode;
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.interoperation.domain.InteropInitiatorType;
|
||||
import org.apache.fineract.interoperation.domain.InteropTransactionRole;
|
||||
import org.apache.fineract.interoperation.domain.InteropTransactionScenario;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.PARAM_INITIATOR;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.PARAM_INITIATOR_TYPE;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.PARAM_SCENARIO;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.PARAM_SUB_SCENARIO;
|
||||
|
||||
public class InteropTransactionTypeData {
|
||||
|
||||
public static final String[] PARAMS = {PARAM_SCENARIO, PARAM_SUB_SCENARIO, PARAM_INITIATOR, PARAM_INITIATOR_TYPE};
|
||||
|
||||
@NotNull
|
||||
private final InteropTransactionScenario scenario;
|
||||
|
||||
private final String subScenario;
|
||||
@NotNull
|
||||
private final InteropTransactionRole initiator;
|
||||
@NotNull
|
||||
private final InteropInitiatorType initiatorType;
|
||||
|
||||
public InteropTransactionTypeData(InteropTransactionScenario scenario, String subScenario, InteropTransactionRole initiator, InteropInitiatorType initiatorType) {
|
||||
this.scenario = scenario;
|
||||
this.subScenario = subScenario;
|
||||
this.initiator = initiator;
|
||||
this.initiatorType = initiatorType;
|
||||
}
|
||||
|
||||
public InteropTransactionScenario getScenario() {
|
||||
return scenario;
|
||||
}
|
||||
|
||||
public String getSubScenario() {
|
||||
return subScenario;
|
||||
}
|
||||
|
||||
public InteropTransactionRole getInitiator() {
|
||||
return initiator;
|
||||
}
|
||||
|
||||
public InteropInitiatorType getInitiatorType() {
|
||||
return initiatorType;
|
||||
}
|
||||
|
||||
|
||||
public static InteropTransactionTypeData validateAndParse(DataValidatorBuilder dataValidator, JsonObject element, FromJsonHelper jsonHelper) {
|
||||
if (element == null)
|
||||
return null;
|
||||
|
||||
jsonHelper.checkForUnsupportedParameters(element, Arrays.asList(PARAMS));
|
||||
|
||||
String scenarioString = jsonHelper.extractStringNamed(PARAM_SCENARIO, element);
|
||||
DataValidatorBuilder dataValidatorCopy = dataValidator.reset().parameter(PARAM_SCENARIO).value(scenarioString).notBlank();
|
||||
InteropTransactionScenario scenario = InteropTransactionScenario.valueOf(scenarioString);
|
||||
|
||||
String subScenario = jsonHelper.extractStringNamed(PARAM_SUB_SCENARIO, element);
|
||||
|
||||
String initiatorString = jsonHelper.extractStringNamed(PARAM_INITIATOR, element);
|
||||
dataValidatorCopy = dataValidatorCopy.reset().parameter(PARAM_INITIATOR).value(initiatorString).notBlank();
|
||||
InteropTransactionRole initiator = InteropTransactionRole.valueOf(initiatorString);
|
||||
|
||||
String initiatorTypeString = jsonHelper.extractStringNamed(PARAM_INITIATOR_TYPE, element);
|
||||
dataValidatorCopy = dataValidatorCopy.reset().parameter(PARAM_INITIATOR_TYPE).value(initiatorTypeString).notBlank();
|
||||
InteropInitiatorType initiatorType = InteropInitiatorType.valueOf(initiatorTypeString);
|
||||
|
||||
dataValidator.merge(dataValidatorCopy);
|
||||
return dataValidator.hasError() ? null : new InteropTransactionTypeData(scenario, subScenario, initiator, initiatorType);
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.interoperation.domain.InteropTransactionRole;
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.*;
|
||||
|
||||
public class InteropTransferRequestData extends InteropRequestData {
|
||||
|
||||
static final String[] PARAMS = {PARAM_TRANSACTION_CODE, PARAM_ACCOUNT_ID, PARAM_AMOUNT, PARAM_TRANSACTION_ROLE, PARAM_TRANSACTION_TYPE,
|
||||
PARAM_NOTE, PARAM_EXPIRATION, PARAM_EXTENSION_LIST, PARAM_TRANSFER_CODE, PARAM_FSP_FEE, PARAM_FSP_COMMISSION,
|
||||
PARAM_LOCALE, PARAM_DATE_FORMAT};
|
||||
|
||||
|
||||
@NotNull
|
||||
private final String transferCode;
|
||||
|
||||
// validation: what was specified in quotes step
|
||||
private MoneyData fspFee;
|
||||
|
||||
private MoneyData fspCommission;
|
||||
|
||||
public InteropTransferRequestData(@NotNull String transactionCode, @NotNull String accountId, @NotNull MoneyData amount,
|
||||
@NotNull InteropTransactionRole transactionRole, InteropTransactionTypeData transactionType, String note, LocalDateTime expiration,
|
||||
List<ExtensionData> extensionList, @NotNull String transferCode, MoneyData fspFee, MoneyData fspCommission) {
|
||||
super(transactionCode, null, accountId, amount, transactionRole, transactionType, note, null, expiration, extensionList);
|
||||
this.transferCode = transferCode;
|
||||
this.fspFee = fspFee;
|
||||
this.fspCommission = fspCommission;
|
||||
}
|
||||
|
||||
public InteropTransferRequestData(@NotNull String transactionCode, @NotNull String transferCode, @NotNull String accountId,
|
||||
@NotNull MoneyData amount, @NotNull InteropTransactionRole transactionRole) {
|
||||
this(transactionCode, accountId, amount, transactionRole, null, null, null, null, transferCode, null, null);
|
||||
}
|
||||
|
||||
private InteropTransferRequestData(InteropRequestData other, @NotNull String transferCode, MoneyData fspFee, MoneyData fspCommission) {
|
||||
this(other.getTransactionCode(), other.getAccountId(), other.getAmount(), other.getTransactionRole(), other.getTransactionType(),
|
||||
other.getNote(), other.getExpiration(), other.getExtensionList(), transferCode, fspFee, fspCommission);
|
||||
}
|
||||
|
||||
public String getTransferCode() {
|
||||
return transferCode;
|
||||
}
|
||||
|
||||
public MoneyData getFspFee() {
|
||||
return fspFee;
|
||||
}
|
||||
|
||||
public MoneyData getFspCommission() {
|
||||
return fspCommission;
|
||||
}
|
||||
|
||||
public void normalizeAmounts(@NotNull MonetaryCurrency currency) {
|
||||
super.normalizeAmounts(currency);
|
||||
if (fspFee != null)
|
||||
fspFee.normalizeAmount(currency);
|
||||
}
|
||||
|
||||
public static InteropTransferRequestData validateAndParse(final DataValidatorBuilder dataValidator, JsonObject element, FromJsonHelper jsonHelper) {
|
||||
if (element == null)
|
||||
return null;
|
||||
|
||||
jsonHelper.checkForUnsupportedParameters(element, Arrays.asList(PARAMS));
|
||||
|
||||
InteropRequestData interopRequestData = InteropRequestData.validateAndParse(dataValidator, element, jsonHelper);
|
||||
|
||||
String transferCode = jsonHelper.extractStringNamed(PARAM_TRANSFER_CODE, element);
|
||||
DataValidatorBuilder dataValidatorCopy = dataValidator.reset().parameter(PARAM_TRANSFER_CODE).value(transferCode).notBlank();
|
||||
|
||||
JsonObject fspFeeElement = jsonHelper.extractJsonObjectNamed(PARAM_FSP_FEE, element);
|
||||
dataValidator.merge(dataValidatorCopy);
|
||||
MoneyData fspFee = MoneyData.validateAndParse(dataValidator, fspFeeElement, jsonHelper);
|
||||
|
||||
JsonObject fspCommissionElement = jsonHelper.extractJsonObjectNamed(PARAM_FSP_COMMISSION, element);
|
||||
dataValidator.merge(dataValidatorCopy);
|
||||
MoneyData fspCommission = MoneyData.validateAndParse(dataValidator, fspCommissionElement, jsonHelper);
|
||||
|
||||
String transactionRoleString = jsonHelper.extractStringNamed(PARAM_TRANSACTION_ROLE, element);
|
||||
dataValidatorCopy = dataValidator.reset().parameter(PARAM_TRANSACTION_ROLE).value(transactionRoleString).notNull();
|
||||
|
||||
dataValidator.merge(dataValidatorCopy);
|
||||
return dataValidator.hasError() ? null : new InteropTransferRequestData(interopRequestData, transferCode, fspFee, fspCommission);
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import org.apache.fineract.interoperation.domain.InteropActionState;
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.beans.Transient;
|
||||
import java.text.ParseException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class InteropTransferResponseData extends InteropResponseData {
|
||||
|
||||
@NotNull
|
||||
private final String transferCode;
|
||||
|
||||
private String completedTimestamp;
|
||||
|
||||
private InteropTransferResponseData(Long resourceId, Long officeId, Long commandId, Map<String, Object> changesOnly,
|
||||
@NotNull String transactionCode, @NotNull InteropActionState state, LocalDateTime expiration,
|
||||
List<ExtensionData> extensionList, @NotNull String transferCode, LocalDateTime completedTimestamp) {
|
||||
super(resourceId, officeId, commandId, changesOnly, transactionCode, state, expiration, extensionList);
|
||||
this.transferCode = transferCode;
|
||||
this.completedTimestamp = format(completedTimestamp);
|
||||
}
|
||||
|
||||
public static InteropTransferResponseData build(Long commandId, @NotNull String transactionCode, @NotNull InteropActionState state,
|
||||
LocalDateTime expiration, List<ExtensionData> extensionList, @NotNull String transferCode,
|
||||
LocalDateTime completedTimestamp) {
|
||||
return new InteropTransferResponseData(null, null, commandId, null, transactionCode, state, expiration, extensionList,
|
||||
transferCode, completedTimestamp);
|
||||
}
|
||||
|
||||
public static InteropTransferResponseData build(@NotNull String transactionCode, @NotNull InteropActionState state,
|
||||
List<ExtensionData> extensionList, @NotNull String transferCode,
|
||||
LocalDateTime completedTimestamp) {
|
||||
return build(null, transactionCode, state, null, extensionList, transferCode, completedTimestamp);
|
||||
}
|
||||
|
||||
public static InteropTransferResponseData build(Long commandId, @NotNull String transactionCode, @NotNull InteropActionState state,
|
||||
@NotNull String transferCode) {
|
||||
return build(commandId, transactionCode, state, null, null, transferCode, null);
|
||||
}
|
||||
|
||||
public static InteropTransferResponseData build(@NotNull String transactionCode, @NotNull InteropActionState state, @NotNull String transferCode) {
|
||||
return build(null, transactionCode, state, transferCode);
|
||||
}
|
||||
|
||||
public String getTransferCode() {
|
||||
return transferCode;
|
||||
}
|
||||
|
||||
public String getCompletedTimestamp() {
|
||||
return completedTimestamp;
|
||||
}
|
||||
|
||||
@Transient
|
||||
public LocalDateTime getCompletedTimestampDate() throws ParseException {
|
||||
return parse(completedTimestamp);
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.data;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.interoperation.util.MathUtil;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.DEFAULT_LOCALE;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.PARAM_AMOUNT;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.PARAM_CURRENCY;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.PARAM_LOCALE;
|
||||
|
||||
public class MoneyData {
|
||||
|
||||
public static final String[] PARAMS = {PARAM_AMOUNT, PARAM_CURRENCY, PARAM_LOCALE};
|
||||
|
||||
@NotNull
|
||||
private final BigDecimal amount;
|
||||
@NotNull
|
||||
private final String currency;
|
||||
|
||||
MoneyData(BigDecimal amount, String currency) {
|
||||
this.amount = amount;
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
public static MoneyData build(BigDecimal amount, String currency) {
|
||||
return new MoneyData(amount, currency);
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public String getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
public void normalizeAmount(@NotNull MonetaryCurrency currency) {
|
||||
if (!currency.getCode().equals(this.currency))
|
||||
throw new UnsupportedOperationException("Internal error: Invalid currency " + currency.getCode());
|
||||
MathUtil.normalizeAmount(amount, currency);
|
||||
}
|
||||
|
||||
public static MoneyData validateAndParse(DataValidatorBuilder dataValidator, JsonObject element, FromJsonHelper jsonHelper) {
|
||||
if (element == null)
|
||||
return null;
|
||||
|
||||
jsonHelper.checkForUnsupportedParameters(element, Arrays.asList(PARAMS));
|
||||
|
||||
String locale = jsonHelper.extractStringNamed(PARAM_LOCALE, element);
|
||||
BigDecimal amount = locale == null
|
||||
? jsonHelper.extractBigDecimalNamed(PARAM_AMOUNT, element, DEFAULT_LOCALE)
|
||||
: jsonHelper.extractBigDecimalWithLocaleNamed(PARAM_AMOUNT, element);
|
||||
DataValidatorBuilder dataValidatorCopy = dataValidator.reset().parameter(PARAM_AMOUNT).value(amount).notBlank().zeroOrPositiveAmount();
|
||||
|
||||
String currency = jsonHelper.extractStringNamed(PARAM_CURRENCY, element);
|
||||
dataValidatorCopy = dataValidatorCopy.reset().parameter(PARAM_CURRENCY).value(currency).notBlank().notExceedingLengthOf(3);
|
||||
|
||||
dataValidator.merge(dataValidatorCopy);
|
||||
return dataValidator.hasError() ? null : new MoneyData(amount, currency);
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.domain;
|
||||
|
||||
public enum InteropActionState {
|
||||
ACCEPTED,
|
||||
REJECTED
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.domain;
|
||||
|
||||
public enum InteropAmountType {
|
||||
SEND,
|
||||
RECEIVE
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.domain;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
@Table(name = "interop_identifier", uniqueConstraints = {
|
||||
@UniqueConstraint(name = "uk_hathor_identifier_account", columnNames = {"account_id", "type"}),
|
||||
@UniqueConstraint(name = "uk_hathor_identifier_value", columnNames = {"type", "a_value", "sub_value_or_type"})
|
||||
})
|
||||
public class InteropIdentifier extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "account_id", nullable = false)
|
||||
private SavingsAccount account;
|
||||
|
||||
@Column(name = "type", nullable = false, length = 32)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private InteropIdentifierType type;
|
||||
|
||||
@Column(name = "a_value", nullable = false, length = 128)
|
||||
private String value;
|
||||
|
||||
@Column(name = "sub_value_or_type", length = 128)
|
||||
private String subValueOrType;
|
||||
|
||||
@Column(name = "created_by", nullable = false, length = 32)
|
||||
private String createdBy;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "created_on", nullable = false)
|
||||
private Date createdOn;
|
||||
|
||||
@Column(name = "modified_by", length = 32)
|
||||
private String modifiedBy;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "modified_on")
|
||||
private Date modifiedOn;
|
||||
|
||||
|
||||
protected InteropIdentifier() {
|
||||
}
|
||||
|
||||
public InteropIdentifier(@NotNull SavingsAccount account, @NotNull InteropIdentifierType type, @NotNull String value,
|
||||
String subValueOrType, @NotNull String createdBy, @NotNull Date createdOn) {
|
||||
this.account = account;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
this.subValueOrType = subValueOrType;
|
||||
this.createdBy = createdBy;
|
||||
this.createdOn = createdOn;
|
||||
}
|
||||
|
||||
public InteropIdentifier(@NotNull SavingsAccount account, @NotNull InteropIdentifierType type, @NotNull String createdBy,
|
||||
@NotNull Date createdOn) {
|
||||
this(account, type, null, null, createdBy, createdOn);
|
||||
}
|
||||
|
||||
public SavingsAccount getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
private void setAccount(SavingsAccount account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
public InteropIdentifierType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
private void setType(InteropIdentifierType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getSubValueOrType() {
|
||||
return subValueOrType;
|
||||
}
|
||||
|
||||
public void setSubValueOrType(String subValueOrType) {
|
||||
this.subValueOrType = subValueOrType;
|
||||
}
|
||||
|
||||
public String getCreatedBy() {
|
||||
return createdBy;
|
||||
}
|
||||
|
||||
private void setCreatedBy(String createdBy) {
|
||||
this.createdBy = createdBy;
|
||||
}
|
||||
|
||||
public Date getCreatedOn() {
|
||||
return createdOn;
|
||||
}
|
||||
|
||||
private void setCreatedOn(Date createdOn) {
|
||||
this.createdOn = createdOn;
|
||||
}
|
||||
|
||||
public String geModifiedBy() {
|
||||
return modifiedBy;
|
||||
}
|
||||
|
||||
public void setModifiedBy(String modifiedBy) {
|
||||
this.modifiedBy = modifiedBy;
|
||||
}
|
||||
|
||||
public Date getModifiedOn() {
|
||||
return modifiedOn;
|
||||
}
|
||||
|
||||
public void setModifiedOn(Date modifiedOn) {
|
||||
this.modifiedOn = modifiedOn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
InteropIdentifier that = (InteropIdentifier) o;
|
||||
|
||||
if (!account.equals(that.account)) return false;
|
||||
if (type != that.type) return false;
|
||||
if (!value.equals(that.value)) return false;
|
||||
return subValueOrType != null ? subValueOrType.equals(that.subValueOrType) : that.subValueOrType == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = type.hashCode();
|
||||
result = 31 * result + value.hashCode();
|
||||
result = 31 * result + (subValueOrType != null ? subValueOrType.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface InteropIdentifierRepository extends JpaRepository<InteropIdentifier, Long>, JpaSpecificationExecutor<InteropIdentifier> {
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.domain;
|
||||
|
||||
public enum InteropIdentifierType {
|
||||
|
||||
MSISDN,
|
||||
EMAIL,
|
||||
PERSONAL_ID,
|
||||
BUSINESS,
|
||||
DEVICE,
|
||||
ACCOUNT_ID,
|
||||
IBAN,
|
||||
ALIAS
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.domain;
|
||||
|
||||
public enum InteropInitiatorType {
|
||||
CONSUMER,
|
||||
AGENT,
|
||||
BUSINESS,
|
||||
DEVICE
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.domain;
|
||||
|
||||
import org.apache.fineract.portfolio.savings.SavingsAccountTransactionType;
|
||||
|
||||
public enum InteropTransactionRole {
|
||||
PAYER,
|
||||
PAYEE,
|
||||
;
|
||||
|
||||
public boolean isWithdraw() {
|
||||
return this == PAYER;
|
||||
}
|
||||
|
||||
public SavingsAccountTransactionType getTransactionType() {
|
||||
return this == PAYER ? SavingsAccountTransactionType.WITHDRAWAL : SavingsAccountTransactionType.DEPOSIT;
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.domain;
|
||||
|
||||
public enum InteropTransactionScenario {
|
||||
|
||||
DEPOSIT,
|
||||
WITHDRAWAL,
|
||||
TRANSFER,
|
||||
PAYMENT,
|
||||
REFUND
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.domain;
|
||||
|
||||
public enum InteropTransferActionType {
|
||||
|
||||
PREPARE,
|
||||
CREATE,
|
||||
;
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.handler;
|
||||
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.interoperation.service.InteropService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ACTION_TRANSFER_COMMIT;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ENTITY_NAME_TRANSFER;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = ENTITY_NAME_TRANSFER, action = ACTION_TRANSFER_COMMIT)
|
||||
public class CommitInteropTransferHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final InteropService interopService;
|
||||
|
||||
@Autowired
|
||||
public CommitInteropTransferHandler(InteropService interopService) {
|
||||
this.interopService = interopService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.interopService.commitTransfer(command);
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.handler;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
|
||||
import org.apache.fineract.interoperation.service.InteropService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ENTITY_NAME_IDENTIFIER;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ENTITY_NAME_REQUEST;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = ENTITY_NAME_IDENTIFIER, action = "CREATE")
|
||||
public class CreateInteropIdentifierHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final InteropService interopService;
|
||||
|
||||
@Autowired
|
||||
public CreateInteropIdentifierHandler(InteropService interopService) {
|
||||
this.interopService = interopService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
String[] split = command.getUrl().split("/");
|
||||
int length = split.length;
|
||||
String subIdOrType = Strings.emptyToNull(StringUtils.trimWhitespace(split[length - 1]));
|
||||
String idValue = split[length - 2];
|
||||
InteropIdentifierType idType = InteropIdentifierType.valueOf(split[length - 3].toUpperCase());
|
||||
return this.interopService.registerAccountIdentifier(idType, idValue, subIdOrType, command);
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.handler;
|
||||
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.interoperation.service.InteropService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ENTITY_NAME_QUOTE;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = ENTITY_NAME_QUOTE, action = "CREATE")
|
||||
public class CreateInteropQuoteHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final InteropService interopService;
|
||||
|
||||
@Autowired
|
||||
public CreateInteropQuoteHandler(InteropService interopService) {
|
||||
this.interopService = interopService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.interopService.createQuote(command);
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.handler;
|
||||
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
|
||||
import org.apache.fineract.interoperation.service.InteropService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ENTITY_NAME_REQUEST;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = ENTITY_NAME_REQUEST, action = "CREATE")
|
||||
public class CreateInteropRequestHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final InteropService interopService;
|
||||
|
||||
@Autowired
|
||||
public CreateInteropRequestHandler(InteropService interopService) {
|
||||
this.interopService = interopService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.interopService.createTransactionRequest(command);
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.handler;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
|
||||
import org.apache.fineract.interoperation.service.InteropService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ENTITY_NAME_IDENTIFIER;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = ENTITY_NAME_IDENTIFIER, action = "DELETE")
|
||||
public class DeleteInteropIdentifierHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final InteropService interopService;
|
||||
|
||||
@Autowired
|
||||
public DeleteInteropIdentifierHandler(InteropService interopService) {
|
||||
this.interopService = interopService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
String[] split = command.getUrl().split("/");
|
||||
int length = split.length;
|
||||
String subIdOrType = Strings.emptyToNull(StringUtils.trimWhitespace(split[length - 1]));
|
||||
String idValue = split[length - 2];
|
||||
InteropIdentifierType idType = InteropIdentifierType.valueOf(split[length - 3].toUpperCase());
|
||||
return this.interopService.deleteAccountIdentifier(idType, idValue, subIdOrType);
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.handler;
|
||||
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.interoperation.service.InteropService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ACTION_TRANSFER_PREPARE;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ENTITY_NAME_TRANSFER;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = ENTITY_NAME_TRANSFER, action = ACTION_TRANSFER_PREPARE)
|
||||
public class PrepareInteropTransferHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final InteropService interopService;
|
||||
|
||||
@Autowired
|
||||
public PrepareInteropTransferHandler(InteropService interopService) {
|
||||
this.interopService = interopService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.interopService.prepareTransfer(command);
|
||||
}
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.serialization;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.interoperation.data.InteropIdentifierRequestData;
|
||||
import org.apache.fineract.interoperation.data.InteropQuoteRequestData;
|
||||
import org.apache.fineract.interoperation.data.InteropTransactionRequestData;
|
||||
import org.apache.fineract.interoperation.data.InteropTransferRequestData;
|
||||
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@Component
|
||||
public class InteropDataValidator {
|
||||
|
||||
private final FromJsonHelper jsonHelper;
|
||||
|
||||
@Autowired
|
||||
public InteropDataValidator(final FromJsonHelper fromJsonHelper) {
|
||||
this.jsonHelper = fromJsonHelper;
|
||||
}
|
||||
|
||||
public InteropIdentifierRequestData validateAndParseCreateIdentifier(@NotNull InteropIdentifierType idType, @NotNull String idValue,
|
||||
String subIdOrType, JsonCommand command) {
|
||||
final DataValidatorBuilder dataValidator = new DataValidatorBuilder(new ArrayList<>()).resource("interoperation.identifier");
|
||||
JsonObject element = extractJsonObject(command);
|
||||
|
||||
InteropIdentifierRequestData result = InteropIdentifierRequestData.validateAndParse(dataValidator, idType, idValue, subIdOrType, element, jsonHelper);
|
||||
throwExceptionIfValidationWarningsExist(dataValidator);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public InteropTransactionRequestData validateAndParseCreateRequest(JsonCommand command) {
|
||||
final DataValidatorBuilder dataValidator = new DataValidatorBuilder(new ArrayList<>()).resource("interoperation.request");
|
||||
JsonObject element = extractJsonObject(command);
|
||||
|
||||
InteropTransactionRequestData result = InteropTransactionRequestData.validateAndParse(dataValidator, element, jsonHelper);
|
||||
throwExceptionIfValidationWarningsExist(dataValidator);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public InteropQuoteRequestData validateAndParseCreateQuote(JsonCommand command) {
|
||||
final DataValidatorBuilder dataValidator = new DataValidatorBuilder(new ArrayList<>()).resource("interoperation.quote");
|
||||
JsonObject element = extractJsonObject(command);
|
||||
|
||||
InteropQuoteRequestData result = InteropQuoteRequestData.validateAndParse(dataValidator, element, jsonHelper);
|
||||
throwExceptionIfValidationWarningsExist(dataValidator);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public InteropTransferRequestData validateAndParsePrepareTransfer(JsonCommand command) {
|
||||
return validateAndParseCreateTransfer(command);
|
||||
}
|
||||
|
||||
public InteropTransferRequestData validateAndParseCreateTransfer(JsonCommand command) {
|
||||
final DataValidatorBuilder dataValidator = new DataValidatorBuilder(new ArrayList<>()).resource("interoperation.transfer");
|
||||
JsonObject element = extractJsonObject(command);
|
||||
|
||||
InteropTransferRequestData result = InteropTransferRequestData.validateAndParse(dataValidator, element, jsonHelper);
|
||||
throwExceptionIfValidationWarningsExist(dataValidator);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private JsonObject extractJsonObject(JsonCommand command) {
|
||||
String json = command.json();
|
||||
if (StringUtils.isBlank(json))
|
||||
throw new InvalidJsonException();
|
||||
|
||||
final JsonElement element = jsonHelper.parse(json);
|
||||
return element.getAsJsonObject();
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(DataValidatorBuilder dataValidator) {
|
||||
if (dataValidator.hasError()) {
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidator.getDataValidationErrors());
|
||||
}
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.service;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.interoperation.data.InteropIdentifierResponseData;
|
||||
import org.apache.fineract.interoperation.data.InteropQuoteResponseData;
|
||||
import org.apache.fineract.interoperation.data.InteropTransactionRequestResponseData;
|
||||
import org.apache.fineract.interoperation.data.InteropTransferResponseData;
|
||||
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public interface InteropService {
|
||||
|
||||
@NotNull
|
||||
InteropIdentifierResponseData getAccountByIdentifier(@NotNull InteropIdentifierType idType, @NotNull String idValue, String subIdOrType);
|
||||
|
||||
@NotNull
|
||||
InteropIdentifierResponseData registerAccountIdentifier(@NotNull InteropIdentifierType idType, @NotNull String idValue,
|
||||
String subIdOrType, @NotNull JsonCommand command);
|
||||
|
||||
@NotNull
|
||||
InteropIdentifierResponseData deleteAccountIdentifier(@NotNull InteropIdentifierType idType, @NotNull String idValue,
|
||||
String subIdOrType);
|
||||
|
||||
InteropTransactionRequestResponseData getTransactionRequest(@NotNull String transactionCode, @NotNull String requestCode);
|
||||
|
||||
@NotNull
|
||||
InteropTransactionRequestResponseData createTransactionRequest(@NotNull JsonCommand command);
|
||||
|
||||
InteropQuoteResponseData getQuote(@NotNull String transactionCode, @NotNull String quoteCode);
|
||||
|
||||
@NotNull
|
||||
InteropQuoteResponseData createQuote(@NotNull JsonCommand command);
|
||||
|
||||
InteropTransferResponseData getTransfer(@NotNull String transactionCode, @NotNull String transferCode);
|
||||
|
||||
@NotNull
|
||||
InteropTransferResponseData prepareTransfer(@NotNull JsonCommand command);
|
||||
|
||||
@NotNull
|
||||
InteropTransferResponseData commitTransfer(@NotNull JsonCommand command);
|
||||
}
|
||||
+429
@@ -0,0 +1,429 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.service;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.interoperation.data.*;
|
||||
import org.apache.fineract.interoperation.domain.InteropIdentifier;
|
||||
import org.apache.fineract.interoperation.domain.InteropIdentifierRepository;
|
||||
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
|
||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrencyRepository;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.interoperation.domain.InteropActionState;
|
||||
import org.apache.fineract.interoperation.serialization.InteropDataValidator;
|
||||
import org.apache.fineract.interoperation.util.MathUtil;
|
||||
import org.apache.fineract.portfolio.note.domain.Note;
|
||||
import org.apache.fineract.portfolio.note.domain.NoteRepository;
|
||||
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.apache.fineract.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
|
||||
import org.apache.fineract.portfolio.paymenttype.domain.PaymentType;
|
||||
import org.apache.fineract.portfolio.paymenttype.domain.PaymentTypeRepository;
|
||||
import org.apache.fineract.portfolio.savings.SavingsAccountTransactionType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsTransactionBooleanValues;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountDomainService;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepository;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransactionRepository;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransactionSummaryWrapper;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsHelper;
|
||||
import org.apache.fineract.portfolio.savings.exception.SavingsAccountNotFoundException;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.data.jpa.domain.Specifications;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Path;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.DEFAULT_LOCALE;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.DEFAULT_ROUTING_CODE;
|
||||
import static org.apache.fineract.interoperation.util.InteropUtil.ISO8601_DATE_TIME_FORMAT;
|
||||
|
||||
@Service
|
||||
public class InteropServiceImpl implements InteropService {
|
||||
|
||||
private final static Logger LOG = LoggerFactory.getLogger(InteropServiceImpl.class);
|
||||
|
||||
private final PlatformSecurityContext securityContext;
|
||||
private final InteropDataValidator dataValidator;
|
||||
|
||||
private final SavingsAccountRepository savingsAccountRepository;
|
||||
private final SavingsAccountTransactionRepository savingsAccountTransactionRepository;
|
||||
private final ApplicationCurrencyRepository currencyRepository;
|
||||
private final NoteRepository noteRepository;
|
||||
private final PaymentTypeRepository paymentTypeRepository;
|
||||
private final InteropIdentifierRepository identifierRepository;
|
||||
|
||||
private final SavingsHelper savingsHelper;
|
||||
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
|
||||
|
||||
private final SavingsAccountDomainService savingsAccountService;
|
||||
private final PaymentDetailWritePlatformService paymentDetailService;
|
||||
|
||||
@Autowired
|
||||
public InteropServiceImpl(PlatformSecurityContext securityContext,
|
||||
InteropDataValidator interopDataValidator,
|
||||
SavingsAccountRepository savingsAccountRepository,
|
||||
SavingsAccountTransactionRepository savingsAccountTransactionRepository,
|
||||
ApplicationCurrencyRepository applicationCurrencyRepository,
|
||||
NoteRepository noteRepository,
|
||||
PaymentTypeRepository paymentTypeRepository,
|
||||
InteropIdentifierRepository identifierRepository,
|
||||
SavingsHelper savingsHelper,
|
||||
SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper,
|
||||
SavingsAccountDomainService savingsAccountService,
|
||||
PaymentDetailWritePlatformService paymentDetailWritePlatformService) {
|
||||
this.securityContext = securityContext;
|
||||
this.dataValidator = interopDataValidator;
|
||||
this.savingsAccountRepository = savingsAccountRepository;
|
||||
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
|
||||
this.currencyRepository = applicationCurrencyRepository;
|
||||
this.noteRepository = noteRepository;
|
||||
this.paymentTypeRepository = paymentTypeRepository;
|
||||
this.identifierRepository = identifierRepository;
|
||||
this.savingsHelper = savingsHelper;
|
||||
this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
|
||||
this.savingsAccountService = savingsAccountService;
|
||||
this.paymentDetailService = paymentDetailWritePlatformService;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Transactional
|
||||
public InteropIdentifierResponseData getAccountByIdentifier(@NotNull InteropIdentifierType idType, @NotNull String idValue, String subIdOrType) {
|
||||
InteropIdentifier identifier = findIdentifier(idType, idValue, subIdOrType);
|
||||
if (identifier == null)
|
||||
throw new UnsupportedOperationException("Account not found for identifier " + idType + "/" + idValue + (subIdOrType == null ? "" : ("/" + subIdOrType)));
|
||||
|
||||
return InteropIdentifierResponseData.build(identifier.getAccount().getExternalId());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Transactional(propagation = Propagation.MANDATORY)
|
||||
public InteropIdentifierResponseData registerAccountIdentifier(@NotNull InteropIdentifierType idType, @NotNull String idValue,
|
||||
String subIdOrType, @NotNull JsonCommand command) {
|
||||
InteropIdentifierRequestData request = dataValidator.validateAndParseCreateIdentifier(idType, idValue, subIdOrType, command);
|
||||
//TODO: error handling
|
||||
SavingsAccount savingsAccount = validateAndGetSavingAccount(request.getAccountId());
|
||||
|
||||
AppUser createdBy = getLoginUser();
|
||||
|
||||
InteropIdentifier identifier = new InteropIdentifier(savingsAccount, request.getIdType(), request.getIdValue(),
|
||||
request.getSubIdOrType(), createdBy.getUsername(), DateUtils.getDateOfTenant());
|
||||
|
||||
identifierRepository.save(identifier);
|
||||
|
||||
return InteropIdentifierResponseData.build(savingsAccount.getExternalId());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Transactional(propagation = Propagation.MANDATORY)
|
||||
public InteropIdentifierResponseData deleteAccountIdentifier(@NotNull InteropIdentifierType idType, @NotNull String idValue,
|
||||
String subIdOrType) {
|
||||
InteropIdentifier identifier = findIdentifier(idType, idValue, subIdOrType);
|
||||
if (identifier == null)
|
||||
throw new UnsupportedOperationException("Account not found for identifier " + idType + "/" + idValue + (subIdOrType == null ? "" : ("/" + subIdOrType)));
|
||||
|
||||
String accountId = identifier.getAccount().getExternalId();
|
||||
|
||||
identifierRepository.delete(identifier);
|
||||
|
||||
return InteropIdentifierResponseData.build(accountId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteropTransactionRequestResponseData getTransactionRequest(@NotNull String transactionCode, @NotNull String requestCode) {
|
||||
// always REJECTED until request info is stored
|
||||
return InteropTransactionRequestResponseData.build(transactionCode, InteropActionState.REJECTED, requestCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@Transactional(propagation = Propagation.MANDATORY)
|
||||
public InteropTransactionRequestResponseData createTransactionRequest(@NotNull JsonCommand command) {
|
||||
// only when Payee request transaction from Payer, so here role must be always Payer
|
||||
InteropTransactionRequestData request = dataValidator.validateAndParseCreateRequest(command);
|
||||
|
||||
//TODO: error handling
|
||||
SavingsAccount savingsAccount = validateAndGetSavingAccount(request);
|
||||
|
||||
return InteropTransactionRequestResponseData.build(command.commandId(), request.getTransactionCode(), InteropActionState.ACCEPTED,
|
||||
request.getExpiration(), request.getExtensionList(), request.getRequestCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteropQuoteResponseData getQuote(@NotNull String transactionCode, @NotNull String quoteCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@Transactional(propagation = Propagation.MANDATORY)
|
||||
public InteropQuoteResponseData createQuote(@NotNull JsonCommand command) {
|
||||
InteropQuoteRequestData request = dataValidator.validateAndParseCreateQuote(command);
|
||||
|
||||
//TODO: error handling
|
||||
SavingsAccount savingsAccount = validateAndGetSavingAccount(request);
|
||||
SavingsAccountTransactionType transactionType = request.getTransactionRole().getTransactionType();
|
||||
|
||||
BigDecimal fee = transactionType.isDebit() ? savingsAccount.calculateWithdrawalFee(request.getAmount().getAmount()) : BigDecimal.ZERO;
|
||||
|
||||
return InteropQuoteResponseData.build(command.commandId(), request.getTransactionCode(), InteropActionState.ACCEPTED,
|
||||
request.getExpiration(), request.getExtensionList(), request.getQuoteCode(), MoneyData.build(fee, savingsAccount.getCurrency().getCode()),
|
||||
null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteropTransferResponseData getTransfer(@NotNull String transactionCode, @NotNull String transferCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@Transactional(propagation = Propagation.MANDATORY)
|
||||
public InteropTransferResponseData prepareTransfer(@NotNull JsonCommand command) {
|
||||
InteropTransferRequestData request = dataValidator.validateAndParsePrepareTransfer(command);
|
||||
|
||||
//TODO: error handling
|
||||
//TODO: REVERSE
|
||||
SavingsAccount savingsAccount = validateAndGetSavingAccount(request);
|
||||
|
||||
BigDecimal total = validateTransfer(request, savingsAccount);
|
||||
|
||||
String transferCode = request.getTransferCode();
|
||||
LocalDateTime transactionDate = DateUtils.getLocalDateTimeOfTenant();
|
||||
if (MathUtil.isGreaterThanZero(total)) {
|
||||
if (MathUtil.isLessThan(savingsAccount.getWithdrawableBalance(), total)) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (findTransaction(savingsAccount, transferCode, SavingsAccountTransactionType.AMOUNT_HOLD) != null)
|
||||
throw new UnsupportedOperationException("Transfer amount was already put on hold " + transferCode);
|
||||
|
||||
PaymentDetail paymentDetail = PaymentDetail.instance(findPaymentType(), savingsAccount.getExternalId(), null, getRoutingCode(), transferCode, null);
|
||||
AppUser appUser = getLoginUser();
|
||||
SavingsAccountTransaction transaction = SavingsAccountTransaction.holdAmount(savingsAccount, savingsAccount.office(),
|
||||
paymentDetail, transactionDate.toLocalDate(), Money.of(savingsAccount.getCurrency(), total), new Date(),
|
||||
appUser);
|
||||
|
||||
savingsAccount.holdAmount(total);
|
||||
savingsAccount.addTransaction(transaction);
|
||||
|
||||
savingsAccountRepository.save(savingsAccount);
|
||||
}
|
||||
|
||||
return InteropTransferResponseData.build(command.commandId(), request.getTransactionCode(), InteropActionState.ACCEPTED, request.getExpiration(),
|
||||
request.getExtensionList(), transferCode, transactionDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@Transactional(propagation = Propagation.MANDATORY)
|
||||
public InteropTransferResponseData commitTransfer(@NotNull JsonCommand command) {
|
||||
InteropTransferRequestData request = dataValidator.validateAndParseCreateTransfer(command);
|
||||
SavingsAccountTransactionType transactionType = request.getTransactionRole().getTransactionType();
|
||||
boolean debit = transactionType.isDebit();
|
||||
|
||||
//TODO: error handling
|
||||
//TODO: REVERSE
|
||||
SavingsAccount savingsAccount = validateAndGetSavingAccount(request);
|
||||
|
||||
validateTransfer(request, savingsAccount);
|
||||
|
||||
String transferCode = request.getTransferCode();
|
||||
if (findTransaction(savingsAccount, transferCode, debit ? SavingsAccountTransactionType.WITHDRAWAL : SavingsAccountTransactionType.DEPOSIT) != null)
|
||||
throw new UnsupportedOperationException("Transfer was already committed " + transferCode);
|
||||
|
||||
PaymentDetail paymentDetail = PaymentDetail.instance(findPaymentType(), savingsAccount.getExternalId(), null, getRoutingCode(), transferCode, null);
|
||||
|
||||
LocalDateTime transactionDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||
LocalDate transactionDate = transactionDateTime.toLocalDate();
|
||||
Date createdDate = new Date();
|
||||
|
||||
SavingsAccountTransaction holdTransaction = findTransaction(savingsAccount, transferCode, SavingsAccountTransactionType.AMOUNT_HOLD);
|
||||
if (holdTransaction != null && holdTransaction.getReleaseIdOfHoldAmountTransaction() == null) {
|
||||
AppUser appUser = getLoginUser();
|
||||
|
||||
SavingsAccountTransaction releaseTransaction = SavingsAccountTransaction.releaseAmount(holdTransaction, transactionDate, createdDate, appUser);
|
||||
releaseTransaction = savingsAccountTransactionRepository.saveAndFlush(releaseTransaction);
|
||||
holdTransaction.updateReleaseId(releaseTransaction.getId());
|
||||
|
||||
savingsAccount.releaseAmount(holdTransaction.getAmount());
|
||||
savingsAccount.addTransaction(releaseTransaction);
|
||||
|
||||
savingsAccountRepository.save(savingsAccount);
|
||||
}
|
||||
|
||||
BigDecimal amount = request.getAmount().getAmount();
|
||||
DateTimeFormatter fmt = getDateTimeFormatter(command);
|
||||
|
||||
SavingsAccountTransaction transaction;
|
||||
if (debit) {
|
||||
SavingsTransactionBooleanValues transactionValues = new SavingsTransactionBooleanValues(false, true, true, false, false);
|
||||
transaction = savingsAccountService.handleWithdrawal(savingsAccount, fmt, transactionDate, amount,
|
||||
paymentDetail, transactionValues);
|
||||
}
|
||||
else {
|
||||
transaction = savingsAccountService.handleDeposit(savingsAccount, fmt, transactionDate, amount,
|
||||
paymentDetail, false, true);
|
||||
}
|
||||
|
||||
String note = request.getNote();
|
||||
if (!StringUtils.isBlank(note)) {
|
||||
noteRepository.save(Note.savingsTransactionNote(savingsAccount, transaction, note));
|
||||
}
|
||||
|
||||
return InteropTransferResponseData.build(command.commandId(), request.getTransactionCode(), InteropActionState.ACCEPTED,
|
||||
request.getExpiration(), request.getExtensionList(), request.getTransferCode(), transactionDateTime);
|
||||
}
|
||||
|
||||
// Util
|
||||
|
||||
private SavingsAccount validateAndGetSavingAccount(String accountId) {
|
||||
SavingsAccount savingsAccount = savingsAccountRepository.findByExternalId(accountId);
|
||||
if (savingsAccount == null)
|
||||
throw new SavingsAccountNotFoundException(accountId);
|
||||
return savingsAccount;
|
||||
}
|
||||
|
||||
private SavingsAccount validateAndGetSavingAccount(@NotNull InteropRequestData request) {
|
||||
//TODO: error handling
|
||||
SavingsAccount savingsAccount = validateAndGetSavingAccount(request.getAccountId());
|
||||
savingsAccount.setHelpers(savingsAccountTransactionSummaryWrapper, savingsHelper);
|
||||
|
||||
ApplicationCurrency currency = currencyRepository.findOneByCode(request.getAmount().getCurrency());
|
||||
if (!savingsAccount.getCurrency().getCode().equals(currency.getCode()))
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
SavingsAccountTransactionType transactionType = request.getTransactionRole().getTransactionType();
|
||||
if (!savingsAccount.isTransactionAllowed(transactionType, request.getExpirationLocalDate()))
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
request.normalizeAmounts(savingsAccount.getCurrency());
|
||||
if (transactionType.isDebit() && MathUtil.isLessThan(savingsAccount.getWithdrawableBalance(), request.getAmount().getAmount()))
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
return savingsAccount;
|
||||
}
|
||||
|
||||
private BigDecimal validateTransfer(@NotNull InteropTransferRequestData request, @NotNull SavingsAccount savingsAccount) {
|
||||
BigDecimal amount = request.getAmount().getAmount();
|
||||
SavingsAccountTransactionType transactionType = request.getTransactionRole().getTransactionType();
|
||||
|
||||
BigDecimal total = transactionType.isDebit() ? amount : MathUtil.negate(amount);
|
||||
MoneyData fspFee = request.getFspFee();
|
||||
if (fspFee != null) {
|
||||
if (!savingsAccount.getCurrency().getCode().equals(fspFee.getCurrency()))
|
||||
throw new UnsupportedOperationException();
|
||||
//TODO: compare with calculated quote fee
|
||||
total = MathUtil.add(total, fspFee.getAmount());
|
||||
}
|
||||
MoneyData fspCommission = request.getFspCommission();
|
||||
if (fspCommission != null) {
|
||||
if (!savingsAccount.getCurrency().getCode().equals(fspCommission.getCurrency()))
|
||||
throw new UnsupportedOperationException();
|
||||
//TODO: compare with calculated quote commission
|
||||
total = MathUtil.subtractToZero(total, fspCommission.getAmount());
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private DateTimeFormatter getDateTimeFormatter(@NotNull JsonCommand command) {
|
||||
Locale locale = command.extractLocale();
|
||||
if (locale == null)
|
||||
locale = DEFAULT_LOCALE;
|
||||
String dateFormat = command.dateFormat();
|
||||
if (StringUtils.isEmpty(dateFormat))
|
||||
dateFormat = "yyyy-MM-dd HH:mm:ss.SSS";
|
||||
|
||||
return DateTimeFormat.forPattern(dateFormat).withLocale(locale);
|
||||
}
|
||||
|
||||
PaymentType findPaymentType() {
|
||||
List<PaymentType> paymentTypes = paymentTypeRepository.findAll();
|
||||
for (PaymentType paymentType : paymentTypes) {
|
||||
if (!paymentType.isCashPayment())
|
||||
return paymentType;
|
||||
//TODO: for now first not cash is retured:
|
||||
// 1. must be added as initial setup,
|
||||
// 2. if more than one non-cashe type added then update this code
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
SavingsAccountTransaction findTransaction(@NotNull SavingsAccount savingsAccount, @NotNull String transactionCode, SavingsAccountTransactionType transactionType) {
|
||||
String routingCode = getRoutingCode();
|
||||
for (SavingsAccountTransaction transaction : savingsAccount.getTransactions()) {
|
||||
if (transactionType != null && !transactionType.getValue().equals(transaction.getTypeOf()))
|
||||
continue;
|
||||
|
||||
PaymentDetail detail = transaction.getPaymentDetail();
|
||||
if (detail != null && routingCode.equals(detail.getRoutingCode()) && transactionCode.equals(detail.getReceiptNumber()))
|
||||
return transaction;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public InteropIdentifier findIdentifier(@NotNull InteropIdentifierType idType, @NotNull String idValue, String subIdOrType) {
|
||||
return identifierRepository.findOne(Specifications.where(idTypeEqual(idType)).and(idValueEqual(idValue)).and(subIdOrTypeEqual(subIdOrType)));
|
||||
}
|
||||
|
||||
public static Specification<InteropIdentifier> idTypeEqual(@NotNull InteropIdentifierType idType) {
|
||||
return (Root<InteropIdentifier> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> cb.and(cb.equal(root.get("type"), idType));
|
||||
}
|
||||
|
||||
public static Specification<InteropIdentifier> idValueEqual(@NotNull String idValue) {
|
||||
return (Root<InteropIdentifier> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> cb.and(cb.equal(root.get("value"), idValue));
|
||||
}
|
||||
|
||||
public static Specification<InteropIdentifier> subIdOrTypeEqual(String subIdOrType) {
|
||||
return (Root<InteropIdentifier> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
|
||||
Path<Object> path = root.get("subValueOrType");
|
||||
return cb.and(subIdOrType == null ? cb.isNull(path) : cb.equal(path, subIdOrType));
|
||||
};
|
||||
}
|
||||
|
||||
private AppUser getLoginUser() {
|
||||
return securityContext.getAuthenticatedUserIfPresent();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
String getRoutingCode() {
|
||||
return DEFAULT_ROUTING_CODE;
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.util;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import serp.util.Strings;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class InteropUtil {
|
||||
|
||||
public static final String ISO8601_DATE_TIME_FORMAT = "yyyy-MM-ddTHH:mm:ss.SSS[-HH:MM]";
|
||||
public static final String ISO8601_DATE_FORMAT = "yyyy-MM-dd";
|
||||
|
||||
public static final Locale DEFAULT_LOCALE = Locale.US;
|
||||
|
||||
public static final String ROOT_PATH = "interoperation";
|
||||
public static final String DEFAULT_ROUTING_CODE = "INTEROPERATION";
|
||||
|
||||
public static final String ENTITY_NAME_IDENTIFIER = "INTERID";
|
||||
public static final String ENTITY_NAME_REQUEST = "INTERREQUEST";
|
||||
public static final String ENTITY_NAME_QUOTE = "INTERQUOTE";
|
||||
public static final String ENTITY_NAME_TRANSFER = "INTERTRANSFER";
|
||||
|
||||
public static final String ACTION_TRANSFER_PREPARE = "PREPARE";
|
||||
public static final String ACTION_TRANSFER_COMMIT = "CREATE";
|
||||
|
||||
public static final String PARAM_LOCALE = "locale";
|
||||
public static final String PARAM_DATE_FORMAT = "dateFormat";
|
||||
|
||||
public static final String PARAM_TRANSACTION_CODE = "transactionCode";
|
||||
public static final String PARAM_REQUEST_CODE = "requestCode";
|
||||
public static final String PARAM_QUOTE_CODE = "quoteCode";
|
||||
public static final String PARAM_TRANSFER_CODE = "transferCode";
|
||||
public static final String PARAM_ACCOUNT_ID = "accountId";
|
||||
public static final String PARAM_AMOUNT_TYPE = "amountType";
|
||||
public static final String PARAM_AMOUNT = "amount";
|
||||
public static final String PARAM_FEES = "fees";
|
||||
public static final String PARAM_FSP_FEE = "fspFee";
|
||||
public static final String PARAM_FSP_COMMISSION = "fspCommission";
|
||||
public static final String PARAM_TRANSACTION_TYPE = "transactionType";
|
||||
public static final String PARAM_TRANSACTION_ROLE = "transactionRole";
|
||||
public static final String PARAM_NOTE = "note";
|
||||
public static final String PARAM_GEO_CODE = "geoCode";
|
||||
|
||||
public static final String PARAM_CURRENCY = "currency";
|
||||
|
||||
public static final String PARAM_SCENARIO = "scenario";
|
||||
public static final String PARAM_SUB_SCENARIO = "subScenario";
|
||||
public static final String PARAM_INITIATOR = "initiator";
|
||||
public static final String PARAM_INITIATOR_TYPE = "initiatorType";
|
||||
public static final String PARAM_EXPIRATION = "expiration";
|
||||
|
||||
public static final String PARAM_LATITUDE = "latitude";
|
||||
public static final String PARAM_LONGITUDE = "latitude";
|
||||
|
||||
public static final String PARAM_EXTENSION_LIST = "extensionList";
|
||||
public static final String PARAM_KEY = "key";
|
||||
public static final String PARAM_VALUE = "value";
|
||||
}
|
||||
+407
@@ -0,0 +1,407 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.interoperation.util;
|
||||
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
|
||||
public class MathUtil {
|
||||
|
||||
public static Long nullToZero(Long value) {
|
||||
return nullToDefault(value, 0L);
|
||||
}
|
||||
|
||||
public static Long nullToDefault(Long value, Long def) {
|
||||
return value == null ? def : value;
|
||||
}
|
||||
|
||||
public static Long zeroToNull(Long value) {
|
||||
return isEmpty(value) ? null : value;
|
||||
}
|
||||
|
||||
/** @return parameter value or ZERO if it is negative */
|
||||
public static Long negativeToZero(Long value) {
|
||||
return isGreaterThanZero(value) ? value : 0L;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(Long value) {
|
||||
return value == null || value.equals(0L);
|
||||
}
|
||||
|
||||
public static boolean isGreaterThanZero(Long value) {
|
||||
return value != null && value > 0L;
|
||||
}
|
||||
|
||||
public static boolean isLessThanZero(Long value) {
|
||||
return value != null && value < 0L;
|
||||
}
|
||||
|
||||
public static boolean isZero(Long value) {
|
||||
return value != null && value.equals(0L);
|
||||
}
|
||||
|
||||
public static boolean isEqualTo(Long first, Long second) {
|
||||
return nullToZero(first).equals(nullToZero(second));
|
||||
}
|
||||
|
||||
public static boolean isGreaterThan(Long first, Long second) {
|
||||
return nullToZero(first) > nullToZero(second);
|
||||
}
|
||||
|
||||
public static boolean isLessThan(Long first, Long second) {
|
||||
return nullToZero(first) < nullToZero(second);
|
||||
}
|
||||
|
||||
public static boolean isGreaterThanOrEqualTo(Long first, Long second) {
|
||||
return nullToZero(first) >= nullToZero(second);
|
||||
}
|
||||
|
||||
public static boolean isLessThanOrEqualZero(Long value) {
|
||||
return nullToZero(value) <= 0L;
|
||||
}
|
||||
|
||||
/** @return parameter value or negated value to positive */
|
||||
public static Long abs(Long value) {
|
||||
return value == null ? 0L : Math.abs(value);
|
||||
}
|
||||
|
||||
/** @return calculates minimum of the two values considering null values
|
||||
* @param notNull if true then null parameter is omitted, otherwise returns null */
|
||||
public static Long min(Long first, Long second, boolean notNull) {
|
||||
return first == null
|
||||
? (notNull ? second : null)
|
||||
: second == null ? (notNull ? first : null) : Math.min(first, second);
|
||||
}
|
||||
|
||||
/** @return calculates minimum of the values considering null values
|
||||
* @param notNull if true then null parameter is omitted, otherwise returns null */
|
||||
public static Long min(Long first, Long second, Long third, boolean notNull) {
|
||||
return min(min(first, second, notNull), third, notNull);
|
||||
}
|
||||
|
||||
/** @return sum the two values considering null values */
|
||||
public static Long add(Long first, Long second) {
|
||||
return first == null
|
||||
? second
|
||||
: second == null ? first : Math.addExact(first, second);
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static Long add(Long first, Long second, Long third) {
|
||||
return add(add(first, second), third);
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static Long add(Long first, Long second, Long third, Long fourth) {
|
||||
return add(add(add(first, second), third), fourth);
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static Long add(Long first, Long second, Long third, Long fourth, Long fifth) {
|
||||
return add(add(add(add(first, second), third), fourth), fifth);
|
||||
}
|
||||
|
||||
/** @return first minus second considering null values, maybe negative */
|
||||
public static Long subtract(Long first, Long second) {
|
||||
return first == null
|
||||
? null
|
||||
: second == null ? first : Math.subtractExact(first, second);
|
||||
}
|
||||
|
||||
/** @return first minus the others considering null values, maybe negative */
|
||||
public static Long subtractToZero(Long first, Long second, Long third) {
|
||||
return subtractToZero(subtract(first, second), third);
|
||||
}
|
||||
|
||||
/** @return first minus the others considering null values, maybe negative */
|
||||
public static Long subtractToZero(Long first, Long second, Long third, Long fourth) {
|
||||
return subtractToZero(subtract(subtract(first, second), third), fourth);
|
||||
}
|
||||
|
||||
/** @return NONE negative first minus second considering null values */
|
||||
public static Long subtractToZero(Long first, Long second) {
|
||||
return negativeToZero(subtract(first, second));
|
||||
}
|
||||
|
||||
/** @return BigDecimal null safe negate */
|
||||
public static Long negate(Long amount) {
|
||||
return isEmpty(amount) ? amount : Math.negateExact(amount);
|
||||
}
|
||||
|
||||
|
||||
// ----------------- BigDecimal -----------------
|
||||
|
||||
public static BigDecimal nullToZero(BigDecimal value) {
|
||||
return nullToDefault(value, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public static BigDecimal nullToDefault(BigDecimal value, BigDecimal def) {
|
||||
return value == null ? def : value;
|
||||
}
|
||||
|
||||
public static BigDecimal zeroToNull(BigDecimal value) {
|
||||
return isEmpty(value) ? null : value;
|
||||
}
|
||||
|
||||
/** @return parameter value or ZERO if it is negative */
|
||||
public static BigDecimal negativeToZero(BigDecimal value) {
|
||||
return isGreaterThanZero(value) ? value : BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(BigDecimal value) {
|
||||
return value == null || BigDecimal.ZERO.compareTo(value) == 0;
|
||||
}
|
||||
|
||||
public static boolean isGreaterThanZero(BigDecimal value) {
|
||||
return value != null && value.compareTo(BigDecimal.ZERO) > 0;
|
||||
}
|
||||
|
||||
public static boolean isLessThanZero(BigDecimal value) {
|
||||
return value != null && value.compareTo(BigDecimal.ZERO) < 0;
|
||||
}
|
||||
|
||||
public static boolean isZero(BigDecimal value) {
|
||||
return value != null && value.compareTo(BigDecimal.ZERO) == 0;
|
||||
}
|
||||
|
||||
public static boolean isEqualTo(BigDecimal first, BigDecimal second) {
|
||||
return nullToZero(first).compareTo(nullToZero(second)) == 0;
|
||||
}
|
||||
|
||||
public static boolean isGreaterThan(BigDecimal first, BigDecimal second) {
|
||||
return nullToZero(first).compareTo(nullToZero(second)) > 0;
|
||||
}
|
||||
|
||||
public static boolean isLessThan(BigDecimal first, BigDecimal second) {
|
||||
return nullToZero(first).compareTo(nullToZero(second)) < 0;
|
||||
}
|
||||
|
||||
public static boolean isGreaterThanOrEqualTo(BigDecimal first, BigDecimal second) {
|
||||
return nullToZero(first).compareTo(nullToZero(second)) >= 0;
|
||||
}
|
||||
|
||||
public static boolean isLessThanOrEqualZero(BigDecimal value) {
|
||||
return nullToZero(value).compareTo(BigDecimal.ZERO) <= 0;
|
||||
}
|
||||
|
||||
/** @return parameter value or negated value to positive */
|
||||
public static BigDecimal abs(BigDecimal value) {
|
||||
return value == null ? BigDecimal.ZERO : value.abs();
|
||||
}
|
||||
|
||||
/** @return calculates minimum of the two values considering null values
|
||||
* @param notNull if true then null parameter is omitted, otherwise returns null */
|
||||
public static BigDecimal min(BigDecimal first, BigDecimal second, boolean notNull) {
|
||||
return notNull
|
||||
? first == null
|
||||
? second
|
||||
: second == null ? first : min(first, second, false)
|
||||
: isLessThan(first, second) ? first : second;
|
||||
}
|
||||
|
||||
/** @return calculates minimum of the values considering null values
|
||||
* @param notNull if true then null parameter is omitted, otherwise returns null */
|
||||
public static BigDecimal min(BigDecimal first, BigDecimal second, BigDecimal third, boolean notNull) {
|
||||
return min(min(first, second, notNull), third, notNull);
|
||||
}
|
||||
|
||||
/** @return sum the two values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second) {
|
||||
return add(first, second, MoneyHelper.getMathContext());
|
||||
}
|
||||
|
||||
/** @return sum the two values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second, MathContext mc) {
|
||||
return first == null
|
||||
? second
|
||||
: second == null ? first : first.add(second, mc);
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second, BigDecimal third) {
|
||||
return add(first, second, third, MoneyHelper.getMathContext());
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second, BigDecimal third, MathContext mc) {
|
||||
return add(add(first, second, mc), third, mc);
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second, BigDecimal third, BigDecimal fourth) {
|
||||
return add(first, second, third, fourth, MoneyHelper.getMathContext());
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second, BigDecimal third, BigDecimal fourth, MathContext mc) {
|
||||
return add(add(add(first, second, mc), third, mc), fourth, mc);
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second, BigDecimal third, BigDecimal fourth, BigDecimal fifth) {
|
||||
return add(first, second, third, fourth, fifth, MoneyHelper.getMathContext());
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second, BigDecimal third, BigDecimal fourth, BigDecimal fifth, MathContext mc) {
|
||||
return add(add(add(add(first, second, mc), third, mc), fourth, mc), fifth, mc);
|
||||
}
|
||||
|
||||
/** @return first minus second considering null values, maybe negative */
|
||||
public static BigDecimal subtract(BigDecimal first, BigDecimal second) {
|
||||
return subtract(first, second, MoneyHelper.getMathContext());
|
||||
}
|
||||
|
||||
/** @return first minus second considering null values, maybe negative */
|
||||
public static BigDecimal subtract(BigDecimal first, BigDecimal second, MathContext mc) {
|
||||
return first == null
|
||||
? null
|
||||
: second == null ? first : first.subtract(second, mc);
|
||||
}
|
||||
|
||||
/** @return NONE negative first minus second considering null values */
|
||||
public static BigDecimal subtractToZero(BigDecimal first, BigDecimal second) {
|
||||
return negativeToZero(subtract(first, second));
|
||||
}
|
||||
|
||||
/** @return first minus the others considering null values, maybe negative */
|
||||
public static BigDecimal subtractToZero(BigDecimal first, BigDecimal second, BigDecimal third) {
|
||||
return subtractToZero(subtract(first, second), third);
|
||||
}
|
||||
|
||||
/** @return first minus the others considering null values, maybe negative */
|
||||
public static BigDecimal subtractToZero(BigDecimal first, BigDecimal second, BigDecimal third, BigDecimal fourth) {
|
||||
return subtractToZero(subtract(subtract(first, second), third), fourth);
|
||||
}
|
||||
|
||||
/** @return BigDecimal with scale set to the 'digitsAfterDecimal' of the parameter currency */
|
||||
public static BigDecimal normalizeAmount(BigDecimal amount, @NotNull MonetaryCurrency currency) {
|
||||
return amount == null ? null : amount.setScale(currency.getDigitsAfterDecimal(), MoneyHelper.getRoundingMode());
|
||||
}
|
||||
|
||||
/** @return BigDecimal null safe negate */
|
||||
public static BigDecimal negate(BigDecimal amount) {
|
||||
return negate(amount, MoneyHelper.getMathContext());
|
||||
}
|
||||
|
||||
/** @return BigDecimal null safe negate */
|
||||
public static BigDecimal negate(BigDecimal amount, MathContext mc) {
|
||||
return isEmpty(amount) ? amount : amount.negate(mc);
|
||||
}
|
||||
|
||||
|
||||
// ----------------- Money -----------------
|
||||
|
||||
public static Money nullToZero(Money value, @NotNull MonetaryCurrency currency) {
|
||||
return nullToDefault(value, Money.zero(currency));
|
||||
}
|
||||
|
||||
public static Money nullToDefault(Money value, Money def) {
|
||||
return value == null ? def : value;
|
||||
}
|
||||
|
||||
public static Money zeroToNull(Money value) {
|
||||
return isEmpty(value) ? null : value;
|
||||
}
|
||||
|
||||
/** @return parameter value or ZERO if it is negative */
|
||||
public static Money negativeToZero(Money value) {
|
||||
return value == null || isGreaterThanZero(value) ? value : Money.zero(value.getCurrency());
|
||||
}
|
||||
|
||||
public static boolean isEmpty(Money value) {
|
||||
return value == null || value.isZero();
|
||||
}
|
||||
|
||||
public static boolean isGreaterThanZero(Money value) {
|
||||
return value != null && value.isGreaterThanZero();
|
||||
}
|
||||
|
||||
public static boolean isLessThanZero(Money value) {
|
||||
return value != null && value.isLessThanZero();
|
||||
}
|
||||
|
||||
public static boolean isEqualTo(Money first, Money second) {
|
||||
return first == null ? second == null : (second != null && first.isEqualTo(second));
|
||||
}
|
||||
|
||||
public static boolean isGreaterThan(Money first, Money second) {
|
||||
return second == null || (first != null && first.isGreaterThan(second));
|
||||
}
|
||||
|
||||
public static boolean isLessThan(Money first, Money second) {
|
||||
return first == null || (second != null && first.isLessThan(second));
|
||||
}
|
||||
|
||||
public static Money plus(Money first, Money second) {
|
||||
return first == null
|
||||
? second
|
||||
: second == null ? first : first.plus(second);
|
||||
}
|
||||
|
||||
public static Money plus(Money first, Money second, Money third) {
|
||||
return plus(plus(first, second), third);
|
||||
}
|
||||
|
||||
public static Money plus(Money first, Money second, Money third, Money fourth) {
|
||||
return plus(plus(plus(first, second), third), fourth);
|
||||
}
|
||||
|
||||
public static Money minus(Money first, Money second) {
|
||||
return first == null
|
||||
? null
|
||||
: second == null ? first : first.minus(second);
|
||||
}
|
||||
|
||||
/** @return first minus the others considering null values, maybe negative */
|
||||
public static Money minusToZero(Money first, Money second, Money third) {
|
||||
return minusToZero(minus(first, second), third);
|
||||
}
|
||||
|
||||
/** @return first minus the others considering null values, maybe negative */
|
||||
public static Money minusToZero(Money first, Money second, Money third, Money fourth) {
|
||||
return minusToZero(minus(minus(first, second), third), fourth);
|
||||
}
|
||||
|
||||
/** @return NONE negative first minus second considering null values */
|
||||
public static Money minusToZero(Money first, Money second) {
|
||||
return negativeToZero(minus(first, second));
|
||||
}
|
||||
|
||||
/** @return calculates minimum of the two values considering null values
|
||||
* @param notNull if true then null parameter is omitted, otherwise returns null */
|
||||
public static Money min(Money first, Money second, boolean notNull) {
|
||||
return notNull
|
||||
? first == null
|
||||
? second
|
||||
: second == null ? first : min(first, second, false)
|
||||
: isLessThan(first, second) ? first : second;
|
||||
}
|
||||
|
||||
/** @return calculates minimum of the values considering null values
|
||||
* @param notNull if true then null parameter is omitted, otherwise returns null */
|
||||
public static Money min(Money first, Money second, Money third, boolean notNull) {
|
||||
return min(min(first, second, notNull), third, notNull);
|
||||
}
|
||||
}
|
||||
+5
@@ -49,6 +49,11 @@ public class MonetaryCurrency {
|
||||
return new MonetaryCurrency(this.code, this.digitsAfterDecimal, this.inMultiplesOf);
|
||||
}
|
||||
|
||||
public static MonetaryCurrency fromApplicationCurrency(ApplicationCurrency applicationCurrency) {
|
||||
return new MonetaryCurrency(applicationCurrency.getCode(), applicationCurrency.getDecimalPlaces(),
|
||||
applicationCurrency.getCurrencyInMultiplesOf());
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
+12
-2
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.apache.fineract.organisation.monetary.domain;
|
||||
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
@@ -28,10 +29,13 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class MoneyHelper {
|
||||
|
||||
|
||||
private static RoundingMode roundingMode = null;
|
||||
private static MathContext mathContext;
|
||||
private static final int PRECISION = 12;
|
||||
|
||||
private static ConfigurationDomainService staticConfigurationDomainService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ConfigurationDomainService configurationDomainService;
|
||||
|
||||
@@ -48,4 +52,10 @@ public class MoneyHelper {
|
||||
return roundingMode;
|
||||
}
|
||||
|
||||
public static MathContext getMathContext() {
|
||||
if (mathContext == null) {
|
||||
mathContext = new MathContext(PRECISION, getRoundingMode());
|
||||
}
|
||||
return mathContext;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -115,5 +115,11 @@ public final class PaymentDetail extends AbstractPersistableCustom<Long> {
|
||||
return this.paymentType;
|
||||
}
|
||||
|
||||
public String getReceiptNumber() { return this.receiptNumber; }
|
||||
public String getReceiptNumber() {
|
||||
return this.receiptNumber;
|
||||
}
|
||||
|
||||
public String getRoutingCode() {
|
||||
return routingCode;
|
||||
}
|
||||
}
|
||||
+42
-2
@@ -81,6 +81,7 @@ import org.apache.fineract.infrastructure.security.service.RandomPasswordGenerat
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
import org.apache.fineract.organisation.staff.domain.Staff;
|
||||
import org.apache.fineract.portfolio.accountdetails.domain.AccountType;
|
||||
@@ -437,6 +438,10 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
||||
this.savingsHelper = savingsHelper;
|
||||
}
|
||||
|
||||
public String getExternalId() {
|
||||
return externalId;
|
||||
}
|
||||
|
||||
public boolean isNotActive() {
|
||||
return !isActive();
|
||||
}
|
||||
@@ -1023,10 +1028,23 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
private void payWithdrawalFee(final BigDecimal transactionAmoount, final LocalDate transactionDate, final AppUser user) {
|
||||
public BigDecimal calculateWithdrawalFee(final BigDecimal transactionAmount) {
|
||||
BigDecimal result = BigDecimal.ZERO;
|
||||
System.out.println("isWithdrawalFeeApplicableForTransfer() = " + isWithdrawalFeeApplicableForTransfer());
|
||||
if (isWithdrawalFeeApplicableForTransfer()) {
|
||||
for (SavingsAccountCharge charge : this.charges()) {
|
||||
if (charge.isWithdrawalFee() && charge.isActive()) {
|
||||
result = result.add(charge.calculateWithdralFeeAmount(transactionAmount), MoneyHelper.getMathContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void payWithdrawalFee(final BigDecimal transactionAmount, final LocalDate transactionDate, final AppUser user) {
|
||||
for (SavingsAccountCharge charge : this.charges()) {
|
||||
if (charge.isWithdrawalFee() && charge.isActive()) {
|
||||
charge.updateWithdralFeeAmount(transactionAmoount);
|
||||
charge.updateWithdralFeeAmount(transactionAmount);
|
||||
this.payCharge(charge, charge.getAmountOutstanding(this.getCurrency()), transactionDate, user);
|
||||
}
|
||||
}
|
||||
@@ -2712,6 +2730,28 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
||||
return isActive();
|
||||
}
|
||||
|
||||
public boolean isTransactionAllowed(SavingsAccountTransactionType transactionType, LocalDate transactionDate) {
|
||||
if (!isTransactionsAllowed())
|
||||
return false;
|
||||
|
||||
Client client = getClient();
|
||||
if (client != null && !client.isActive()) {
|
||||
return false;
|
||||
}
|
||||
Group group = group();
|
||||
if (group != null && !group.isActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (transactionDate == null)
|
||||
return true;
|
||||
if (DateUtils.isDateInTheFuture(transactionDate) || transactionDate.isBefore(getActivationLocalDate()))
|
||||
return false;
|
||||
if (transactionType.isCredit())
|
||||
return true;
|
||||
return !isAccountLocked(transactionDate);
|
||||
}
|
||||
|
||||
public BigDecimal minBalanceForInterestCalculation() {
|
||||
return this.minBalanceForInterestCalculation;
|
||||
}
|
||||
|
||||
+8
-3
@@ -38,11 +38,13 @@ import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||
@@ -704,17 +706,20 @@ public class SavingsAccountCharge extends AbstractPersistableCustom<Long> {
|
||||
.isEquals();
|
||||
}
|
||||
|
||||
public BigDecimal updateWithdralFeeAmount(final BigDecimal transactionAmount) {
|
||||
public BigDecimal calculateWithdralFeeAmount(@NotNull BigDecimal transactionAmount) {
|
||||
BigDecimal amountPaybale = BigDecimal.ZERO;
|
||||
if (ChargeCalculationType.fromInt(this.chargeCalculation).isFlat()) {
|
||||
amountPaybale = this.amount;
|
||||
} else if (ChargeCalculationType.fromInt(this.chargeCalculation).isPercentageOfAmount()) {
|
||||
amountPaybale = transactionAmount.multiply(this.percentage).divide(BigDecimal.valueOf(100l));
|
||||
amountPaybale = transactionAmount.multiply(this.percentage).divide(BigDecimal.valueOf(100L), MoneyHelper.getRoundingMode());
|
||||
}
|
||||
this.amountOutstanding = amountPaybale;
|
||||
return amountPaybale;
|
||||
}
|
||||
|
||||
public BigDecimal updateWithdralFeeAmount(final BigDecimal transactionAmount) {
|
||||
return amountOutstanding = calculateWithdralFeeAmount(transactionAmount);
|
||||
}
|
||||
|
||||
public void updateToNextDueDateFrom(final LocalDate startingDate) {
|
||||
if (isAnnualFee() || isMonthlyFee() || isWeeklyFee()) {
|
||||
this.dueDate = getNextDueDateFrom(startingDate).toDate();
|
||||
|
||||
+2
@@ -53,4 +53,6 @@ public interface SavingsAccountRepository extends JpaRepository<SavingsAccount,
|
||||
SavingsAccount findNonClosedAccountByAccountNumber(@Param("accountNumber") String accountNumber);
|
||||
|
||||
Page<SavingsAccount> findByStatus(Integer status,Pageable pageable);
|
||||
|
||||
SavingsAccount findByExternalId(String externalId);
|
||||
}
|
||||
+1
-1
@@ -71,7 +71,7 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L
|
||||
@JoinColumn(name = "office_id", nullable = false)
|
||||
private Office office;
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
@ManyToOne(cascade = CascadeType.ALL, optional = true)
|
||||
@JoinColumn(name = "payment_detail_id", nullable = true)
|
||||
private PaymentDetail paymentDetail;
|
||||
|
||||
|
||||
+5
-1
@@ -31,11 +31,15 @@ import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType;
|
||||
import org.apache.fineract.portfolio.savings.domain.interest.CompoundInterestHelper;
|
||||
import org.apache.fineract.portfolio.savings.domain.interest.PostingPeriod;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public final class SavingsHelper {
|
||||
|
||||
AccountTransfersReadPlatformService accountTransfersReadPlatformService = null;
|
||||
|
||||
|
||||
@Autowired
|
||||
public SavingsHelper(AccountTransfersReadPlatformService accountTransfersReadPlatformService) {
|
||||
this.accountTransfersReadPlatformService = accountTransfersReadPlatformService;
|
||||
}
|
||||
|
||||
+4
@@ -25,4 +25,8 @@ public class SavingsAccountNotFoundException extends AbstractPlatformResourceNot
|
||||
public SavingsAccountNotFoundException(final Long id) {
|
||||
super("error.msg.saving.account.id.invalid", "Savings account with identifier " + id + " does not exist", id);
|
||||
}
|
||||
|
||||
public SavingsAccountNotFoundException(final String externalId) {
|
||||
super("error.msg.saving.account.id.invalid", "Savings account with external identifier " + externalId + " does not exist", externalId);
|
||||
}
|
||||
}
|
||||
@@ -47,11 +47,12 @@
|
||||
org.apache.fineract.infrastructure.*,
|
||||
org.apache.fineract.scheduledjobs.*,
|
||||
org.apache.fineract.organisation.*,
|
||||
org.apache.fineract.interoperation.*,
|
||||
org.apache.fineract.portfolio.loanaccount.*,
|
||||
org.apache.fineract.portfolio.savingsaccount.*,
|
||||
org.apache.fineract.portfolio.*,
|
||||
org.apache.fineract.useradministration.*,
|
||||
org.apache.fineract.mix.*,
|
||||
org.apache.fineract.mix.*,
|
||||
org.apache.fineract.notification.*,
|
||||
org.apache.fineract.template.*,
|
||||
org.apache.fineract.template.service.*,
|
||||
@@ -86,8 +87,9 @@
|
||||
<jpa:repositories base-package="org.apache.fineract.adhocquery.domain" />
|
||||
<jpa:repositories base-package="org.apache.fineract.notification.domain"/>
|
||||
<jpa:repositories base-package="org.apache.fineract.infrastructure.campaigns.email.domain"/>
|
||||
|
||||
|
||||
<jpa:repositories base-package="org.apache.fineract.interoperation.domain"/>
|
||||
|
||||
|
||||
<import resource="infrastructure.xml" />
|
||||
|
||||
<import resource="securityContext.xml" />
|
||||
@@ -103,6 +105,4 @@
|
||||
<import resource="spmContext.xml"/>
|
||||
|
||||
<import resource="swagger.xml"/>
|
||||
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
--
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||
-- or more contributor license agreements. See the NOTICE file
|
||||
-- distributed with this work for additional information
|
||||
-- regarding copyright ownership. The ASF licenses this file
|
||||
-- to you under the Apache License, Version 2.0 (the
|
||||
-- "License"); you may not use this file except in compliance
|
||||
-- with the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing,
|
||||
-- software distributed under the License is distributed on an
|
||||
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
-- KIND, either express or implied. See the License for the
|
||||
-- specific language governing permissions and limitations
|
||||
-- under the License.
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `interop_identifier`;
|
||||
CREATE TABLE `interop_identifier` (
|
||||
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
`account_id` BIGINT(20) NOT NULL,
|
||||
`type` VARCHAR(32) NOT NULL,
|
||||
`a_value` VARCHAR(128) NOT NULL,
|
||||
`sub_value_or_type` VARCHAR(128) NULL,
|
||||
`created_by` VARCHAR(32) NOT NULL,
|
||||
`created_on` TIMESTAMP NOT NULL,
|
||||
`modified_by` VARCHAR(32) NULL,
|
||||
`modified_on` TIMESTAMP NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `uk_interop_identifier_account` (`account_id`, `type`),
|
||||
UNIQUE INDEX `uk_interop_identifier_value` (`type`, `a_value`, `sub_value_or_type`),
|
||||
INDEX `fk_interop_identifier_account` (`account_id`),
|
||||
CONSTRAINT `fk_interop_identifier_account` FOREIGN KEY (`account_id`) REFERENCES `m_savings_account` (`id`)
|
||||
)
|
||||
COLLATE = 'utf8_general_ci'
|
||||
ENGINE = InnoDB;
|
||||
|
||||
-- user+roles
|
||||
|
||||
SET @interop_username = 'interopUser';
|
||||
INSERT INTO `m_appuser`
|
||||
VALUES (NULL, 0, 1, NULL, @interop_username, 'Interop', 'User', '5787039480429368bf94732aacc771cd0a3ea02bcf504ffe1185ab94213bc63a',
|
||||
'email@email.com', b'0', b'1', b'1', b'1', b'1', CURDATE(), 0, b'0');
|
||||
|
||||
INSERT INTO `m_appuser_role` VALUES ((SELECT id FROM m_appuser WHERE username = @interop_username), 1);
|
||||
|
||||
-- Interoperation permissions
|
||||
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
VALUES ('interop', 'READ_INTERID', 'INTERID', 'READ', 0);
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
VALUES ('interop', 'READ_INTERREQUEST', 'INTERREQUEST', 'READ', 0);
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
VALUES ('interop', 'READ_INTERQUOTE', 'INTERQUOTE', 'READ', 0);
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
VALUES ('interop', 'READ_INTERTRANSFER', 'INTERTRANSFER', 'READ', 0);
|
||||
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
VALUES ('interop', 'PREPARE_INTERTRANSFER', 'INTERTRANSFER', 'PREPARE', 0);
|
||||
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
VALUES ('interop', 'CREATE_INTERID', 'INTERID', 'CREATE', 0);
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
VALUES ('interop', 'CREATE_INTERREQUEST', 'INTERREQUEST', 'CREATE', 0);
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
VALUES ('interop', 'CREATE_INTERQUOTE', 'INTERQUOTE', 'CREATE', 0);
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
VALUES ('interop', 'CREATE_INTERTRANSFER', 'INTERTRANSFER', 'CREATE', 0);
|
||||
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
VALUES ('interop', 'DELETE_INTERID', 'INTERID', 'DELETE', 0);
|
||||
|
||||
|
||||
INSERT IGNORE INTO m_code (code_name, is_system_defined) VALUES ('PaymentType', 1);
|
||||
|
||||
SET @code_id = -1;
|
||||
SELECT id INTO @code_id FROM m_code WHERE code_name = 'PaymentType';
|
||||
|
||||
INSERT IGNORE INTO m_code_value (code_id, code_value, order_position) VALUES (@code_id, 'Money Transfer', 1);
|
||||
|
||||
INSERT IGNORE INTO m_payment_type (value, description, order_position) VALUES ('Money Transfer', 'Money Transfer', 1);
|
||||
+5
@@ -67,6 +67,11 @@ CREATE TABLE `tenants` (
|
||||
LOCK TABLES `tenants` WRITE;
|
||||
/*!40000 ALTER TABLE `tenants` DISABLE KEYS */;
|
||||
INSERT INTO `tenants` VALUES (1,'default','Default Demo Tenant','mifostenant-default','Asia/Kolkata',NULL,NULL,NULL,NULL,'localhost','3306','root','mysql',1);
|
||||
-- Add tenants to support interoperation multi-tenancy
|
||||
-- INSERT INTO `tenants` VALUES (2,'tn01','Buffalo','tn01','Africa/Bujumbura',NULL,NULL,NULL,NULL,'localhost','3306','root','mysql',1);
|
||||
-- INSERT INTO `tenants` VALUES (3,'tn02','Lion','tn02','Africa/Bujumbura',NULL,NULL,NULL,NULL,'localhost','3306','root','mysql',1);
|
||||
-- INSERT INTO `tenants` VALUES (4,'tn03','Rhino','tn03','Africa/Bujumbura',NULL,NULL,NULL,NULL,'localhost','3306','root','mysql',1);
|
||||
-- INSERT INTO `tenants` VALUES (5,'tn04','Elephant','tn04','Africa/Bujumbura',NULL,NULL,NULL,NULL,'localhost','3306','root','mysql',1);
|
||||
/*!40000 ALTER TABLE `tenants` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
--
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||
-- or more contributor license agreements. See the NOTICE file
|
||||
-- distributed with this work for additional information
|
||||
-- regarding copyright ownership. The ASF licenses this file
|
||||
-- to you under the Apache License, Version 2.0 (the
|
||||
-- "License"); you may not use this file except in compliance
|
||||
-- with the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing,
|
||||
-- software distributed under the License is distributed on an
|
||||
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
-- KIND, either express or implied. See the License for the
|
||||
-- specific language governing permissions and limitations
|
||||
-- under the License.
|
||||
--
|
||||
|
||||
-- To use: Change saving_account_no before every run!
|
||||
-- !both tn03, tn04 tenants
|
||||
|
||||
-- saving product, account
|
||||
SET @last_saving_prod_id = -1;
|
||||
SELECT COALESCE(max(id), 1) into @last_saving_prod_id from m_savings_product;
|
||||
|
||||
SET @saving_prod_name = concat('Saving Product', @last_saving_prod_id);
|
||||
|
||||
INSERT INTO `m_savings_product`
|
||||
(`name`, `short_name`, `description`, `deposit_type_enum`, `currency_code`, `currency_digits`,
|
||||
`currency_multiplesof`, `nominal_annual_interest_rate`, `interest_compounding_period_enum`,
|
||||
`interest_posting_period_enum`, `interest_calculation_type_enum`, `interest_calculation_days_in_year_type_enum`,
|
||||
`min_required_opening_balance`, `accounting_type`, `withdrawal_fee_amount`, `withdrawal_fee_type_enum`,
|
||||
`withdrawal_fee_for_transfer`, `allow_overdraft`, `min_required_balance`, `enforce_min_required_balance`,
|
||||
`min_balance_for_interest_calculation`, `withhold_tax`, `tax_group_id`, `is_dormancy_tracking_active`)
|
||||
VALUES (@saving_prod_name, concat('SP', @last_saving_prod_id), 'Saving Product', 100, 'TZS', 2, NULL, 0.000000, 1,
|
||||
4, 1, 360, NULL, 2, NULL, NULL, 0, 0, 0.000000, 1, NULL, 0, NULL, 0);
|
||||
|
||||
SET @saving_prod_id = -1;
|
||||
SELECT id INTO @saving_prod_id FROM m_savings_product WHERE name = @saving_prod_name;
|
||||
|
||||
-- interop_identifier
|
||||
|
||||
-- charge, mapping
|
||||
-- gl_account, mappings
|
||||
-- ASSET-1, LIABILITY-2, EQUITY-3, INCOME-4, EXPENSE-5
|
||||
|
||||
SET @payment_type_id = -1;
|
||||
SELECT id INTO @payment_type_id FROM m_payment_type WHERE value = 'Money Transfer';
|
||||
|
||||
SET @saving_gl_name = 'Interoperation Saving';
|
||||
INSERT INTO `acc_gl_account` (`name`, `parent_id`, `hierarchy`, `gl_code`, `disabled`, `manual_journal_entries_allowed`, `account_usage`, `classification_enum`, `description`)
|
||||
VALUES (@saving_gl_name, NULL, NULL, 'Interop_Saving', 0, 1, 1, 1, 'Interoperation Saving Asset'); -- account_usage: DETAIL, classification_enum: ASSET
|
||||
|
||||
INSERT INTO `acc_product_mapping` (`gl_account_id`, `product_id`, `product_type`, `payment_type`, `charge_id`, `financial_account_type`)
|
||||
VALUES ((SELECT id FROM acc_gl_account WHERE name = @saving_gl_name), @saving_prod_id, 2, @payment_type_id, NULL, 1); -- product_type: SAVING, financial_account_type: ASSET
|
||||
|
||||
SET @nostro_gl_name = 'Interoperation NOSTRO';
|
||||
INSERT INTO `acc_gl_account` (`name`, `parent_id`, `hierarchy`, `gl_code`, `disabled`, `manual_journal_entries_allowed`, `account_usage`, `classification_enum`, `description`)
|
||||
VALUES (@nostro_gl_name, NULL, NULL, 'Interop_Nostro', 0, 0, 1, 2, 'Interoperation NOSTRO Liability'); -- account_usage: DETAIL, classification_enum: LIABILITY
|
||||
|
||||
INSERT INTO `acc_product_mapping` (`gl_account_id`, `product_id`, `product_type`, `payment_type`, `charge_id`, `financial_account_type`)
|
||||
VALUES ((SELECT id FROM acc_gl_account WHERE name = @nostro_gl_name), @saving_prod_id, 2, NULL, NULL, 2); -- product_type: SAVING, financial_account_type: LIABILITY
|
||||
|
||||
SET @fee_gl_name = 'Interoperation Fee';
|
||||
INSERT INTO `acc_gl_account` (`name`, `parent_id`, `hierarchy`, `gl_code`, `disabled`, `manual_journal_entries_allowed`, `account_usage`, `classification_enum`, `description`)
|
||||
VALUES (@fee_gl_name, NULL, NULL, 'Interop_Fee', 0, 0, 1, 4, 'Interoperation Fee Income'); -- account_usage: DETAIL, classification_enum: INCOME
|
||||
|
||||
SET @fee_gl_id = -1;
|
||||
SELECT id INTO @fee_gl_id FROM acc_gl_account WHERE name = @fee_gl_name;
|
||||
|
||||
INSERT INTO `acc_product_mapping` (`gl_account_id`, `product_id`, `product_type`, `payment_type`, `charge_id`, `financial_account_type`)
|
||||
VALUES (@fee_gl_id, @saving_prod_id, 2, NULL, NULL, 4); -- product_type: SAVING, financial_account_type: INCOME
|
||||
|
||||
SET @charge_name = 'Interoperation Withdraw Fee';
|
||||
INSERT INTO `m_charge`
|
||||
(`name`,`currency_code`,`charge_applies_to_enum`,`charge_time_enum`,`charge_calculation_enum`,`charge_payment_mode_enum`,
|
||||
`amount`,`fee_on_day`,`fee_interval`,`fee_on_month`,`is_penalty`,`is_active`,`is_deleted`,`min_cap`,`max_cap`,`fee_frequency`,
|
||||
`income_or_liability_account_id`,`tax_group_id`)
|
||||
VALUES (@charge_name, 'TZS', 2, 5, 1, NULL, 1.000000, NULL, NULL, NULL, 0, 0, 0, NULL, NULL, NULL, @fee_gl_id, NULL);
|
||||
|
||||
-- loan product
|
||||
/*
|
||||
SET @last_ext_id = -1;
|
||||
SELECT COALESCE(max(external_id), 1) INTO @last_ext_id FROM m_product_loan;
|
||||
|
||||
INSERT INTO `m_product_loan`
|
||||
VALUES
|
||||
(CONCAT('IP', @last_product_id), 'EUR', 2, 1, 50000.000000, NULL, NULL, NULL, concat('Interoperation Customer Product', @last_product_id),
|
||||
'Demo Interoperation Product', NULL, b'0', b'0', 1.000000, 1.000000, NULL, NULL, 3, 1.000000, 0, 1, 1, 1, 2, 1200, NULL,
|
||||
NULL, NULL, NULL, NULL, 1, 1, 3, @last_ext_id + 1, 0, 0,ADDDATE(curdate(),-100),ADDDATE(curdate(),100), 0, 0, NULL, NULL,
|
||||
NULL, 1, 30, 0, 0, 0.00, 0, 1, 0, 0, 0);
|
||||
|
||||
SET @product_id = -1;
|
||||
SELECT id INTO @product_id FROM m_product_loan WHERE name = concat('Interoperation Customer Product', @last_product_id);
|
||||
|
||||
-- charge, mapping
|
||||
INSERT INTO `m_charge` VALUES (
|
||||
NULL, concat('Loan Withdraw Fee_', @product_id), 'TZS', 1, 2,
|
||||
1, 0, 1.000000, NULL, NULL,
|
||||
NULL, 0, 1, 0, NULL,
|
||||
NULL, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO `m_product_loan_charge` VALUES
|
||||
(@product_id, (SELECT id
|
||||
FROM m_charge
|
||||
WHERE name = concat('Loan Withdraw Fee_', @product_id)));
|
||||
|
||||
-- gl_account, mappings
|
||||
-- ASSET-1, LIABILITY-2, EQUITY-3, INCOME-4, EXPENSE-5
|
||||
SET @liab_acc_name = concat('Loan Payable Liability_', @product_id);
|
||||
INSERT INTO `acc_gl_account` VALUES (
|
||||
NULL, @liab_acc_name, NULL, NULL, concat('0360009420', @product_id),
|
||||
0, 1, 1, 1, NULL, 'Loan Payable Liability');
|
||||
|
||||
INSERT INTO `acc_product_mapping` VALUES (
|
||||
NULL,
|
||||
(SELECT id
|
||||
FROM acc_gl_account
|
||||
WHERE name = @liab_acc_name),
|
||||
@product_id,
|
||||
NULL, NULL, NULL, 2);
|
||||
|
||||
SET @nostro_acc_name = concat('Loan NOSTRO_', @product_id);
|
||||
INSERT INTO `acc_gl_account` VALUES (
|
||||
NULL, @nostro_acc_name, NULL, NULL, concat('0360009421', @product_id),
|
||||
0, 1, 1, 1, NULL, 'Loan NOSTRO');
|
||||
|
||||
INSERT INTO `acc_product_mapping` VALUES (
|
||||
NULL,
|
||||
(SELECT id
|
||||
FROM acc_gl_account
|
||||
WHERE name = @nostro_acc_name),
|
||||
@product_id,
|
||||
NULL, NULL, NULL, 1);
|
||||
|
||||
SET @cash_acc_name = concat('Loan Product Cash_', @product_id);
|
||||
INSERT INTO `acc_gl_account` VALUES (
|
||||
NULL, @cash_acc_name, NULL, NULL, concat('0360009422', @product_id),
|
||||
0, 1, 1, 1, NULL, 'Loan Product Cash');
|
||||
|
||||
INSERT INTO `acc_product_mapping` VALUES (
|
||||
NULL,
|
||||
(SELECT id
|
||||
FROM acc_gl_account
|
||||
WHERE name = @cash_acc_name),
|
||||
@product_id,
|
||||
NULL, NULL, NULL, 1);
|
||||
|
||||
SET @expen_acc_name = concat('Loan Product Expenses_', @product_id);
|
||||
INSERT INTO `acc_gl_account` VALUES (
|
||||
NULL, @expen_acc_name, NULL, NULL, concat('0360009423', @product_id),
|
||||
0, 1, 1, 1, NULL, 'Loan Product Expenses');
|
||||
|
||||
INSERT INTO `acc_product_mapping` VALUES (
|
||||
NULL,
|
||||
(SELECT id
|
||||
FROM acc_gl_account
|
||||
WHERE name = @expen_acc_name),
|
||||
@product_id,
|
||||
NULL, NULL, NULL, 5);
|
||||
|
||||
SET @accrue_acc_name = concat('Loan Product Accrue Liability_', @product_id);
|
||||
INSERT INTO `acc_gl_account` VALUES (
|
||||
NULL, @accrue_acc_name, NULL, NULL, concat('0360009424', @product_id),
|
||||
0, 1, 1, 1, NULL, 'Loan Product Accrue Liability');
|
||||
|
||||
INSERT INTO `acc_product_mapping` VALUES (
|
||||
NULL,
|
||||
(SELECT id
|
||||
FROM acc_gl_account
|
||||
WHERE name = @accrue_acc_name),
|
||||
@product_id,
|
||||
NULL, NULL, NULL, 2);
|
||||
|
||||
SET @equ_acc_name = concat('Loan Product Equity_', @product_id);
|
||||
INSERT INTO `acc_gl_account` VALUES (
|
||||
NULL, @equ_acc_name, NULL, NULL, concat('0360009425', @product_id),
|
||||
0, 1, 1, 1, NULL, 'Loan Product Equity');
|
||||
|
||||
INSERT INTO `acc_product_mapping` VALUES (
|
||||
NULL,
|
||||
(SELECT id
|
||||
FROM acc_gl_account
|
||||
WHERE name = @equ_acc_name),
|
||||
@product_id,
|
||||
NULL, NULL, NULL, 3);
|
||||
|
||||
SET @feer_acc_name = concat('Loan Product Fees Revenue_', @product_id);
|
||||
INSERT INTO `acc_gl_account` VALUES (
|
||||
NULL, @feer_acc_name, NULL, NULL, concat('0360009426', @product_id),
|
||||
0, 1, 1, 1, NULL, 'Loan Product Fees Revenue');
|
||||
|
||||
INSERT INTO `acc_product_mapping` VALUES (
|
||||
NULL,
|
||||
(SELECT id
|
||||
FROM acc_gl_account
|
||||
WHERE name = @feer_acc_name),
|
||||
@product_id,
|
||||
NULL, NULL, NULL, 4);*/
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
--
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||
-- or more contributor license agreements. See the NOTICE file
|
||||
-- distributed with this work for additional information
|
||||
-- regarding copyright ownership. The ASF licenses this file
|
||||
-- to you under the Apache License, Version 2.0 (the
|
||||
-- "License"); you may not use this file except in compliance
|
||||
-- with the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing,
|
||||
-- software distributed under the License is distributed on an
|
||||
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
-- KIND, either express or implied. See the License for the
|
||||
-- specific language governing permissions and limitations
|
||||
-- under the License.
|
||||
--
|
||||
|
||||
-- To use: Change saving_account_no before every run!
|
||||
|
||||
USE `tn03`;
|
||||
|
||||
-- data initialization
|
||||
-- user+roles
|
||||
|
||||
-- client
|
||||
SET @saving_account_no = '9062b90de19b43989005';
|
||||
|
||||
INSERT INTO `m_client` (`account_no`, `external_id`, `status_enum`, `sub_status`, `activation_date`, `office_joining_date`,
|
||||
`office_id`, `transfer_to_office_id`, `staff_id`, `firstname`, `middlename`, `lastname`, `fullname`,
|
||||
`display_name`, `mobile_no`, `gender_cv_id`, `date_of_birth`, `image_id`, `closure_reason_cv_id`,
|
||||
`closedon_date`, `updated_by`, `updated_on`, `submittedon_date`, `submittedon_userid`, `activatedon_userid`,
|
||||
`closedon_userid`, `default_savings_product`, `default_savings_account`, `client_type_cv_id`, `client_classification_cv_id`,
|
||||
`reject_reason_cv_id`, `rejectedon_date`, `rejectedon_userid`, `withdraw_reason_cv_id`, `withdrawn_on_date`,
|
||||
`withdraw_on_userid`, `reactivated_on_date`, `reactivated_on_userid`, `legal_form_enum`, `reopened_on_date`,
|
||||
`reopened_by_userid`)
|
||||
VALUES (@saving_account_no, NULL, 300, NULL, ADDDATE(curdate(), -100), NULL, 1, NULL, NULL, NULL, NULL, NULL,
|
||||
'InteropCustomer', 'InteropCustomer', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ADDDATE(curdate(), -100),
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,NULL, NULL);
|
||||
|
||||
-- saving product, account
|
||||
SET @last_saving_prod_id = -1;
|
||||
SELECT COALESCE(max(id), 1) into @last_saving_prod_id from m_savings_product;
|
||||
|
||||
SET @saving_prod_name = concat('Saving Product', @last_saving_prod_id);
|
||||
SET @saving_prod_id = -1;
|
||||
SELECT id INTO @saving_prod_id FROM m_savings_product WHERE name = @saving_prod_name;
|
||||
|
||||
SET @client_id = -1;
|
||||
SELECT id INTO @client_id FROM m_client WHERE fullname = 'InteropCustomer';
|
||||
|
||||
INSERT INTO `m_savings_account`
|
||||
(`account_no`, `external_id`, `client_id`, `group_id`, `product_id`, `field_officer_id`, `status_enum`,
|
||||
`sub_status_enum`, `account_type_enum`, `deposit_type_enum`, `submittedon_date`, `submittedon_userid`,
|
||||
`approvedon_date`, `approvedon_userid`, `activatedon_date`, `activatedon_userid`,
|
||||
`currency_code`, `currency_digits`, `currency_multiplesof`, `nominal_annual_interest_rate`,
|
||||
`interest_compounding_period_enum`, `interest_posting_period_enum`, `interest_calculation_type_enum`,
|
||||
`interest_calculation_days_in_year_type_enum`, `min_required_opening_balance`, `withdrawal_fee_for_transfer`,
|
||||
`allow_overdraft`, `account_balance_derived`, `min_required_balance`, `enforce_min_required_balance`,
|
||||
`version`, `withhold_tax`)
|
||||
VALUES (@saving_account_no, '9062b90de19b43989005d9', @client_id, NULL, @saving_prod_id, NULL, 300, 0, 1, 100, ADDDATE(curdate(), -100),
|
||||
NULL, ADDDATE(curdate(), -100), NULL, ADDDATE(curdate(), -100), NULL, 'TZS', 2, NULL, 1.000000, 1, 4, 1, -- 29. - 4
|
||||
360, NULL, 1, 1, 100000000.000000, 0.000000, 1, 1, 0);
|
||||
|
||||
-- interop_identifier
|
||||
SET @saving_acc_id = -1;
|
||||
SELECT id INTO @saving_acc_id FROM m_savings_account WHERE account_no = @saving_account_no;
|
||||
|
||||
INSERT INTO interop_identifier (id, account_id, type, a_value, sub_value_or_type, created_by, created_on, modified_by, modified_on)
|
||||
VALUES (NULL, @saving_acc_id, 'IBAN', 'IC11in02tn039062b90de19b43989005d9', NULL, 'operator', CURDATE(), 'operator',
|
||||
CURDATE());
|
||||
INSERT INTO interop_identifier (id, account_id, type, a_value, sub_value_or_type, created_by, created_on, modified_by, modified_on)
|
||||
VALUES (NULL, @saving_acc_id, 'MSISDN', '27710203999', NULL, 'operator', CURDATE(), 'operator', CURDATE());
|
||||
|
||||
-- charge, mapping
|
||||
-- gl_account, mappings
|
||||
-- ASSET-1, LIABILITY-2, EQUITY-3, INCOME-4, EXPENSE-5
|
||||
SET @charge_name = 'Interoperation Withdraw Fee';
|
||||
|
||||
INSERT INTO `m_savings_account_charge` (`savings_account_id`, `charge_id`, `is_penalty`, `charge_time_enum`, `charge_calculation_enum`,
|
||||
`amount`, `amount_outstanding_derived`,`is_paid_derived`, `waived`, `is_active`)
|
||||
VALUES (@saving_acc_id, (SELECT id FROM m_charge WHERE name = @charge_name), 0, 5, 1, 1.000000, 0.000000, 0, 0, 1);
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
--
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||
-- or more contributor license agreements. See the NOTICE file
|
||||
-- distributed with this work for additional information
|
||||
-- regarding copyright ownership. The ASF licenses this file
|
||||
-- to you under the Apache License, Version 2.0 (the
|
||||
-- "License"); you may not use this file except in compliance
|
||||
-- with the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing,
|
||||
-- software distributed under the License is distributed on an
|
||||
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
-- KIND, either express or implied. See the License for the
|
||||
-- specific language governing permissions and limitations
|
||||
-- under the License.
|
||||
--
|
||||
|
||||
-- To use: Change saving_account_no before every run!
|
||||
|
||||
USE `tn04`;
|
||||
|
||||
-- data initialization
|
||||
-- user+roles
|
||||
|
||||
-- client
|
||||
SET @saving_account_no = 'a6b6c10b2aaa4778ac2f';
|
||||
|
||||
INSERT INTO `m_client` (`account_no`, `external_id`, `status_enum`, `sub_status`, `activation_date`, `office_joining_date`,
|
||||
`office_id`, `transfer_to_office_id`, `staff_id`, `firstname`, `middlename`, `lastname`, `fullname`,
|
||||
`display_name`, `mobile_no`, `gender_cv_id`, `date_of_birth`, `image_id`, `closure_reason_cv_id`,
|
||||
`closedon_date`, `updated_by`, `updated_on`, `submittedon_date`, `submittedon_userid`, `activatedon_userid`,
|
||||
`closedon_userid`, `default_savings_product`, `default_savings_account`, `client_type_cv_id`, `client_classification_cv_id`,
|
||||
`reject_reason_cv_id`, `rejectedon_date`, `rejectedon_userid`, `withdraw_reason_cv_id`, `withdrawn_on_date`,
|
||||
`withdraw_on_userid`, `reactivated_on_date`, `reactivated_on_userid`, `legal_form_enum`, `reopened_on_date`,
|
||||
`reopened_by_userid`)
|
||||
VALUES (@saving_account_no, NULL, 300, NULL, ADDDATE(curdate(), -100), NULL, 1, NULL, NULL, NULL, NULL, NULL,
|
||||
'InteropMerchant', 'InteropMerchant', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ADDDATE(curdate(), -100),
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,NULL, NULL);
|
||||
|
||||
-- saving product, account
|
||||
SET @last_saving_prod_id = -1;
|
||||
SELECT COALESCE(max(id), 1) into @last_saving_prod_id from m_savings_product;
|
||||
|
||||
SET @saving_prod_name = concat('Saving Product', @last_saving_prod_id);
|
||||
SET @saving_prod_id = -1;
|
||||
SELECT id INTO @saving_prod_id FROM m_savings_product WHERE name = @saving_prod_name;
|
||||
|
||||
SET @client_id = -1;
|
||||
SELECT id INTO @client_id FROM m_client WHERE fullname = 'InteropMerchant';
|
||||
|
||||
INSERT INTO `m_savings_account`
|
||||
(`account_no`, `external_id`, `client_id`, `group_id`, `product_id`, `field_officer_id`, `status_enum`,
|
||||
`sub_status_enum`, `account_type_enum`, `deposit_type_enum`, `submittedon_date`, `submittedon_userid`,
|
||||
`approvedon_date`, `approvedon_userid`, `activatedon_date`, `activatedon_userid`,
|
||||
`currency_code`, `currency_digits`, `currency_multiplesof`, `nominal_annual_interest_rate`,
|
||||
`interest_compounding_period_enum`, `interest_posting_period_enum`, `interest_calculation_type_enum`,
|
||||
`interest_calculation_days_in_year_type_enum`, `min_required_opening_balance`, `withdrawal_fee_for_transfer`,
|
||||
`allow_overdraft`, `account_balance_derived`, `min_required_balance`, `enforce_min_required_balance`,
|
||||
`version`, `withhold_tax`)
|
||||
VALUES (@saving_account_no, 'a6b6c10b2aaa4778ac2fc9', @client_id, NULL, @saving_prod_id, NULL, 300, 0, 1, 100, ADDDATE(curdate(), -100),
|
||||
NULL, ADDDATE(curdate(), -100), NULL, ADDDATE(curdate(), -100), NULL, 'TZS', 2, NULL, 1.000000, 1, 4, 1, -- 29. - 4
|
||||
360, NULL, 1, 1, 100000000.000000, 0.000000, 1, 1, 0);
|
||||
|
||||
-- interop_identifier
|
||||
SET @saving_acc_id = -1;
|
||||
SELECT id INTO @saving_acc_id FROM m_savings_account WHERE account_no = @saving_account_no;
|
||||
|
||||
INSERT INTO interop_identifier (id, account_id, type, a_value, sub_value_or_type, created_by, created_on, modified_by, modified_on)
|
||||
VALUES (NULL, @saving_acc_id, 'IBAN', 'IC11in02tn04a6b6c10b2aaa4778ac2fc9', NULL, 'operator', CURDATE(), 'operator',
|
||||
CURDATE());
|
||||
INSERT INTO interop_identifier (id, account_id, type, a_value, sub_value_or_type, created_by, created_on, modified_by, modified_on)
|
||||
VALUES (NULL, @saving_acc_id, 'MSISDN', '27710204999', NULL, 'operator', CURDATE(), 'operator', CURDATE());
|
||||
|
||||
-- charge, mapping
|
||||
-- gl_account, mappings
|
||||
-- ASSET-1, LIABILITY-2, EQUITY-3, INCOME-4, EXPENSE-5
|
||||
SET @charge_name = 'Interoperation Withdraw Fee';
|
||||
|
||||
INSERT INTO `m_savings_account_charge` (`savings_account_id`, `charge_id`, `is_penalty`, `charge_time_enum`, `charge_calculation_enum`,
|
||||
`amount`, `amount_outstanding_derived`,`is_paid_derived`, `waived`, `is_active`)
|
||||
VALUES (@saving_acc_id, (SELECT id FROM m_charge WHERE name = @charge_name), 0, 5, 1, 1.000000, 0.000000, 0, 0, 1);
|
||||
Reference in New Issue
Block a user