-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FINERACT-2065: Schedule handling for fixed length configuration #3808
FINERACT-2065: Schedule handling for fixed length configuration #3808
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please add some unit / integration tests?
f0f79ad
to
15f0e4d
Compare
@@ -58,6 +61,7 @@ public LoanScheduleModel generate(final MathContext mc, final LoanApplicationTer | |||
final ApplicationCurrency applicationCurrency = loanApplicationTerms.getApplicationCurrency(); | |||
// generate list of proposed schedule due dates | |||
LocalDate loanEndDate = getScheduledDateGenerator().getLastRepaymentDate(loanApplicationTerms, holidayDetailDTO); | |||
log.info("loanEndDate {}", loanEndDate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this info logger...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, Removed!
@@ -102,6 +106,19 @@ public LoanScheduleModel generate(final MathContext mc, final LoanApplicationTer | |||
// Loan Schedule Exceptions that need to be applied for Loan Account | |||
LoanTermVariationParams termVariationParams = applyLoanTermVariations(loanApplicationTerms, scheduleParams, scheduledDueDate); | |||
scheduledDueDate = termVariationParams.scheduledDueDate(); | |||
log.info("scheduledDueDate {}", scheduledDueDate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this info logger...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, Removed!
|
||
isNextRepaymentAvailable = DateUtils.isBefore(scheduledDueDate, loanEndDate); | ||
} | ||
log.info("scheduledDueDate {}", scheduledDueDate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this info logger...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, Removed!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed from this method and class
|
||
// Fixed Length Validations - If the Number or Repayments requested is greater than current/last | ||
// Installment number | ||
if (loanApplicationTerms.getFixedLength() != null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be validated in the validator, not during the schedule generation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have talked about this, that validation will be keep it here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed from this method and class
log.info("scheduledDueDate {}", scheduledDueDate); | ||
|
||
// Fixed Length Validations - Ensure the last repayment date equal to Fixed Length | ||
if (loanApplicationTerms.getFixedLength() != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont fully understand this here...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have talked about this in the session
} | ||
lastRepaymentDate = adjustRepaymentDate(lastRepaymentDate, loanApplicationTerms, holidayDetailDTO).getChangedScheduleDate(); | ||
// Fixed Length validation - When the Number of Repayments is lower than Fixed Length | ||
if (maxDateForFixedLength != null && DateUtils.isAfter(maxDateForFixedLength, lastRepaymentDate)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we do it twice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have talked about this in the session
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (maxDateForFixedLength != null && DateUtils.isAfter(maxDateForFixedLength, lastRepaymentDate)) { | ||
lastRepaymentDate = maxDateForFixedLength; | ||
} | ||
log.info("lastRepaymentDate {}", lastRepaymentDate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the info logger
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, Removed!
|
||
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException; | ||
|
||
public class BadFixedLengthSetupException extends AbstractPlatformDomainRuleException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We dont need a new exception. Please use the GenericPlatformDomainRuleException
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done! removed
validateRepaymentPeriod(loanDetails, 2, LocalDate.of(2023, 12, 22), 33.0, 0.0, 33.0, 0.0, 0.0); | ||
validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2024, 1, 01), 34.0, 0.0, 34.0, 0.0, 0.0); | ||
assertEquals(loanDetails.getNumberOfRepayments(), 3); | ||
assertEquals(Utils.getDifferenceInDays(loanDetails.getTimeline().getActualDisbursementDate(), LocalDate.of(2024, 1, 01)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should test the due date of the very last installment instead of hard coding a date...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, validations updated with the due date of the last period
validateRepaymentPeriod(loanDetails, 2, LocalDate.of(2023, 12, 20), 33.0, 0.0, 33.0, 0.0, 0.0); | ||
validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 12, 27), 34.0, 0.0, 34.0, 0.0, 0.0); | ||
assertEquals(loanDetails.getNumberOfRepayments(), 3); | ||
assertEquals(Utils.getDifferenceInWeeks(loanDetails.getTimeline().getActualDisbursementDate(), LocalDate.of(2023, 12, 27)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, validations updated with the due date of the last period
}); | ||
} | ||
|
||
// UC127: Advanced payment allocation with Fixed Length for 11 months and Loan Term for 12 months (6 repayments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a test case when the fixed lenght is longer than the loan term.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TC uc128 created
loanTransactionHelper.disburseLoan(loanResponse.getLoanId(), | ||
new PostLoansLoanIdRequest().actualDisbursementDate("22 November 2023").dateFormat(DATETIME_PATTERN) | ||
.transactionAmount(BigDecimal.valueOf(100.0)).locale("en")); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add test cases where you are testing negative scenarios:
- Providing invalid fixed length parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please kindly check my comments!
b956079
to
4bd1621
Compare
boolean isFirstRepayment = true; | ||
for (int repaymentPeriod = 1; repaymentPeriod <= numberOfRepayments; repaymentPeriod++) { | ||
lastRepaymentDate = generateNextRepaymentDate(lastRepaymentDate, loanApplicationTerms, isFirstRepayment); | ||
isFirstRepayment = false; | ||
// Fixed Length validation - When the Number of Repayments is greater than Fixed Length |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please correct these comments. This has nothing to do with the number of repayments... it checks whether the last repaymentDate is greater than the fixedLengthDate...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
break; | ||
} | ||
} | ||
// Fixed Length validation - When the Number of Repayments is lower than Fixed Length |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please correct these comments. This has nothing to do with the number of repayments... it checks whether the last repaymentDate is lower than the fixedLengthDate...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
// Fixed Length validation - When the Number of Repayments is greater than Fixed Length | ||
if (maxDateForFixedLength != null && DateUtils.isAfter(lastRepaymentDate, maxDateForFixedLength)) { | ||
lastRepaymentDate = maxDateForFixedLength; | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind moving this condition out of the cycle, it does not require do to anything there. After the cycle finished you will have the lastRepaymentDate
set, which is the due date of the last installment and after you can decide whether it needs to be changed or not:
if lastRepaymentDate
is not equal with the fixedLengthDate
, override it with the fixedLengthDate
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
4bd1621
to
88e5bd8
Compare
...apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java
Show resolved
Hide resolved
lastRepaymentDate = generateNextRepaymentDate(lastRepaymentDate, loanApplicationTerms, isFirstRepayment); | ||
isFirstRepayment = false; | ||
LocalDate lastRepaymentDate = loanApplicationTerms.getRepaymentStartDate(); | ||
// When exists defined a Fixed Length value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We dont really need this..
Please revert and just adjust the lastRepaymentDate after it got calculated (the after the for cycle) in the following manner:
if the lastRepaymentDate
is not equals with calculatedMaxDateForFixedLenght
than override the lastRepaymentDate
with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done! updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kindly check my review and please add the requested negative test scenarios!
88e5bd8
to
c0b758f
Compare
The last change was already done and the negative case is the uc128 |
.numberOfRepayments(6).repaymentEvery(1).repaymentFrequencyType(repaymentFrequencyType.longValue()).fixedLength(6); | ||
PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(product); | ||
|
||
loanTransactionHelper.applyLoanWithError(new PostLoansRequest().clientId(client.getClientId()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should check whether the provided exception and message is correct or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see my comments and kindly fix the conflicts!
ec1cf2a
to
c2894da
Compare
@alberto-art3ch Please fix the code format error! |
c2894da
to
b416bfc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
b416bfc
to
a38273b
Compare
interestRatePerPeriod); | ||
} | ||
|
||
if (fixedLength != null && numberOfRepayments.compareTo(fixedLength) > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is incorrect...
Example which should work:
- number of repayments: 3
- Repay every: 15 DAYS
- Loan term: 45 DAYS
- Fixed term length: 40 days
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a38273b
to
23627a4
Compare
23627a4
to
160c5a2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Description
Following with the Loan Product
Fixed Length
configuration we need to consider the schedule generation with this new setting.We will get this with the next considerations:
BadFixedLengthException
FINERACT-2065.
Fixed_Length_Loan_Account.mov
Checklist
Please make sure these boxes are checked before submitting your pull request - thanks!
Write the commit message as per https://github.com/apache/fineract/#pull-requests
Acknowledge that we will not review PRs that are not passing the build ("green") - it is your responsibility to get a proposed PR to pass the build, not primarily the project's maintainers.
Create/update unit or integration tests for verifying the changes made.
Follow coding conventions at https://cwiki.apache.org/confluence/display/FINERACT/Coding+Conventions.
Add required Swagger annotation and update API documentation at fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm with details of any API changes
Submission is not a "code dump". (Large changes can be made "in repository" via a branch. Ask on the developer mailing list for guidance, if required.)
FYI our guidelines for code reviews are at https://cwiki.apache.org/confluence/display/FINERACT/Code+Review+Guide.