FINERACT-1289: Taxes on Loan charges#5780
FINERACT-1289: Taxes on Loan charges#5780alberto-art3ch wants to merge 1 commit intoapache:developfrom
Conversation
a073ab8 to
ee29805
Compare
|
@alberto-art3ch It seems GA check is giving error prone issue on fineract-tax:compileTestJava can you please check. While i tried to look at the ticket. Can you confirm me the tax bifurcation logic. Asking based on usecase perspective while on ticket i tried to cross-check I cannot seem to understand how tax logic should be calculated not much relevant data i can find. |
|
ee29805 to
dbe72e1
Compare
I've reviewed the compilation issue in the fineract-tax Test part and solved. Thanks. About the bifurcation logic about the Taxes in the Loan Charges is: If you have a Loan Charge with 100.00 as amount and you have a Tax of 15% in this case, the client pays the same 100.00 but internally (in the accounting) you will have three Journal Entries:
The Tax liability account is taken from Tax Component definition, and obviously it is linked to the Charge using the Tax Group We are trying to follow a similar approach that we have in the Savings, so we are creating entities to have the detail about which Taxes (if apply) are being paying on the repayment transactions Please let me know any comment or doubt |
Yes, can you tell me is there any way user can check how much tax he has paid till now. It will be better for compliance. While I also want to make sure that tax bifurcation is also documented on ticket too. |
To start, in the Loan Charge entity there is a new field that will store the Tax Amount (sum of all the different Taxes applied) of this Loan Charge. In resume the data is already there, one way to know (as other ones) is with a report, or maybe we can extend the Loan Charge api details to have that data |
Need to ask Bharat and other PMC member for this. Thanks for explaining. I just want to make sure these things are documented properly. |
Aman-Mittal
left a comment
There was a problem hiding this comment.
Code Wise seems ok, I have also checked the relevant ticket, Based on conversation it seems to implement what it implements.
adamsaghy
left a comment
There was a problem hiding this comment.
Please make sure the new functionality and the changes are covered with documentation in the fineract-doc module and under the https://issues.apache.org/jira/browse/FINERACT-1289
|
In Colombia, VAT (IVA, 19%) on insurance and similar loan charges is passed through to the customer: the customer pays With the current PR, after
This works perfectly for tax models where the bank absorbs the tax (e.g. savings withholding tax). But for pass-through tax, the customer's ProposalA // LoanChargeService.applyTaxIfConfigured
loanCharge.setTaxAmount(totalTax);
if (taxGroup.isTaxAddedToAmount()) {
}
loanCharge.setAmountOutstanding(loanCharge.calculateOutstanding());
loanCharge.getTaxDetails().clear();
taxSplit.forEach((component, taxAmt) ->
loanCharge.getTaxDetails().add(new LoanChargeTaxDetails(loanCharge, component, taxAmt)));Schema delta: <changeSet author="fineract" id="loan-charge-tax-3">
<addColumn tableName="m_tax_group">
<column name="tax_added_to_amount" type="BOOLEAN" defaultValueBoolean="false">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet> The flag is queryable via I'd be happy to open a follow-up PR with the migration, the flag, the API exposure on Independent issue, much smaller. The call is: chargeTaxApplicationService.computeTax(taxGroup, loanCharge.getAmount(), effectiveDate, 6); The ProposalUse the loan currency's scale instead, with a sensible fallback: int scale = (loanCharge.getLoan() != null && loanCharge.getLoan().getCurrency() != null)
? loanCharge.getLoan().getCurrency().getDigitsAfterDecimal()
: 2;
Map<TaxComponent, BigDecimal> taxSplit =
chargeTaxApplicationService.computeTax(taxGroup, loanCharge.getAmount(), effectiveDate, scale); This change is risk-free and aligns with how Money/MoneyHelper rounds elsewhere in the core. Could land as a small commit on this PR or as a tiny separate fix. |
@jonattanvargas-habi The enhancement you have mentioned is not part of this ticket and I believe we can handle it through different story. Could you please create a new enhancement ticket on fineract JIRA? |
@Aman-Mittal Appreciate all your questions and the detailed code review. The functionality explained by @alberto-art3ch looks correct for the inclusive tax configuration. I also believe we can further enhance the tax bifurcation space over time, and those improvements can be handled through separate stories instead of being part of this ticket. @alberto-art3ch , as mentioned by @adamsaghy , could you please document the current behavior in the fineract-doc module under FINERACT-1289? |
dbe72e1 to
f085e18
Compare
@adamsaghy / @bharathcgowda I've added the adoc file |
| for (LoanChargeTaxDetails taxDetail : lc.getTaxDetails()) { | ||
| if (taxDetail.getTaxComponent().getCreditAccount() != null) { | ||
| final BigDecimal proRatedTax = taxDetail.getAmount().multiply(paidAmount).divide(chargeAmount, 6, | ||
| RoundingMode.HALF_EVEN); |
There was a problem hiding this comment.
why to hardcode the rounding? Use the configured rounding instead!
| final List<ChargeTaxPaymentDTO> feeTaxPayments = loanCommonAccountingHelper.filterTaxPayments(loanTransactionDTO, false); | ||
| final BigDecimal feeTaxTotal = loanCommonAccountingHelper.sumTaxAmounts(feeTaxPayments); | ||
| if (feeTaxTotal.compareTo(BigDecimal.ZERO) > 0) { | ||
| final BigDecimal netFees = feesAmount.subtract(feeTaxTotal); | ||
| this.helper.createCreditJournalEntryForLoanCharges(office, currencyCode, | ||
| AccrualAccountsForLoan.INCOME_FROM_FEES.getValue(), loanProductId, loanId, transactionId, transactionDate, | ||
| netFees, | ||
| loanCommonAccountingHelper.computeNetChargePayments(loanTransactionDTO.getFeePayments(), feeTaxPayments)); | ||
| loanCommonAccountingHelper.createTaxLiabilityCreditEntries(office, currencyCode, loanId, transactionId, transactionDate, | ||
| feeTaxPayments); | ||
| } else { | ||
| this.helper.createCreditJournalEntryForLoanCharges(office, currencyCode, | ||
| AccrualAccountsForLoan.INCOME_FROM_FEES.getValue(), loanProductId, loanId, transactionId, transactionDate, | ||
| feesAmount, loanTransactionDTO.getFeePayments()); | ||
| } |
There was a problem hiding this comment.
You are recalculating tax payments over and over again...
You can SUM and fetch the appropriate tax entries for a particular charge in 1 sql query.
Would that be better than fetching all fee payment and all tax payments and group and sum them over and over again? What do you think?
There was a problem hiding this comment.
tax amount is calculated at earlier stage, why dont just use that?
| * | ||
| * Pure domain-object tests — no Spring context, no persistence. | ||
| */ | ||
| class LoanChargeTaxDetailsTest { |
There was a problem hiding this comment.
Quite useless tests... i would remove...
| // Reversal: CR Penalties Receivable (full), DR Income from Penalties (net), DR Tax Liability | ||
| this.helper.createCreditJournalEntryForLoanCharges(office, currencyCode, | ||
| AccrualAccountsForLoan.PENALTIES_RECEIVABLE.getValue(), loanProductId, loanId, transactionId, transactionDate, | ||
| penaltiesAmount, loanTransactionDTO.getPenaltyPayments()); |
There was a problem hiding this comment.
what is the difference between penaltyTaxPayments and loanTransactionDTO.getPenaltyPayments()?
| this.helper.createDebitJournalEntryForLoanCharges(office, currencyCode, | ||
| AccrualAccountsForLoan.PENALTIES_RECEIVABLE.getValue(), loanProductId, loanId, transactionId, transactionDate, | ||
| penaltiesAmount, loanTransactionDTO.getPenaltyPayments()); | ||
| this.helper.createCreditJournalEntryForLoanCharges(office, currencyCode, |
There was a problem hiding this comment.
Duplicates? Common operations can be extracted... the whole logic would be less complex!
adamsaghy
left a comment
There was a problem hiding this comment.
Kindly review my concerns...
Description
There was an issue with the Tax attached to the loan charge is not getting affected at the loan/accounting level. Tthe tax bifurcation was not happening
FINERACT-1289
Checklist
Please make sure these boxes are checked before submitting your pull request - thanks!
Your assigned reviewer(s) will follow our guidelines for code reviews.