diff --git a/.gitignore b/.gitignore index fe5a6fca0..af7eae4be 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ repos rebel.xml *.sublime-workspace *.DS_Store +*.ini diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index 7102c41b4..781539785 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -470,6 +470,22 @@ + + Loan Charges + loans/{loanId}/charges + Add a Loan Charge + + + + + + + loans/{loanId}/charges/{loanChargeId} + + Retrieve a Loan Charge + Modify a Loan Charge + Delete a Loan Charge + Loan Guarantors loans/{loanId}/guarantors @@ -1529,7 +1545,7 @@ function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFuncti Error Message returned when attempting to create an Office without passing any parameters { "developerMessage": "The request was invalid. This typically will happen due to validation errors which are provided.", -"developerDocLink": "https://github.com/keithwoodlock/mifosx/wiki/HTTP-API-Error-codes", +"developerDocLink": "https://github.com/openMF/mifosx/wiki/HTTP-API-Error-codes", "httpStatusCode": "400", "defaultUserMessage": "Validation errors exist.", "userMessageGlobalisationCode": "validation.msg.validation.errors.exist", @@ -4260,255 +4276,7 @@ Request Body: - -   -
-
-

Loan Charges

-

Loan charges can be fees or penalities. They can be defined using the charges api and associated with loan products.

-

- - - - - - - - - - - - - - - - - - - - - - -
Field Descriptions
chargeId
The id of the charge definition.
amount
The flat amount or percenatge amount of the charge. (depending on its type)
dueDate
The date the loan charge is due for collection. Relevant for charges defined as specified due date.
-
-
- -   -
-
-

Retrieve Loan Charge Template

-

This is a convenience resource. It can be useful when - building maintenance user interface screens for client - applications. The template data returned consists of any or all - of: -

-

-

Example Request:

-
loans/1/charges/template
-
-
- -GET https://DomainName/api/v1/loans/{loanId}/charges/template - - -{ - { - "amountPaid": 0, - "amountWaived": 0, - "amountWrittenOff": 0, - "chargeOptions": [ - { - "id": 1, - "name": "Bank Fee (per installment)", - "active": true, - "penalty": false, - "currency": { - "code": "UGX", - "name": "Uganda Shilling", - "decimalPlaces": 2, - "displaySymbol": "USh", - "nameCode": "currency.UGX", - "displayLabel": "Uganda Shilling (USh)" - }, - "amount": 1500, - "chargeTimeType": { - "id": 2, - "code": "chargeTimeType.specifiedDueDate", - "value": "Specified due date" - }, - "chargeAppliesTo": { - "id": 1, - "code": "chargeAppliesTo.loan", - "value": "Loan" - }, - "chargeCalculationType": { - "id": 1, - "code": "chargeCalculationType.flat", - "value": "Flat" - } - } - ], - "penalty": false -} -} - -
-
- -   -
-
-

Create a Loan Charge

- - - - - - - -
Mandatory Fields
chargeId, amount, dueDate (depending on chargeTimeType of charge definition)
-
-
- -POST https://DomainName/api/v1//loans/{loanId}/charges - - -POST /loans/1/charges -Content-Type: application/json -Request Body: -{ - "locale": "en", - "dateFormat": "dd MMMM yyyy", - "chargeId": 1, - "amount": "333", - "dueDate": "21 November 2011" -} - - -{ - "officeId": 1, - "clientId": 1, - "loanId": 1, - "resourceId": 14 -} - -
-
- -   -
-
-

Update a Loan Charge

-
-
- -PUT https://DomainName/api/v1//loans/{loanId}/charges/{loanChargeId} - - -PUT /loans/1/charges/14 -Content-Type: application/json -Request Body: -{ - "locale": "en", - "amount": "650" -} - - -{ - "officeId": 1, - "clientId": 1, - "loanId": 1, - "resourceId": 14, - "changes": { - "amount": 650, - "locale": "en" - } -} - -
-
- -   -
-
-

Delete a Loan Charge

-
-
- -DELETE https://DomainName/api/v1//loans/{loanId}/charges/{loanChargeId} - - -DELETE /loans/1/charges/14 -Content-Type: application/json - - -{ - "officeId": 1, - "clientId": 1, - "loanId": 1, - "resourceId": 14 -} - -
-
- -   -
-
-

Retrieve a Loan Charge

-
-
- -GET https://DomainName/api/v1//loans/{loanId}/charges/{loanChargeId} - - -GET /loans/1/charges/1 -Content-Type: application/json - - -{ - "id": 14, - "chargeId": 1, - "name": "Bank Fee (per installment)", - "chargeTimeType": { - "id": 2, - "code": "chargeTimeType.specifiedDueDate", - "value": "Specified due date" - }, - "dueDate": [ - 2011, - 11, - 21 - ], - "chargeCalculationType": { - "id": 1, - "code": "chargeCalculationType.flat", - "value": "Flat" - }, - "percentage": 0, - "amountPercentageAppliedTo": 0, - "currency": { - "code": "UGX", - "name": "Uganda Shilling", - "decimalPlaces": 2, - "displaySymbol": "USh", - "nameCode": "currency.UGX", - "displayLabel": "Uganda Shilling (USh)" - }, - "amount": 650, - "amountPaid": 0, - "amountWaived": 0, - "amountWrittenOff": 0, - "amountOutstanding": 650, - "amountOrPercentage": 650, - "penalty": false -} - -
-
+  
@@ -5116,6 +4884,431 @@ No Request Body:
+ +   +
+
+

Loan Charges

+

Its typical for MFIs to add extra costs for their loan products. They + can be either Fees or Penalties.

+

Loan Charges are instances of Charges and + represent either fees and penalties for loan products. Refer Charges + for documentation of the various properties of a charge, Only additional properties ( + specific to the context of a Charge being associated with a Loan) are + described here

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
amountPaid
The Total amount which has been paid for this Charge +
amountWaived
The Total amount that has been waived for this Charge +
amountWrittenOff
Total amount written off from this Charge +
amountOutstanding
The Total outstanding amount for this Charge +
+
+
+ +   +
+
+

List Loan Charges

+

Example Requests:

+
loans/1/charges
+
+
+
loans/1/charges?fields=name,amountOrPercentage
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/charges + + +[ + { + "id": 1, + "chargeId": 1, + "name": "Loan Processing fee", + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false + }, + { + "id": 7, + "chargeId": 2, + "name": "Collection Fee", + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "dueDate": [ + 2013, + 3, + 29 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false + } +] + +
+
+ +   +
+
+

Retrieve Loan Charges Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

+

+

Example Request:

+
loans/1/charges/template
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/charges/template + + +{ + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "chargeOptions": [ + { + "id": 2, + "name": "Collection Fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + } + }, + { + "id": 3, + "name": "Late payment penalty", + "active": true, + "penalty": true, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 1, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + } + }, + { + "id": 1, + "name": "Loan Processing fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + } + } + ], + "penalty": false +} + +
+
+ +   +
+
+

Retrieve a Loan Charge

+

Example Requests:

+
/loans/1/charges/1
+
+
+
/loans/1/charges/1?fields=name,amountOrPercentage
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/charges/{chargeId} + + +{ + "id": 1, + "chargeId": 1, + "name": "Loan Processing fee", + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false +} +
+
+ +   +
+
+

Create a Loan Charge

+ + + + + + + +
Mandatory Fields + for Loan Charges
chargeId, amount, dueDate
+
+
+ +POST https://DomainName/api/v1/loans/{loanId}/charges + + +POST /loans/1/charges +Content-Type: application/json +Request Body: +{ + "chargeId": "2", + "locale": "en", + "amount": "100", + "dateFormat": "dd MMMM yyyy", + "dueDate": "29 April 2013" +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 31 +} + +
+
+ +   +
+
+

Update a Loan Charge

+

Currently Loan Charges may be updated only if the Loan + is not yet approved +

+
+
+ +PUT https://DomainName/api/v1/loans/{loanId}/charges/{chargeId} + + +PUT loans/1/charges/12 +Content-Type: application/json +Request Body: +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "amount": "60", + "dueDate": "27 March 2013" +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 6, + "changes": { + "dueDate": "27 March 2013", + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "amount": 60.0 + } +} + +
+
+ +   +
+
+

Delete a Loan Charge

+

+ Note:Currently, A Loan Charge may only be removed from Loans that are not + yet approved. +

+
+
+ +DELETE https://DomainName/api/v1/loans/{loanId}/charges/{chargeId} + + +DELETE loans/1/charges/2 +Content-Type: application/json +No Request Body: + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 2 +} + +
+
+  
@@ -6808,7 +7001,7 @@ Request Body:

Staff

Allows you to model staff members. At present the key role - of signifigance is whether this staff member is a loan officer or + of significance is whether this staff member is a loan officer or not.

@@ -6925,21 +7118,156 @@ Request Body: - +  

Charges

- Its typical for MFIs to add extra costs to their financial - products. There are typically Fees or Penalites. + Its typical for MFIs to add extra costs for their financial + products. There are typically Fees or Penalties.

-

Charges is what we use to model both fees and penalities. +

Charges is what we use to model both fees and penalties. For now charges can only be associated with loan products / loans.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
Name associated with this charge.
active
Boolean flag determines if the Charge is currently active.
penalty
Boolean flag determines if the Charge is a penalty.
currency
Details of the currency associated with this charge. + Refer Charges Template for additional details
amount
Field holds the details of the actual amount to be collected + in the case of "Flat Charges" or the percentage amount to be collected in + case of "Percentage Amount Charges". Refer Charges Template + for details of the Available Charge Types
chargeTimeType
The time at which the charge becomes Due. + Refer Charges Template for additional details
chargeAppliesTo
The Entity for which the charge can be applied (Loans etc). + Refer Charges Template for additional details
chargeCalculationType
Rules for calculating the amount for a particular Charge. + Refer Charges Template for additional details
-   +   +
+
+

Retrieve Charges Details Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

+

+

Example Request:

+
charges/template
+
+
+ +GET https://DomainName/api/v1/charges/template + + +{ + "active": false, + "penalty": false, + "currencyOptions": + [ + { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + ], + "chargeCalculationTypeOptions": + [ + { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + { + "id": 2, + "code": "chargeCalculationType.percent.of.amount", + "value": "% Amount" + } + ], + "chargeAppliesToOptions": + [ + { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + } + ], + "chargeTimeTypeOptions": + [ + { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + } + ] +} + +
+
+ +  

Create/Define a Charge

@@ -6965,7 +7293,32 @@ Request Body: "active": true } - { "resourceId": 1 } + +{ + "resourceId": 1 +} + + +POST charges +Content-Type: application/json +Request Body: +{ + "locale": "en", + "name": "Default Penalty", + "amount": "2", + "currencyCode": "USD", + "chargeAppliesTo": "1", + "chargeTimeType": "2", + "chargeCalculationType": "2", + "active": "true", + "penalty": "true" +} + + +{ + "resourceId": 4 +} +
@@ -7118,8 +7471,8 @@ Content-Type: application/json

