diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index 062942278..282155441 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -1008,13 +1008,11 @@
The API concept of loans models the loan application process and the loan contract/monitoring process.
Field Descriptions |
|
| principal | +accountNo |
| The amount to be provided in the loan. | +The account no. associated with this loan. Is auto generated if not provided at loan application creation time. |
| externalId | @@ -2342,6 +2341,141 @@ DELETE groups/7 it must be unique.|
| fundId | +|
| Optional: For associating a loan with a given fund. | +|
| loanOfficerId | +|
| Optional: For associating a loan with a given staff member who is a loan officer. | +|
| loanPurposeId | +|
| Optional: For marking a loan with a given loan purpose option. Loan purposes are configurable and can be setup by system admin through code/code values screens. | +|
| currencyCode | +|
| A three letter ISO code of currency. | +|
| digitsAfterDecimal | +|
| Override the currency default value for digitsAfterDecimal. | +|
| principal | +|
| The loan amount to be disbursed to through loan. | +|
| loanTermFrequency | +|
| The length of loan term Used like: + loanTermFrequency loanTermFrequencyType e.g. 12 Months + |
+ |
| loanTermFrequencyType | +|
| The loan term period to use. Used like:
+ loanTermFrequency loanTermFrequencyType e.g. 12 Months + Example Values: 0=Days, 1=Weeks, 2=Months, 3=Years + |
+ |
| numberOfRepayments | +|
| Number of installments to repay. + Used like: numberOfRepayments Every repaymentEvery + repaymentFrequencyType e.g. 10 (repayments) Every 12 Weeks + |
+ |
| repaymentEvery | +|
| Used like: numberOfRepayments Every
+ repaymentEvery repaymentFrequencyType e.g. 10 + (repayments) Every 12 Weeks + |
+ |
| repaymentFrequencyType | +|
| Used like: numberOfRepayments Every
+ repaymentEvery repaymentFrequencyType e.g. 10 + (repayments) Every 12 Weeks + Example Values: 0=Days, 1=Weeks, 2=Months + |
+ |
| interestRatePerPeriod | +|
| Interest Rate. Used like: + interestRatePerPeriod % interestRateFrequencyType - interestType + e.g. 12.0000% Per year - Declining Balance + |
+ |
| interestRateFrequencyType | +|
| Used like: interestRatePerPeriod%
+ interestRateFrequencyType - interestType e.g. 12.0000% + Per year - Declining Balance + Example Values: 2=Per month, 3=Per year + |
+ |
| expectedDisbursementDate | +|
| The proposed disbursement date of the loan so a proposed repayment schedule can be provided. | +|
| submittedOnDate | +|
| The date the loan application was submitted by applicant. | +|
| amortizationType | +|
| Example Values: 0=Equal + principle payments, 1=Equal installments | +|
| interestType | +|
| Used like: interestRatePerPeriod%
+ interestRateFrequencyType - interestType e.g. 12.0000% + Per year - Declining Balance + Example Values: 0=Declining Balance, 1=Flat + |
+ |
| interestCalculationPeriodType | +|
| Example Values: 0=Daily, 1=Same as repayment period | +|
| inArrearsTolerance | |
| numberOfRepayments | +transactionProcessingStrategyId |
| Number of installments to repay. - Used like: numberOfRepayments Every repaymentEvery - repaymentFrequencyType e.g. 10 (repayments) - Every 12 Weeks + | The type of transaction processing strategy to be used. + At present some MFI specific ones exist. This is an important point of change for many MFIs. + Responsible for things like payment order and how early or late repayments should be processed. + Out of the box, four available: +
|
| interestRatePerPeriod | -|
| Interest Rate. Used like: - interestRatePerPeriod% interestRateFrequencyType - interestType - e.g. 12.0000% Per year - Declining Balance - |
- |
| repaymentEvery | -|
| Used like: numberOfRepayments Every
- repaymentEvery repaymentFrequencyType e.g. 10 - (repayments) Every 12 Weeks - |
- |
| Each of the items below has an id, code
- and (english) value. Only the id (integer) is used when - updating. All 3 are returned on GET (read) requests. - The options are fully listed in Retrieve - Loan Product Details Template. - |
- |
| repaymentFrequencyType | -|
| Used like: numberOfRepayments Every
- repaymentEvery repaymentFrequencyType e.g. 10 - (repayments) Every 12 Weeks - Example Values: Days, Weeks, Months - |
- |
| interestRateFrequencyType | -|
| Used like: interestRatePerPeriod%
- interestRateFrequencyType - interestType e.g. 12.0000% - Per year - Declining Balance - Example Values: Per month, Per year - |
- |
| amortizationType | -|
| Example Values: Equal - principle payments, Equal installments | -|
| interestType | -|
| Used like: interestRatePerPeriod%
- interestRateFrequencyType - interestType e.g. 12.0000% - Per year - Declining Balance - Example Values: Declining Balance, Flat - |
- |
| interestCalculationPeriodType | -|
| Example Values: Same as - repayment period, Daily | -
Example Requests:
-
@@ -2481,205 +2544,265 @@ GET https://DomainName/api/v1/loans/template?clientId=1
{
- "clientId": 1,
- "clientName": "Petra Yton",
+ "clientId": 1,
+ "clientName": "Kampala first Client",
+ "clientOfficeId": 2,
+ "timeline": {
"expectedDisbursementDate": [
- 2013,
- 2,
- 5
- ],
- "loanOfficerOptions": [
- {
- "id": 1,
- "firstname": "John",
- "lastname": "Doe",
- "displayName": "Doe, John",
- "officeId": 1,
- "officeName": "Head Office",
- "isLoanOfficer": true
- }
- ],
- "productOptions": [
- {
- "id": 1,
- "name": "A new loan product for me"
- }
- ],
- "termFrequencyTypeOptions": [
- {
- "id": 0,
- "code": "loanTermFrequency.periodFrequencyType.days",
- "value": "Days"
- },
- {
- "id": 1,
- "code": "loanTermFrequency.periodFrequencyType.weeks",
- "value": "Weeks"
- },
- {
- "id": 2,
- "code": "loanTermFrequency.periodFrequencyType.months",
- "value": "Months"
- },
- {
- "id": 3,
- "code": "loanTermFrequency.periodFrequencyType.years",
- "value": "Years"
- }
- ],
- "repaymentFrequencyTypeOptions": [
- {
- "id": 0,
- "code": "repaymentFrequency.periodFrequencyType.days",
- "value": "Days"
- },
- {
- "id": 1,
- "code": "repaymentFrequency.periodFrequencyType.weeks",
- "value": "Weeks"
- },
- {
- "id": 2,
- "code": "repaymentFrequency.periodFrequencyType.months",
- "value": "Months"
- }
- ],
- "repaymentStrategyOptions": [
- {
- "id": 1,
- "code": "mifos-standard-strategy",
- "name": "Mifos style"
- },
- {
- "id": 2,
- "code": "heavensfamily-strategy",
- "name": "Heavensfamily"
- },
- {
- "id": 3,
- "code": "creocore-strategy",
- "name": "Creocore"
- },
- {
- "id": 4,
- "code": "rbi-india-strategy",
- "name": "RBI (India)"
- }
- ],
- "interestRateFrequencyTypeOptions": [
- {
- "id": 2,
- "code": "interestRateFrequency.periodFrequencyType.months",
- "value": "Per month"
- },
- {
- "id": 3,
- "code": "interestRateFrequency.periodFrequencyType.years",
- "value": "Per year"
- }
- ],
- "amortizationTypeOptions": [
- {
- "id": 1,
- "code": "amortizationType.equal.installments",
- "value": "Equal installments"
- },
- {
- "id": 0,
- "code": "amortizationType.equal.principal",
- "value": "Equal principle payments"
- }
- ],
- "interestTypeOptions": [
- {
- "id": 1,
- "code": "interestType.flat",
- "value": "Flat"
- },
- {
- "id": 0,
- "code": "interestType.declining.balance",
- "value": "Declining Balance"
- }
- ],
- "interestCalculationPeriodTypeOptions": [
- {
- "id": 0,
- "code": "interestCalculationPeriodType.daily",
- "value": "Daily"
- },
- {
- "id": 1,
- "code": "interestCalculationPeriodType.same.as.repayment.period",
- "value": "Same as repayment period"
- }
- ],
- "fundOptions": [
- {
- "id": 1,
- "name": "EU Agri Fund"
- }
- ],
- "chargeOptions": [
- {
- "id": 1,
- "name": "Loan service fee",
- "active": true,
- "penalty": false,
- "currency": {
- "code": "USD",
- "name": "US Dollar",
- "decimalPlaces": 2,
- "displaySymbol": "$",
- "nameCode": "currency.USD",
- "displayLabel": "US Dollar ($)"
- },
- "amount": 230.56,
- "chargeTimeType": {
- "id": 1,
- "code": "chargeTimeType.disbursement",
- "value": "Disbursement"
- },
- "chargeAppliesTo": {
- "id": 1,
- "code": "chargeAppliesTo.loan",
- "value": "Loan"
- },
- "chargeCalculationType": {
- "id": 1,
- "code": "chargeCalculationType.flat",
- "value": "Flat"
- }
- }
- ],
- "chargeTemplate": {
- "active": false,
- "penalty": false,
- "chargeCalculationTypeOptions": [
- {
- "id": 1,
- "code": "chargeCalculationType.flat",
- "value": "Flat"
- },
- {
- "id": 2,
- "code": "chargeCalculationType.percent.of.amount",
- "value": "% Amount"
- }
- ],
- "chargeTimeTypeOptions": [
- {
- "id": 1,
- "code": "chargeTimeType.disbursement",
- "value": "Disbursement"
- },
- {
- "id": 2,
- "code": "chargeTimeType.specifiedDueDate",
- "value": "Specified due date"
- }
- ]
+ 2013,
+ 3,
+ 8
+ ]
+ },
+ "productOptions": [
+ {
+ "id": 1,
+ "name": "Kampala Product (with cash accounting)"
}
+ ]
+}
+
+
+GET https://DomainName/api/v1/loans/template?clientId=1&productId=1
+
+
+{
+ "clientId": 1,
+ "clientName": "Kampala first Client",
+ "clientOfficeId": 2,
+ "loanProductId": 1,
+ "loanProductName": "Kampala Product (with cash accounting)",
+ "loanProductDescription": "Typical Kampala loan product with cash accounting enabled for testing.",
+ "currency": {
+ "code": "UGX",
+ "name": "Uganda Shilling",
+ "decimalPlaces": 2,
+ "displaySymbol": "USh",
+ "nameCode": "currency.UGX",
+ "displayLabel": "Uganda Shilling (USh)"
+ },
+ "principal": 1000000,
+ "termFrequency": 12,
+ "termPeriodFrequencyType": {
+ "id": 2,
+ "code": "repaymentFrequency.periodFrequencyType.months",
+ "value": "Months"
+ },
+ "numberOfRepayments": 12,
+ "repaymentEvery": 1,
+ "repaymentFrequencyType": {
+ "id": 2,
+ "code": "repaymentFrequency.periodFrequencyType.months",
+ "value": "Months"
+ },
+ "interestRatePerPeriod": 24,
+ "interestRateFrequencyType": {
+ "id": 3,
+ "code": "interestRateFrequency.periodFrequencyType.years",
+ "value": "Per year"
+ },
+ "annualInterestRate": 24,
+ "amortizationType": {
+ "id": 1,
+ "code": "amortizationType.equal.installments",
+ "value": "Equal installments"
+ },
+ "interestType": {
+ "id": 1,
+ "code": "interestType.flat",
+ "value": "Flat"
+ },
+ "interestCalculationPeriodType": {
+ "id": 1,
+ "code": "interestCalculationPeriodType.same.as.repayment.period",
+ "value": "Same as repayment period"
+ },
+ "transactionProcessingStrategyId": 2,
+ "timeline": {
+ "expectedDisbursementDate": [
+ 2013,
+ 3,
+ 8
+ ]
+ },
+ "charges": [],
+ "productOptions": [
+ {
+ "id": 1,
+ "name": "Kampala Product (with cash accounting)"
+ }
+ ],
+ "loanOfficerOptions": [
+ {
+ "id": 2,
+ "firstname": "Kampala",
+ "lastname": "LoanOfficer",
+ "displayName": "LoanOfficer, Kampala",
+ "officeId": 2,
+ "officeName": "Uganda (Kampala)",
+ "isLoanOfficer": true
+ }
+ ],
+ "loanPurposeOptions": [
+ {
+ "id": 20,
+ "name": "option.Agriculture",
+ "position": 1
+ },
+ {
+ "id": 21,
+ "name": "option.Manufacturing",
+ "position": 20
+ },
+ {
+ "id": 22,
+ "name": "option.HousingImprovement",
+ "position": 21
+ }
+ ],
+ "termFrequencyTypeOptions": [
+ {
+ "id": 0,
+ "code": "loanTermFrequency.periodFrequencyType.days",
+ "value": "Days"
+ },
+ {
+ "id": 1,
+ "code": "loanTermFrequency.periodFrequencyType.weeks",
+ "value": "Weeks"
+ },
+ {
+ "id": 2,
+ "code": "loanTermFrequency.periodFrequencyType.months",
+ "value": "Months"
+ },
+ {
+ "id": 3,
+ "code": "loanTermFrequency.periodFrequencyType.years",
+ "value": "Years"
+ }
+ ],
+ "repaymentFrequencyTypeOptions": [
+ {
+ "id": 0,
+ "code": "repaymentFrequency.periodFrequencyType.days",
+ "value": "Days"
+ },
+ {
+ "id": 1,
+ "code": "repaymentFrequency.periodFrequencyType.weeks",
+ "value": "Weeks"
+ },
+ {
+ "id": 2,
+ "code": "repaymentFrequency.periodFrequencyType.months",
+ "value": "Months"
+ }
+ ],
+ "interestRateFrequencyTypeOptions": [
+ {
+ "id": 2,
+ "code": "interestRateFrequency.periodFrequencyType.months",
+ "value": "Per month"
+ },
+ {
+ "id": 3,
+ "code": "interestRateFrequency.periodFrequencyType.years",
+ "value": "Per year"
+ }
+ ],
+ "amortizationTypeOptions": [
+ {
+ "id": 1,
+ "code": "amortizationType.equal.installments",
+ "value": "Equal installments"
+ },
+ {
+ "id": 0,
+ "code": "amortizationType.equal.principal",
+ "value": "Equal principle payments"
+ }
+ ],
+ "interestTypeOptions": [
+ {
+ "id": 1,
+ "code": "interestType.flat",
+ "value": "Flat"
+ },
+ {
+ "id": 0,
+ "code": "interestType.declining.balance",
+ "value": "Declining Balance"
+ }
+ ],
+ "interestCalculationPeriodTypeOptions": [
+ {
+ "id": 0,
+ "code": "interestCalculationPeriodType.daily",
+ "value": "Daily"
+ },
+ {
+ "id": 1,
+ "code": "interestCalculationPeriodType.same.as.repayment.period",
+ "value": "Same as repayment period"
+ }
+ ],
+ "transactionProcessingStrategyOptions": [
+ {
+ "id": 2,
+ "code": "heavensfamily-strategy",
+ "name": "Heavensfamily"
+ }
+ ],
+ "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"
+ }
+ }
+ ],
+ "loanCollateralOptions": [
+ {
+ "id": 17,
+ "name": "option.House",
+ "position": 1
+ },
+ {
+ "id": 18,
+ "name": "option.Television",
+ "position": 17
+ },
+ {
+ "id": 19,
+ "name": "option.Gold",
+ "position": 18
+ }
+ ]
}
{
- "loanTermInDays": 366,
"currency": {
"code": "UGX",
"name": "Uganda Shilling",
@@ -2888,18 +3078,18 @@ Request Body:
"nameCode": "currency.UGX",
"displayLabel": "Uganda Shilling (USh)"
},
- "cumulativePrincipalDisbursed": 100000,
- "cumulativePrincipalDue": 100000,
- "cumulativePrincipalOutstanding": 0,
- "cumulativeInterestExpected": 13471.52,
- "cumulativeFeeChargesToDate": 0,
- "totalCostOfLoan": 13471.52,
- "totalExpectedRepayment": 113471.52,
- "totalPaidToDate": 0,
- "totalWaivedToDate": 0,
- "totalWrittenOffToDate": 0,
- "totalOutstanding": 113471.52,
- "totalInArrears": 0,
+ "loanTermInDays": 366,
+ "totalPrincipalDisbursed": 100000,
+ "totalPrincipalExpected": 100000,
+ "totalPrincipalPaid": 0,
+ "totalInterestCharged": 13471.52,
+ "totalFeeChargesCharged": 0,
+ "totalPenaltyChargesCharged": 0,
+ "totalWaived": 0,
+ "totalWrittenOff": 0,
+ "totalRepaymentExpected": 113471.52,
+ "totalRepayment": 0,
+ "totalOutstanding": 0,
"periods": [
{
"period": 0,
@@ -2948,10 +3138,19 @@ Request Body:
"totalActualCostOfLoanForPeriod": 2000
},
...
+ ...
{
"period": 12,
- "fromDate": [2012,8,20],
- "dueDate": [2012,9,20],
+ "fromDate": [
+ 2012,
+ 8,
+ 20
+ ],
+ "dueDate": [
+ 2012,
+ 9,
+ 20
+ ],
"daysInPeriod": 31,
"principalOriginalDue": 9270.56,
"principalDue": 9270.56,
@@ -2988,8 +3187,8 @@ Request Body:
loanTermFrequencyType, numberOfRepayments, repaymentEvery,
repaymentFrequencyType, interestRatePerPeriod,
interestRateFrequencyType, amortizationType, interestType,
- interestCalculationPeriodType, expectedDisbursementDate,
- submittedOnDate, transactionProcessingStrategyId
+ interestCalculationPeriodType, transactionProcessingStrategyId,
+ expectedDisbursementDate, submittedOnDate
@@ -5263,50 +5462,54 @@ Request Body:
A Loan product is a template that is used when creating a
loan. Much of the template definition can be overridden during
loan creation.
+
Field Descriptions
+
+ name
+
+
+ Name associated with loan product on system.
+
+
+ description
+
+
+ For providing helpful description of product offering.
+
+
+ fundId
+
+
+ For associating a loan product with a given fund by default.
+
+
+ currencyCode
+
+
+ A three letter ISO code of currency.
+
digitsAfterDecimal
- Override the currency default value for
- digitsAfterDecimal.
+ Override the currency default value for digitsAfterDecimal.
principal
- Loan amount.
-
-
- inArrearsTolerance
-
-
- The amount that can be 'waived' at end
- of all loan payments because it is too small to worry about.
- This is also the tolerance amount assessed when determining if a
- loan is in arrears.
-
+ The loan amount to be disbursed to through loan.
numberOfRepayments
Number of installments to repay.
- Used like: numberOfRepayments Every repaymentEvery
- repaymentFrequencyType
e.g. 10 (repayments)
- Every 12 Weeks
-
-
-
- interestRatePerPeriod
-
-
- Interest Rate.
Used like:
- interestRatePerPeriod% interestRateFrequencyType - interestType
- e.g. 12.0000% Per year - Declining Balance
+ Used like: numberOfRepayments Every repaymentEvery
+ repaymentFrequencyType
e.g. 10 (repayments) Every 12 Weeks
@@ -5314,26 +5517,27 @@ Request Body:
Used like: numberOfRepayments Every
- repaymentEvery repaymentFrequencyType
e.g. 10
+ repaymentEvery repaymentFrequencyType
e.g. 10
(repayments) Every 12 Weeks
-
- Each of the items below has an id, code
- and (english) value.
Only the id (integer) is used when
- updating. All 3 are returned on GET (read) requests.
- The options are fully listed in Retrieve
- Loan Product Details Template.
-
-
repaymentFrequencyType
- Used like: numberOfRepayments Every
- repaymentEvery repaymentFrequencyType
e.g. 10
+ Used like: numberOfRepayments Every
+ repaymentEvery repaymentFrequencyType
e.g. 10
(repayments) Every 12 Weeks
- Example Values: 0=Days, 1=Weeks, 2=Months
+ Example Values: 0=Days, 1=Weeks, 2=Months
+
+
+
+ interestRatePerPeriod
+
+
+ Interest Rate.
Used like:
+ interestRatePerPeriod % interestRateFrequencyType - interestType
+ e.g. 12.0000% Per year - Declining Balance
@@ -5353,8 +5557,6 @@ Request Body:
Example Values: 0=Equal
principle payments, 1=Equal installments
-
-
interestType
@@ -5365,17 +5567,37 @@ Request Body:
Example Values: 0=Declining Balance, 1=Flat
-
-
interestCalculationPeriodType
- Example Values: 0=Daily,
- 1=Same as repayment period
+ Example Values: 0=Daily, 1=Same as repayment period
-
+
+ inArrearsTolerance
+
+ The amount that can be 'waived' at end
+ of all loan payments because it is too small to worry about.
+ This is also the tolerance amount assessed when determining if a
+ loan is in arrears.
+
+
+
+ transactionProcessingStrategyId
+
+
+ The type of transaction processing strategy to be used.
+ At present some MFI specific ones exist. This is an important point of change for many MFIs.
+
Responsible for things like payment order and how early or late repayments should be processed.
+ Out of the box, four available:
+
+ - id=1, code=mifos-standard-strategy, name=Mifos style
+ - id=2, code=heavensfamily-strategy, name=Heavensfamily
+ - id=3, code=creocore-strategy, name=Creocore
+ - id=4, code=rbi-india-strategy, name=RBI (India)
+
+
accountingRule
@@ -5985,7 +6207,7 @@ Request Body:
"interestCalculationPeriodType": 1,
"inArrearsTolerance": "0",
"transactionProcessingStrategyId": 1,
- "charges":[{"id":"1"},{"id":"1"}],
+ "charges":[{"id":"1"}],
"accountingRule": 1
}
@@ -11476,13 +11698,11 @@ Content-Type: application/json
clients/template
- Retrieve Client Details
- Template
+ Retrieve Client Details Template
- loans/template
- Retrieve Loan Details
- Template
+ loans/template?clientId={clientId}
+ Retrieve Loan Details Template
loans/{loanId}/transactions/template
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 36d4502d0..13e10f278 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
@@ -252,7 +252,7 @@ public class Loan extends AbstractPersistable {
private boolean accountNumberRequiresAutoGeneration = false;
@Transient
private LoanRepaymentScheduleTransactionProcessorFactory transactionProcessorFactory;
-
+
@Transient
private LoanLifecycleStateMachine loanLifecycleStateMachine;
@Transient
@@ -555,7 +555,7 @@ public class Loan extends AbstractPersistable {
}
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
-
+
existingTransactionIds.addAll(findExistingTransactionIds());
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
@@ -1238,8 +1238,7 @@ public class Loan extends AbstractPersistable {
final Money totalFeeChargesDueAtDisbursement = this.summary.getTotalFeeChargesDueAtDisbursement(loanCurrency());
if (totalFeeChargesDueAtDisbursement.isGreaterThanZero()) {
- LoanTransaction chargesPayment = LoanTransaction.repaymentAtDisbursement(totalFeeChargesDueAtDisbursement,
- disbursedOn);
+ LoanTransaction chargesPayment = LoanTransaction.repaymentAtDisbursement(totalFeeChargesDueAtDisbursement, disbursedOn);
Money zero = Money.zero(getCurrency());
chargesPayment.updateComponents(zero, zero, totalFeeChargesDueAtDisbursement, zero);
chargesPayment.updateLoan(this);
@@ -1324,15 +1323,15 @@ public class Loan extends AbstractPersistable {
updateLoanSummaryDerivedFields();
}
- public LoanTransaction waiveInterest(final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine,final List existingTransactionIds,
- final List existingReversedTransactionIds) {
+ public LoanTransaction waiveInterest(final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine,
+ final List existingTransactionIds, final List existingReversedTransactionIds) {
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
final Money amountToWaive = Money.of(loanCurrency(), transactionAmount);
final LoanTransaction waiveInterestTransaction = LoanTransaction.waiver(this, amountToWaive, transactionDate);
-
+
existingTransactionIds.addAll(findExistingTransactionIds());
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
@@ -1702,7 +1701,8 @@ public class Loan extends AbstractPersistable {
final Money totalOutstanding = this.summary.getTotalOutstanding(loanCurrency());
if (totalOutstanding.isGreaterThanZero() && getInArrearsTolerance().isGreaterThanOrEqualTo(totalOutstanding)) {
- final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.REPAID_IN_FULL, LoanStatus.fromInt(this.loanStatus));
+ final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.REPAID_IN_FULL,
+ LoanStatus.fromInt(this.loanStatus));
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
this.loanStatus = statusEnum.getValue();
changes.put("status", LoanEnumerations.status(this.loanStatus));
@@ -1727,7 +1727,8 @@ public class Loan extends AbstractPersistable {
updateLoanSummaryDerivedFields();
} else if (totalOutstanding.isGreaterThanZero()) {
final String errorMessage = "A loan with money outstanding cannot be closed";
- throw new InvalidLoanStateTransitionException("close", "loan.has.money.outstanding", errorMessage, totalOutstanding.toString());
+ throw new InvalidLoanStateTransitionException("close", "loan.has.money.outstanding", errorMessage,
+ totalOutstanding.toString());
}
}
@@ -1737,7 +1738,8 @@ public class Loan extends AbstractPersistable {
// TODO - KW - technically should set somewhere that this loan
// has
// 'overpaid' amount
- final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.REPAID_IN_FULL, LoanStatus.fromInt(this.loanStatus));
+ final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.REPAID_IN_FULL,
+ LoanStatus.fromInt(this.loanStatus));
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
this.loanStatus = statusEnum.getValue();
changes.put("status", LoanEnumerations.status(this.loanStatus));
@@ -1971,24 +1973,32 @@ public class Loan extends AbstractPersistable {
public void reassignLoanOfficer(final Staff newLoanOfficer, final LocalDate assignmentDate) {
final LoanOfficerAssignmentHistory latestHistoryRecord = findLatestIncompleteHistoryRecord();
- final LoanOfficerAssignmentHistory lastAssignmentRecordWithNoEndDate = findLastAssignmentHistoryRecord();
+ final LoanOfficerAssignmentHistory lastAssignmentRecordWithNoEndDate = findLastAssignmentHistoryRecord();
- //assignment date should not be less than loan submitted date
+ // assignment date should not be less than loan submitted date
if (getSubmittedOnDate().isAfter(assignmentDate)) {
- final String errorMessage = "The Loan Officer assignment date (" + assignmentDate.toString() + ") cannot be before loan submitted date (" + getSubmittedOnDate().toString() + ").";
- throw new LoanOfficerAssignmentDateException("cannot.be.before.loan.submittal.date", errorMessage, assignmentDate, getSubmittedOnDate());
+ final String errorMessage = "The Loan Officer assignment date (" + assignmentDate.toString()
+ + ") cannot be before loan submitted date (" + getSubmittedOnDate().toString() + ").";
+ throw new LoanOfficerAssignmentDateException("cannot.be.before.loan.submittal.date", errorMessage, assignmentDate,
+ getSubmittedOnDate());
- //assignment date should not be less than latest unassignment date
+ // assignment date should not be less than latest unassignment date
+ // FIXME - rather then fetching the data from the object all the
+ // time e.g
+ // getEndDate() and asking questions of it - move the operation to
+ // the object e.g. obj.isEndDateAfter(date)
} else if (lastAssignmentRecordWithNoEndDate != null && lastAssignmentRecordWithNoEndDate.getEndDate() != null
&& lastAssignmentRecordWithNoEndDate.getEndDate().isAfter(assignmentDate)) {
- final String errorMessage = "The Loan Officer assignment date (" + assignmentDate + ") cannot be before previous Loan Officer unassigned date (" + lastAssignmentRecordWithNoEndDate.getEndDate() + ").";
- throw new LoanOfficerAssignmentDateException("cannot.be.before.previous.unassignement.date", errorMessage, assignmentDate, lastAssignmentRecordWithNoEndDate.getEndDate());
+ final String errorMessage = "The Loan Officer assignment date (" + assignmentDate
+ + ") cannot be before previous Loan Officer unassigned date (" + lastAssignmentRecordWithNoEndDate.getEndDate() + ").";
+ throw new LoanOfficerAssignmentDateException("cannot.be.before.previous.unassignement.date", errorMessage, assignmentDate,
+ lastAssignmentRecordWithNoEndDate.getEndDate());
- //assignment date should not be in the future
+ // assignment date should not be in the future
} else if (DateUtils.getLocalDateOfTenant().isBefore(assignmentDate)) {
final String errorMessage = "The Loan Officer assignment date (" + assignmentDate + ") cannot be in the future.";
throw new LoanOfficerAssignmentDateException("cannot.be.a.future.date", errorMessage, assignmentDate);
- }else if (latestHistoryRecord != null && this.loanOfficer.identifiedBy(newLoanOfficer)) {
+ } else if (latestHistoryRecord != null && this.loanOfficer.identifiedBy(newLoanOfficer)) {
latestHistoryRecord.updateStartDate(assignmentDate);
} else if (latestHistoryRecord != null && latestHistoryRecord.matchesStartDateOf(assignmentDate)) {
latestHistoryRecord.updateLoanOfficer(newLoanOfficer);
@@ -2065,9 +2075,9 @@ public class Loan extends AbstractPersistable {
break;
}
- if(lastAssignmentRecordWithNoEndDate == null){
+ if (lastAssignmentRecordWithNoEndDate == null) {
lastAssignmentRecordWithNoEndDate = historyRecord;
- } else if(historyRecord.getEndDate().isAfter(lastAssignmentRecordWithNoEndDate.getEndDate())){
+ } else if (historyRecord.getEndDate().isAfter(lastAssignmentRecordWithNoEndDate.getEndDate())) {
lastAssignmentRecordWithNoEndDate = historyRecord;
}
}
@@ -2115,7 +2125,7 @@ public class Loan extends AbstractPersistable {
public Staff getLoanOfficer() {
return this.loanOfficer;
}
-
+
public LoanSummary getSummary() {
return this.summary;
}
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanOfficerAssignmentHistory.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanOfficerAssignmentHistory.java
index 83d7d0a25..5e10a4fb9 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanOfficerAssignmentHistory.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanOfficerAssignmentHistory.java
@@ -5,10 +5,7 @@
*/
package org.mifosplatform.portfolio.loanaccount.domain;
-import org.joda.time.LocalDate;
-import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
-import org.mifosplatform.organisation.staff.domain.Staff;
-import org.mifosplatform.useradministration.domain.AppUser;
+import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -17,13 +14,17 @@ import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
-import java.util.Date;
+
+import org.joda.time.LocalDate;
+import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
+import org.mifosplatform.organisation.staff.domain.Staff;
+import org.mifosplatform.useradministration.domain.AppUser;
@Entity
@Table(name = "m_loan_officer_assignment_history")
public class LoanOfficerAssignmentHistory extends AbstractAuditableCustom {
- @SuppressWarnings("unused")
+ @SuppressWarnings("unused")
@ManyToOne
@JoinColumn(name = "loan_id", nullable = false)
private Loan loan;
@@ -37,7 +38,7 @@ public class LoanOfficerAssignmentHistory extends AbstractAuditableCustom