2424import org .apache .fineract .infrastructure .core .service .DateUtils ;
2525import org .apache .fineract .infrastructure .core .service .MathUtil ;
2626import org .apache .fineract .portfolio .loanaccount .domain .Loan ;
27+ import org .apache .fineract .portfolio .loanaccount .domain .LoanOverAppliedCalculationType ;
2728import org .apache .fineract .portfolio .loanproduct .domain .LoanProduct ;
2829import org .apache .fineract .portfolio .loanaccount .exception .InvalidLoanStateTransitionException ;
2930import org .apache .fineract .portfolio .loanaccount .exception .LoanDisbursalException ;
@@ -40,26 +41,8 @@ public void compareDisbursedToApprovedOrProposedPrincipal(final Loan loan, final
4041 final BigDecimal totalCapitalizedIncomeAdjustment = MathUtil .nullToZero (loan .getSummary ().getTotalCapitalizedIncomeAdjustment ());
4142 final BigDecimal netCapitalizedIncome = totalCapitalizedIncome .subtract (totalCapitalizedIncomeAdjustment );
4243
43- // Always use the same logic for over-applied config and fallback
44- LoanProduct loanProduct = loan .getLoanProduct ();
45- BigDecimal approvedPrincipal = loan .getApprovedPrincipal ();
46- BigDecimal maxAllowed = approvedPrincipal ;
47-
48- if (loanProduct .getOverAppliedCalculationType () != null && loanProduct .getOverAppliedNumber () != null ) {
49- BigDecimal overAppliedNumber = BigDecimal .valueOf (loanProduct .getOverAppliedNumber ());
50- if ("percentage" .equalsIgnoreCase (loanProduct .getOverAppliedCalculationType ())) {
51- BigDecimal extra = approvedPrincipal .multiply (overAppliedNumber ).divide (BigDecimal .valueOf (100 ));
52- maxAllowed = approvedPrincipal .add (extra );
53- } else {
54- // ABSOLUTE (flat)
55- maxAllowed = approvedPrincipal .add (overAppliedNumber );
56- }
57- }
58-
44+ final BigDecimal maxAllowed = calculateMaxAllowedDisbursement (loan );
5945 BigDecimal total = totalDisbursed .add (netCapitalizedIncome );
60- if (maxAllowed == null ) {
61- maxAllowed = approvedPrincipal ;
62- }
6346 if (total .compareTo (maxAllowed ) > 0 ) {
6447 throw new LoanDisbursalException (
6548 "Disbursement exceeds allowed limit including over-applied threshold" ,
@@ -68,25 +51,8 @@ public void compareDisbursedToApprovedOrProposedPrincipal(final Loan loan, final
6851 }
6952
7053 public void validateOverMaximumAmount (final Loan loan , final BigDecimal totalDisbursed , final BigDecimal capitalizedIncome ) {
71- LoanProduct loanProduct = loan .getLoanProduct ();
72- BigDecimal approvedPrincipal = loan .getApprovedPrincipal ();
73- BigDecimal maxAllowed = approvedPrincipal ;
74-
75- if (loanProduct .getOverAppliedCalculationType () != null && loanProduct .getOverAppliedNumber () != null ) {
76- BigDecimal overAppliedNumber = BigDecimal .valueOf (loanProduct .getOverAppliedNumber ());
77- if ("percentage" .equalsIgnoreCase (loanProduct .getOverAppliedCalculationType ())) {
78- BigDecimal extra = approvedPrincipal .multiply (overAppliedNumber ).divide (BigDecimal .valueOf (100 ));
79- maxAllowed = approvedPrincipal .add (extra );
80- } else {
81- // ABSOLUTE (flat)
82- maxAllowed = approvedPrincipal .add (overAppliedNumber );
83- }
84- }
85-
54+ final BigDecimal maxAllowed = calculateMaxAllowedDisbursement (loan );
8655 BigDecimal total = totalDisbursed .add (capitalizedIncome );
87- if (maxAllowed == null ) {
88- maxAllowed = approvedPrincipal ;
89- }
9056 if (total .compareTo (maxAllowed ) > 0 ) {
9157 final String errorMessage = String .format (
9258 "Disbursement exceeds allowed limit including over-applied threshold. Total disbursed amount: %s Maximum allowed: %s" ,
@@ -96,6 +62,27 @@ public void validateOverMaximumAmount(final Loan loan, final BigDecimal totalDis
9662 }
9763 }
9864
65+ private BigDecimal calculateMaxAllowedDisbursement (final Loan loan ) {
66+ final LoanProduct loanProduct = loan .getLoanProduct ();
67+ final BigDecimal approvedPrincipal = loan .getApprovedPrincipal () != null ? loan .getApprovedPrincipal () : loan .getProposedPrincipal ();
68+ BigDecimal maxAllowed = approvedPrincipal ;
69+
70+ if (loanProduct .getOverAppliedCalculationType () != null && loanProduct .getOverAppliedNumber () != null ) {
71+ final BigDecimal overAppliedMax = BigDecimal .valueOf (loanProduct .getOverAppliedNumber ());
72+ final LoanOverAppliedCalculationType calculationType = LoanOverAppliedCalculationType
73+ .valueOf (loanProduct .getOverAppliedCalculationType ().toUpperCase ());
74+
75+ if (calculationType .isPercentage ()) {
76+ final BigDecimal extra = approvedPrincipal .multiply (overAppliedMax ).divide (BigDecimal .valueOf (100 ));
77+ maxAllowed = approvedPrincipal .add (extra );
78+ } else {
79+ maxAllowed = approvedPrincipal .add (overAppliedMax );
80+ }
81+ }
82+
83+ return maxAllowed ;
84+ }
85+
9986 public void validateDisburseDate (final Loan loan , final LocalDate disbursedOn , final LocalDate expectedDate ) {
10087 if (expectedDate != null
10188 && (DateUtils .isAfter (disbursedOn , loan .fetchRepaymentScheduleInstallment (1 ).getDueDate ())
0 commit comments