Savings Product:

-

An MFIs savings product offerings are modelled using this API.

-

When creating savings accounts, the details from the savings product are used to autofill details of savings account.

+

An MFIs savings product offerings are modeled using this API.

+

When creating savings accounts, the details from the savings product are used to auto fill details of savings account.

@@ -7130,7 +7483,7 @@ Content-Type: application/json - + @@ -7724,7 +8077,7 @@ Request Body:

Arguments

associations
-
optional, Either 'all' or a comma separated list of savings 'associations' (itemised below).
+
optional, Either 'all' or a comma separated list of savings 'associations' (itemized below).

Associations are just extra pieces of data that you might or might not want to retrieve.

'all': Gets data related to all associations e.g. ?associations=all.
'transactions': Gets data related to transactions on the account e.g. ?associations=transactions
@@ -7813,7 +8166,7 @@ No Request Body:

Delete a Savings Account

-

At present we support hard delete of savings account but this is likely to change to a savings account closure or de-activation process/command.

+

At present we support hard delete of savings account but this is likely to change to a savings account closure or De-activation process/command.

DELETE https://Domain Name/api/v1/savingsaccounts/{accountsId} @@ -7959,7 +8312,7 @@ No Request Body: 'plugged-in' table. The API checks for permission and for 'data scoping' (only data within the users' office hierarchy can be managed by the user).

-

The Mifos X Reference App uses a JQuery plugin called +

The Mifos X Reference App uses a JQuery plug-in called stretchydatatables (which in turn uses this datatables resource) to provide a pretty flexible CRUD (Create, Read, Update, Delete) User Interface.

@@ -9927,7 +10280,7 @@ No Request Body { "developerMessage": "Invalid authentication details were passed in api request.", - "developerDocLink": "https://github.com/keithwoodlock/mifosx/wiki/HTTP-API-Error-codes", + "developerDocLink": "https://github.com/openMF/mifosx/wiki/HTTP-API-Error-codes", "httpStatusCode": "401", "defaultUserMessage": "Unauthenticated. Please login.", "userMessageGlobalisationCode": "error.msg.not.authenticated", @@ -11720,7 +12073,7 @@ Content-Type: application/json
- + diff --git a/keystore.jks b/keystore.jks new file mode 100644 index 000000000..d407af322 Binary files /dev/null and b/keystore.jks differ diff --git a/mifosng-db/migrations/V1__mifosplatform-core-ddl-latest.sql b/mifosng-db/migrations/V1__mifosplatform-core-ddl-latest.sql index 54a24d01b..339ef8b0b 100644 --- a/mifosng-db/migrations/V1__mifosplatform-core-ddl-latest.sql +++ b/mifosng-db/migrations/V1__mifosplatform-core-ddl-latest.sql @@ -595,6 +595,7 @@ CREATE TABLE `m_loan_arrears_aging` ( CREATE TABLE `m_guarantor` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `loan_id` BIGINT(20) NOT NULL, + `client_reln_cv_id` INT(11) DEFAULT NULL, `type_enum` SMALLINT(5) NOT NULL, `entity_id` BIGINT(20) NULL DEFAULT NULL, `firstname` VARCHAR(50) NULL DEFAULT NULL, @@ -611,6 +612,7 @@ CREATE TABLE `m_guarantor` ( `comment` VARCHAR(500) NULL DEFAULT NULL, PRIMARY KEY (`id`), INDEX `FK_m_guarantor_m_loan` (`loan_id`), + CONSTRAINT `FK_m_guarantor_m_code_value` FOREIGN KEY (`client_reln_cv_id`) REFERENCES `m_code_value` (`id`), CONSTRAINT `FK_m_guarantor_m_loan` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -642,6 +644,7 @@ CREATE TABLE `m_loan_collateral` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `loan_id` bigint(20) NOT NULL, `type_cv_id` int(11) NOT NULL, + `value` DECIMAL(19,6) DEFAULT NULL, `description` varchar(500) DEFAULT NULL, PRIMARY KEY (`id`), KEY `FK_collateral_m_loan` (`loan_id`), diff --git a/mifosng-db/migrations/V2__mifosx-base-reference-data-utf8.sql b/mifosng-db/migrations/V2__mifosx-base-reference-data-utf8.sql index 80a68352d..1393ea946 100644 --- a/mifosng-db/migrations/V2__mifosx-base-reference-data-utf8.sql +++ b/mifosng-db/migrations/V2__mifosx-base-reference-data-utf8.sql @@ -271,7 +271,8 @@ VALUES ('LoanCollateral',1), ('LoanPurpose',1), ('Gender',1), -('YesNo',1); +('YesNo',1), +('GuarantorRelationship',1); INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) select mc.id, 'Passport', 1 @@ -291,4 +292,30 @@ where mc.`code_name` = "Customer Identifier"; INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) select mc.id, 'Any Other Id Type', 4 from m_code mc -where mc.`code_name` = "Customer Identifier"; \ No newline at end of file +where mc.`code_name` = "Customer Identifier"; + +-- Adding a few Default Guarantor Relationships +insert into m_code_value (code_id,code_value,order_position) + select id,"Spouse",0 + from m_code + where m_code.code_name="GuarantorRelationship"; + +insert into m_code_value (code_id,code_value,order_position) + select id,"Parent",0 + from m_code + where m_code.code_name="GuarantorRelationship"; + +insert into m_code_value (code_id,code_value,order_position) + select id,"Sibling",0 + from m_code + where m_code.code_name="GuarantorRelationship"; + +insert into m_code_value (code_id,code_value,order_position) + select id,"Business Associate",0 + from m_code + where m_code.code_name="GuarantorRelationship"; + +insert into m_code_value (code_id,code_value,order_position) + select id,"Other",0 + from m_code + where m_code.code_name="GuarantorRelationship"; \ No newline at end of file diff --git a/mifosng-db/migrations/V3__mifosx-permissions-and-authorisation-utf8.sql b/mifosng-db/migrations/V3__mifosx-permissions-and-authorisation-utf8.sql index 971065a42..aaf726ab1 100644 --- a/mifosng-db/migrations/V3__mifosx-permissions-and-authorisation-utf8.sql +++ b/mifosng-db/migrations/V3__mifosx-permissions-and-authorisation-utf8.sql @@ -220,6 +220,13 @@ INSERT INTO `m_permission` ('portfolio', 'UPDATE_GUARANTOR_CHECKER', 'GUARANTOR', 'UPDATE', 0), ('portfolio', 'DELETE_GUARANTOR', 'GUARANTOR', 'DELETE', 1), ('portfolio', 'DELETE_GUARANTOR_CHECKER', 'GUARANTOR', 'DELETE', 0), +('portfolio', 'READ_COLLATERAL', 'COLLATERAL', 'READ', '0'), +('portfolio', 'CREATE_COLLATERAL', 'COLLATERAL', 'CREATE', '1'), +('portfolio', 'UPDATE_COLLATERAL', 'COLLATERAL', 'UPDATE', '1'), +('portfolio', 'DELETE_COLLATERAL', 'COLLATERAL', 'DELETE', '1'), +('portfolio', 'CREATE_COLLATERAL_CHECKER', 'COLLATERAL', 'CREATE', '0'), +('portfolio', 'UPDATE_COLLATERAL_CHECKER', 'COLLATERAL', 'UPDATE', '0'), +('portfolio', 'DELETE_COLLATERAL_CHECKER', 'COLLATERAL', 'DELETE', '0'), ('transaction_loan', 'APPROVE_LOAN', 'LOAN', 'APPROVE', '1'), ('transaction_loan', 'APPROVEINPAST_LOAN', 'LOAN', 'APPROVEINPAST', '1'), ('transaction_loan', 'REJECT_LOAN', 'LOAN', 'REJECT', '1'), diff --git a/mifosng-db/0001a-mifosplatform-core-ddl-latest.sql b/mifosng-db/old-schema-files/0001a-mifosplatform-core-ddl-latest.sql similarity index 99% rename from mifosng-db/0001a-mifosplatform-core-ddl-latest.sql rename to mifosng-db/old-schema-files/0001a-mifosplatform-core-ddl-latest.sql index 54a24d01b..dc02925ad 100644 --- a/mifosng-db/0001a-mifosplatform-core-ddl-latest.sql +++ b/mifosng-db/old-schema-files/0001a-mifosplatform-core-ddl-latest.sql @@ -595,6 +595,7 @@ CREATE TABLE `m_loan_arrears_aging` ( CREATE TABLE `m_guarantor` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `loan_id` BIGINT(20) NOT NULL, + `client_reln_cv_id` INT(11) DEFAULT NULL, `type_enum` SMALLINT(5) NOT NULL, `entity_id` BIGINT(20) NULL DEFAULT NULL, `firstname` VARCHAR(50) NULL DEFAULT NULL, @@ -611,6 +612,7 @@ CREATE TABLE `m_guarantor` ( `comment` VARCHAR(500) NULL DEFAULT NULL, PRIMARY KEY (`id`), INDEX `FK_m_guarantor_m_loan` (`loan_id`), + CONSTRAINT `FK_m_guarantor_m_code_value` FOREIGN KEY (`client_reln_cv_id`) REFERENCES `m_code_value` (`id`) CONSTRAINT `FK_m_guarantor_m_loan` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -642,6 +644,7 @@ CREATE TABLE `m_loan_collateral` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `loan_id` bigint(20) NOT NULL, `type_cv_id` int(11) NOT NULL, + `value` DECIMAL(19,6) DEFAULT NULL, `description` varchar(500) DEFAULT NULL, PRIMARY KEY (`id`), KEY `FK_collateral_m_loan` (`loan_id`), diff --git a/mifosng-db/0002-mifosx-base-reference-data-utf8.sql b/mifosng-db/old-schema-files/0002-mifosx-base-reference-data-utf8.sql similarity index 94% rename from mifosng-db/0002-mifosx-base-reference-data-utf8.sql rename to mifosng-db/old-schema-files/0002-mifosx-base-reference-data-utf8.sql index 80a68352d..1393ea946 100644 --- a/mifosng-db/0002-mifosx-base-reference-data-utf8.sql +++ b/mifosng-db/old-schema-files/0002-mifosx-base-reference-data-utf8.sql @@ -271,7 +271,8 @@ VALUES ('LoanCollateral',1), ('LoanPurpose',1), ('Gender',1), -('YesNo',1); +('YesNo',1), +('GuarantorRelationship',1); INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) select mc.id, 'Passport', 1 @@ -291,4 +292,30 @@ where mc.`code_name` = "Customer Identifier"; INSERT INTO `m_code_value`(`code_id`,`code_value`,`order_position`) select mc.id, 'Any Other Id Type', 4 from m_code mc -where mc.`code_name` = "Customer Identifier"; \ No newline at end of file +where mc.`code_name` = "Customer Identifier"; + +-- Adding a few Default Guarantor Relationships +insert into m_code_value (code_id,code_value,order_position) + select id,"Spouse",0 + from m_code + where m_code.code_name="GuarantorRelationship"; + +insert into m_code_value (code_id,code_value,order_position) + select id,"Parent",0 + from m_code + where m_code.code_name="GuarantorRelationship"; + +insert into m_code_value (code_id,code_value,order_position) + select id,"Sibling",0 + from m_code + where m_code.code_name="GuarantorRelationship"; + +insert into m_code_value (code_id,code_value,order_position) + select id,"Business Associate",0 + from m_code + where m_code.code_name="GuarantorRelationship"; + +insert into m_code_value (code_id,code_value,order_position) + select id,"Other",0 + from m_code + where m_code.code_name="GuarantorRelationship"; \ No newline at end of file diff --git a/mifosng-db/0003-mifosx-permissions-and-authorisation-utf8.sql b/mifosng-db/old-schema-files/0003-mifosx-permissions-and-authorisation-utf8.sql similarity index 97% rename from mifosng-db/0003-mifosx-permissions-and-authorisation-utf8.sql rename to mifosng-db/old-schema-files/0003-mifosx-permissions-and-authorisation-utf8.sql index 971065a42..aaf726ab1 100644 --- a/mifosng-db/0003-mifosx-permissions-and-authorisation-utf8.sql +++ b/mifosng-db/old-schema-files/0003-mifosx-permissions-and-authorisation-utf8.sql @@ -220,6 +220,13 @@ INSERT INTO `m_permission` ('portfolio', 'UPDATE_GUARANTOR_CHECKER', 'GUARANTOR', 'UPDATE', 0), ('portfolio', 'DELETE_GUARANTOR', 'GUARANTOR', 'DELETE', 1), ('portfolio', 'DELETE_GUARANTOR_CHECKER', 'GUARANTOR', 'DELETE', 0), +('portfolio', 'READ_COLLATERAL', 'COLLATERAL', 'READ', '0'), +('portfolio', 'CREATE_COLLATERAL', 'COLLATERAL', 'CREATE', '1'), +('portfolio', 'UPDATE_COLLATERAL', 'COLLATERAL', 'UPDATE', '1'), +('portfolio', 'DELETE_COLLATERAL', 'COLLATERAL', 'DELETE', '1'), +('portfolio', 'CREATE_COLLATERAL_CHECKER', 'COLLATERAL', 'CREATE', '0'), +('portfolio', 'UPDATE_COLLATERAL_CHECKER', 'COLLATERAL', 'UPDATE', '0'), +('portfolio', 'DELETE_COLLATERAL_CHECKER', 'COLLATERAL', 'DELETE', '0'), ('transaction_loan', 'APPROVE_LOAN', 'LOAN', 'APPROVE', '1'), ('transaction_loan', 'APPROVEINPAST_LOAN', 'LOAN', 'APPROVEINPAST', '1'), ('transaction_loan', 'REJECT_LOAN', 'LOAN', 'REJECT', '1'), diff --git a/mifosng-db/0004-mifosx-core-reports-utf8.sql b/mifosng-db/old-schema-files/0004-mifosx-core-reports-utf8.sql similarity index 100% rename from mifosng-db/0004-mifosx-core-reports-utf8.sql rename to mifosng-db/old-schema-files/0004-mifosx-core-reports-utf8.sql diff --git a/mifosng-db/patches/1-add-status-to-savings-account.sql b/mifosng-db/patchesPutOnDemoServer20130401/1-add-status-to-savings-account.sql similarity index 100% rename from mifosng-db/patches/1-add-status-to-savings-account.sql rename to mifosng-db/patchesPutOnDemoServer20130401/1-add-status-to-savings-account.sql diff --git a/mifosng-db/patches/2-audit-add-account-savings-id.sql b/mifosng-db/patchesPutOnDemoServer20130401/2-audit-add-account-savings-id.sql similarity index 100% rename from mifosng-db/patches/2-audit-add-account-savings-id.sql rename to mifosng-db/patchesPutOnDemoServer20130401/2-audit-add-account-savings-id.sql diff --git a/mifosng-db/patches/3-collateral-add-value.sql b/mifosng-db/patchesPutOnDemoServer20130401/3-collateral-add-value.sql old mode 100755 new mode 100644 similarity index 100% rename from mifosng-db/patches/3-collateral-add-value.sql rename to mifosng-db/patchesPutOnDemoServer20130401/3-collateral-add-value.sql diff --git a/mifosng-db/patches/4-add-interest-calculation-fields.sql b/mifosng-db/patchesPutOnDemoServer20130401/4-add-interest-calculation-fields.sql similarity index 100% rename from mifosng-db/patches/4-add-interest-calculation-fields.sql rename to mifosng-db/patchesPutOnDemoServer20130401/4-add-interest-calculation-fields.sql diff --git a/mifosng-db/patches/5-guarantor-add-relationship.sql b/mifosng-db/patchesPutOnDemoServer20130401/5-guarantor-add-relationship.sql old mode 100755 new mode 100644 similarity index 100% rename from mifosng-db/patches/5-guarantor-add-relationship.sql rename to mifosng-db/patchesPutOnDemoServer20130401/5-guarantor-add-relationship.sql diff --git a/mifosng-provider/build.gradle b/mifosng-provider/build.gradle index 26b2b42ce..513c128b3 100644 --- a/mifosng-provider/build.gradle +++ b/mifosng-provider/build.gradle @@ -180,11 +180,14 @@ task dist(type:Zip){ task deployPentahoReports() { def pentahoReportDir = System.properties['user.home'] + System.properties['file.separator'] + '.mifosx' + System.properties['file.separator'] + 'pentahoReports' - println ":deployPentahoReports - moving pentaho reports under: " + pentahoReportDir copy { from "src/main/pentahoReports" into pentahoReportDir } + + doLast { + println ':deployPentahoReports - moving pentaho reports under: ' + pentahoReportDir + } } war { @@ -200,6 +203,7 @@ tomcatRun { httpPort = 8080 httpsPort = 8443 stopPort = 8081 + stopKey= 'stopKey' enableSSL = true configFile = file('src/test/resources/META-INF/context.xml') } @@ -208,7 +212,10 @@ tomcatRunWar { httpPort = 8080 httpsPort = 8443 stopPort = 8081 + stopKey= 'stopKey' enableSSL = true + keystoreFile = file('../keystore.jks') + keystorePass = 'openmf' configFile = file('src/test/resources/META-INF/context.xml') } @@ -224,12 +231,53 @@ configurations { } task integrationTest(type:Test){ - description = "Run integration tests (located in src/integrationTest/java). Requires server to be running." + description = "Run integration tests (located in src/integrationTest/java). Starts tomcat in daemon mode before executing the tests." + doFirst { + tomcatRunWar.daemon = true + tomcatRunWar.execute() + } + + doLast { + tomcatStop.execute() + } testClassesDir = project.sourceSets.integrationTest.output.classesDir classpath = project.sourceSets.integrationTest.runtimeClasspath } +import groovy.sql.Sql + +repositories { + mavenCentral() +} +configurations { + driver +} +dependencies { + driver 'mysql:mysql-connector-java:5.1.16' +} + +URLClassLoader loader = GroovyObject.class.classLoader +configurations.driver.each {File file -> + loader.addURL(file.toURL()) +} + +task createDatabase<<{ + description= "Creates the Database mifosplatform-tenants and mifostenant-default" + sql = Sql.newInstance( 'jdbc:mysql://localhost:3306/', 'root', 'mysql', 'com.mysql.jdbc.Driver' ) + sql.execute( 'create database `mifosplatform-tenants`' ) + sql.execute( 'create database `mifostenant-default`' ) + +} +task dropDatabase<<{ + description= "Drops the created Databases mifosplatform-tenants and mifostenant-default" + sql = Sql.newInstance( 'jdbc:mysql://localhost:3306/', 'root', 'mysql', 'com.mysql.jdbc.Driver' ) + sql.execute( 'DROP DATABASE `mifosplatform-tenants`' ) + sql.execute( 'DROP DATABASE `mifostenant-default`' ) + +} + + apply plugin: 'flyway' buildscript { repositories { @@ -272,4 +320,5 @@ def qualifyVersionIfNecessary(version) { } } return version -} \ No newline at end of file +} + diff --git a/mifosng-provider/src/main/java/org/mifosplatform/audit/api/AuditApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/api/AuditsApiResource.java similarity index 94% rename from mifosng-provider/src/main/java/org/mifosplatform/audit/api/AuditApiResource.java rename to mifosng-provider/src/main/java/org/mifosplatform/commands/api/AuditsApiResource.java index f45081002..f76d226a6 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/audit/api/AuditApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/api/AuditsApiResource.java @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mifosplatform.audit.api; +package org.mifosplatform.commands.api; import java.util.Arrays; import java.util.Collection; @@ -21,9 +21,9 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; import org.apache.commons.lang.StringUtils; -import org.mifosplatform.audit.data.AuditData; -import org.mifosplatform.audit.data.AuditSearchData; -import org.mifosplatform.audit.service.AuditReadPlatformService; +import org.mifosplatform.commands.data.AuditData; +import org.mifosplatform.commands.data.AuditSearchData; +import org.mifosplatform.commands.service.AuditReadPlatformService; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; @@ -33,10 +33,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; -@Path("/audit") +@Path("/audits") @Component @Scope("singleton") -public class AuditApiResource { +public class AuditsApiResource { private final Set RESPONSE_DATA_PARAMETERS = new HashSet( Arrays.asList("id", "actionName", "entityName", "resourceId", "subresourceId", @@ -52,7 +52,7 @@ public class AuditApiResource { private final DefaultToApiJsonSerializer toApiJsonSerializerSearchTemplate; @Autowired - public AuditApiResource( + public AuditsApiResource( final PlatformSecurityContext context, final AuditReadPlatformService auditReadPlatformService, final ApiRequestParameterHelper apiRequestParameterHelper, @@ -130,10 +130,10 @@ public class AuditApiResource { .process(uriInfo.getQueryParameters()); final AuditSearchData auditSearchData = this.auditReadPlatformService - .retrieveSearchTemplate(); + .retrieveSearchTemplate("audit"); final Set RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE = new HashSet( - Arrays.asList("appUsers", "apiOperations", "resources")); + Arrays.asList("appUsers", "actionNames", "entityNames", "processingResults")); return this.toApiJsonSerializerSearchTemplate.serialize(settings, auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/api/CommandsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/api/MakercheckersApiResource.java similarity index 76% rename from mifosng-provider/src/main/java/org/mifosplatform/commands/api/CommandsApiResource.java rename to mifosng-provider/src/main/java/org/mifosplatform/commands/api/MakercheckersApiResource.java index a7d80e02f..a53994c11 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/api/CommandsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/api/MakercheckersApiResource.java @@ -23,9 +23,10 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; import org.apache.commons.lang.StringUtils; -import org.mifosplatform.audit.data.AuditData; -import org.mifosplatform.audit.service.AuditReadPlatformService; +import org.mifosplatform.commands.data.AuditData; +import org.mifosplatform.commands.data.AuditSearchData; import org.mifosplatform.commands.data.CommandSourceData; +import org.mifosplatform.commands.service.AuditReadPlatformService; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; @@ -37,10 +38,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; -@Path("/commands") +@Path("/makercheckers") @Component @Scope("singleton") -public class CommandsApiResource { +public class MakercheckersApiResource { private final Set RESPONSE_DATA_PARAMETERS = new HashSet( Arrays.asList("id", "actionName", "entityName", "resourceId", "subresourceId", @@ -52,18 +53,21 @@ public class CommandsApiResource { private final AuditReadPlatformService readPlatformService; private final DefaultToApiJsonSerializer toApiJsonSerializer; private final DefaultToApiJsonSerializer toApiJsonSerializerAudit; + private final DefaultToApiJsonSerializer toApiJsonSerializerSearchTemplate; private final ApiRequestParameterHelper apiRequestParameterHelper; private final PortfolioCommandSourceWritePlatformService writePlatformService; @Autowired - public CommandsApiResource(final PlatformSecurityContext context, final AuditReadPlatformService readPlatformService, - final DefaultToApiJsonSerializer toApiJsonSerializer, final DefaultToApiJsonSerializer toApiJsonSerializerAudit, + public MakercheckersApiResource(final PlatformSecurityContext context, final AuditReadPlatformService readPlatformService, + final DefaultToApiJsonSerializer toApiJsonSerializer, final DefaultToApiJsonSerializer toApiJsonSerializerAudit, + final DefaultToApiJsonSerializer toApiJsonSerializerSearchTemplate, final ApiRequestParameterHelper apiRequestParameterHelper, final PortfolioCommandSourceWritePlatformService writePlatformService) { this.context = context; this.readPlatformService = readPlatformService; this.toApiJsonSerializer = toApiJsonSerializer; this.apiRequestParameterHelper = apiRequestParameterHelper; this.toApiJsonSerializerAudit = toApiJsonSerializerAudit; + this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate; this.writePlatformService = writePlatformService; } @@ -80,6 +84,28 @@ public class CommandsApiResource { return this.toApiJsonSerializerAudit.serialize(settings, entries, RESPONSE_DATA_PARAMETERS); } + @GET + @Path("/searchtemplate") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveAuditSearchTemplate(@Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission( + resourceNameForPermissions); + + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper + .process(uriInfo.getQueryParameters()); + + final AuditSearchData auditSearchData = this.readPlatformService + .retrieveSearchTemplate("makerchecker"); + + final Set RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE = new HashSet( + Arrays.asList("appUsers", "actionNames", "entityNames")); + + return this.toApiJsonSerializerSearchTemplate.serialize(settings, + auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE); + } + @POST @Path("{commandId}") @Consumes({ MediaType.APPLICATION_JSON }) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/audit/data/AuditData.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/data/AuditData.java similarity index 98% rename from mifosng-provider/src/main/java/org/mifosplatform/audit/data/AuditData.java rename to mifosng-provider/src/main/java/org/mifosplatform/commands/data/AuditData.java index 1b236c320..af059a467 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/audit/data/AuditData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/data/AuditData.java @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mifosplatform.audit.data; +package org.mifosplatform.commands.data; import org.joda.time.DateTime; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/audit/data/AuditSearchData.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/data/AuditSearchData.java similarity index 92% rename from mifosng-provider/src/main/java/org/mifosplatform/audit/data/AuditSearchData.java rename to mifosng-provider/src/main/java/org/mifosplatform/commands/data/AuditSearchData.java index 0701cbd68..a7af851f6 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/audit/data/AuditSearchData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/data/AuditSearchData.java @@ -3,12 +3,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mifosplatform.audit.data; +package org.mifosplatform.commands.data; import java.util.Collection; import java.util.List; -import org.mifosplatform.audit.api.ProcessingResultLookup; import org.mifosplatform.useradministration.data.AppUserData; /** diff --git a/mifosng-provider/src/main/java/org/mifosplatform/audit/api/ProcessingResultLookup.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/data/ProcessingResultLookup.java similarity index 94% rename from mifosng-provider/src/main/java/org/mifosplatform/audit/api/ProcessingResultLookup.java rename to mifosng-provider/src/main/java/org/mifosplatform/commands/data/ProcessingResultLookup.java index 0bf93be1a..275569067 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/audit/api/ProcessingResultLookup.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/data/ProcessingResultLookup.java @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mifosplatform.audit.api; +package org.mifosplatform.commands.data; /** * Immutable data object for application user data. diff --git a/mifosng-provider/src/main/java/org/mifosplatform/audit/service/AuditReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/AuditReadPlatformService.java similarity index 70% rename from mifosng-provider/src/main/java/org/mifosplatform/audit/service/AuditReadPlatformService.java rename to mifosng-provider/src/main/java/org/mifosplatform/commands/service/AuditReadPlatformService.java index 198cfca84..e1d40bce1 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/audit/service/AuditReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/AuditReadPlatformService.java @@ -3,12 +3,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mifosplatform.audit.service; +package org.mifosplatform.commands.service; import java.util.Collection; -import org.mifosplatform.audit.data.AuditData; -import org.mifosplatform.audit.data.AuditSearchData; +import org.mifosplatform.commands.data.AuditData; +import org.mifosplatform.commands.data.AuditSearchData; public interface AuditReadPlatformService { @@ -16,7 +16,7 @@ public interface AuditReadPlatformService { AuditData retrieveAuditEntry(Long auditId); - AuditSearchData retrieveSearchTemplate(); + AuditSearchData retrieveSearchTemplate(String useType); Collection retrieveAllEntriesToBeChecked(); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/audit/service/AuditReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/AuditReadPlatformServiceImpl.java similarity index 90% rename from mifosng-provider/src/main/java/org/mifosplatform/audit/service/AuditReadPlatformServiceImpl.java rename to mifosng-provider/src/main/java/org/mifosplatform/commands/service/AuditReadPlatformServiceImpl.java index 8745d9dd8..1a44c7a2d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/audit/service/AuditReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/AuditReadPlatformServiceImpl.java @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mifosplatform.audit.service; +package org.mifosplatform.commands.service; import java.sql.ResultSet; import java.sql.SQLException; @@ -12,10 +12,11 @@ import java.util.List; import org.apache.commons.lang.StringUtils; import org.joda.time.DateTime; -import org.mifosplatform.audit.api.ProcessingResultLookup; -import org.mifosplatform.audit.data.AuditData; -import org.mifosplatform.audit.data.AuditSearchData; +import org.mifosplatform.commands.data.AuditData; +import org.mifosplatform.commands.data.AuditSearchData; +import org.mifosplatform.commands.data.ProcessingResultLookup; import org.mifosplatform.infrastructure.core.domain.JdbcSupport; +import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.useradministration.data.AppUserData; @@ -141,7 +142,12 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService { } @Override - public AuditSearchData retrieveSearchTemplate() { + public AuditSearchData retrieveSearchTemplate(String useType) { + + if (!(useType.equals("audit") || useType.equals("makerchecker"))) { + throw new PlatformDataIntegrityException("error.msg.invalid.auditSearchTemplate.useType", + "Invalid Audit Search Template UseType: " + useType); } + final Collection appUsers = appUserReadPlatformService .retrieveSearchTemplate(); @@ -153,10 +159,12 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService { List entityNames = this.jdbcTemplate.query(mapper2.schema(), mapper2, new Object[] {}); - ProcessingResultsMapper mapper3 = new ProcessingResultsMapper(); - Collection processingResults = this.jdbcTemplate - .query(mapper3.schema(), mapper3, new Object[] {}); - + Collection processingResults = null; + if (useType.equals("audit")) { + ProcessingResultsMapper mapper3 = new ProcessingResultsMapper(); + processingResults = this.jdbcTemplate.query(mapper3.schema(), mapper3, new Object[] {}); + } + return new AuditSearchData(appUsers, actionNames, entityNames, processingResults); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoanChargesApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoanChargesApiResource.java index ee4fb02a9..a0734d319 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoanChargesApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoanChargesApiResource.java @@ -77,6 +77,19 @@ public class LoanChargesApiResource { return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue); } + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveAllLoanCharges(@PathParam("loanId") final Long loanId, @Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + + final Collection loanCharges = this.loanChargeReadPlatformService.retrieveLoanCharges(loanId); + + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, loanCharges, RESPONSE_DATA_PARAMETERS); + } + @GET @Path("template") @Consumes({ MediaType.APPLICATION_JSON }) @@ -94,10 +107,10 @@ public class LoanChargesApiResource { } @GET - @Path("{loanChargeId}") + @Path("{chargeId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveLoanCharge(@PathParam("loanId") final Long loanId, @PathParam("loanChargeId") final Long loanChargeId, + public String retrieveLoanCharge(@PathParam("loanId") final Long loanId, @PathParam("chargeId") final Long loanChargeId, @Context final UriInfo uriInfo) { context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); @@ -121,10 +134,10 @@ public class LoanChargesApiResource { } @PUT - @Path("{loanChargeId}") + @Path("{chargeId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String updateLoanCharge(@PathParam("loanId") final Long loanId, @PathParam("loanChargeId") final Long loanChargeId, + public String updateLoanCharge(@PathParam("loanId") final Long loanId, @PathParam("chargeId") final Long loanChargeId, final String apiRequestBodyAsJson) { final CommandWrapper commandRequest = new CommandWrapperBuilder().updateLoanCharge(loanId, loanChargeId) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index dfc2fc2cb..8fb3dacc5 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -810,9 +810,12 @@ public class Loan extends AbstractPersistable { } final String clientIdParamName = "clientId"; - if (command.isChangeInLongParameterNamed(clientIdParamName, this.client.getId())) { - final Long newValue = command.longValueOfParameterNamed(clientIdParamName); - actualChanges.put(clientIdParamName, newValue); + //FIXME AA : Client is null for group loans. Group loan modifications require group validation. + if (this.client != null) { + if (command.isChangeInLongParameterNamed(clientIdParamName, this.client.getId())) { + final Long newValue = command.longValueOfParameterNamed(clientIdParamName); + actualChanges.put(clientIdParamName, newValue); + } } final String productIdParamName = "productId"; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java index d3bddd2fb..960662b63 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java @@ -36,7 +36,7 @@ public final class CalculateLoanScheduleQueryFromApiJsonHelper { /** * The parameters supported for this command. */ - final Set supportedParameters = new HashSet(Arrays.asList("id", "clientId", "groupId", "productId", "accountNo", + final Set supportedParameters = new HashSet(Arrays.asList("id", "clientId", "groupId", "calendarId", "productId", "accountNo", "externalId", "fundId", "loanOfficerId", "loanPurposeId", "transactionProcessingStrategyId", "principal", "inArrearsTolerance", "interestRatePerPeriod", "repaymentEvery", "numberOfRepayments", "loanTermFrequency", "loanTermFrequencyType", "repaymentFrequencyType", "interestRateFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType",
Field Descriptions
A description of the product offering.
currencyCode
Three letter ISO code reprsenting currency.
Three letter ISO code representing currency.
digitsAfterDecimal
Override the currency default value for digitsAfterDecimal.
Loan Charges loans/{loanId}/chargesAdd a loan chargeAdd a Loan Charge