mariiaKraievska commented on PR #6454:
URL: https://github.com/apache/fineract/pull/6454#issuecomment-5816248468

   > Reusing the undo core and handing the replacement to 
`processRepaymentLikeTransaction` is the right direction, and the plumbing 
(permission, handler, `CommandWrapperBuilder`, Swagger, Liquibase) follows the 
WC conventions. I know it's a draft, so read this as early feedback - but the 
way the adjust is composed causes a few problems I'd want settled first.
   > 
   > **1. The loan history is replayed twice.** 
`adjustRepaymentLikeTransaction` runs the full undo 
(`reverseRepaymentLikeTransactionCore`: reprocess, breach/delinquency undo, 
reversal journal entries, `determineAndTransition`, 
`recalculateOverpaidOnDate`) and then the whole repayment flow again for the 
replacement, including a second reprocess when it's backdated with charges, 
overpayment or charge-off. Every later transaction whose allocation changes 
gets restated twice (including the charge-off restatement and 
`restateFinalDiscountFeeAmortization`), leaving reverse/re-post pairs in the 
ledger even when the net change is zero. Each pass also publishes its own bulk 
adjust event, so consumers are told about an intermediate "loan without X" 
state that never existed. A loan closed or overpaid by X goes closed -> ACTIVE 
-> closed inside one command, running 
`triggerInlineAmortizationIfLoanClosed`/`accrueOnClosure` twice. That's exactly 
the shape that burned us in #6281 and #6399. Term l
 oans do it once: mark X reversed with its reversal entries, create X', 
reprocess once from `min(X.date, X'.date)`, transition status once, one adjust 
event.
   > 
   > **2. The risky paths have no tests.** All six e2e scenarios use one 
accounting product with discount 0, keep the original date, on an ACTIVE loan 
with no charge-off. Missing: a changed `transactionDate` (either direction), 
adjusting the payment that closed or overpaid the loan (status round trip, 
`overpaidOnDate`, closure amortization and accrual), a charged-off loan, a 
product with a discount, a loan with a CBR, and negative cases (already 
reversed, unsupported type, charge adjustment above the available amount, bad 
status). No unit tests for `adjustRepaymentLikeTransaction` / 
`validateAdjustTransaction` / `validateChargeAdjustmentAmountForAdjust` either.
   > 
   > **3. External id contract differs from term loans.** The original external 
id is moved from the reversed transaction to the replacement and the request 
has no `externalId` parameter. Term loans take the new transaction's 
`externalId` from the command and leave the reversed one alone. The reversed 
transaction in the adjust event now has no external id, so consumers can't 
match it to what they hold, and `.../external-id/{origId}` resolves to a 
different row. Either accept `externalId` and keep the original on the reversed 
one, or document the move.
   > 
   > **4. Charge adjustment skips checks.** 
`validateChargeAdjustmentAmountForAdjust` re-implements 
`chargeAdjustmentEntranceValidation`/`calculateAvailableAmountForChargeAdjustment`
 from the charge service but leaves out `wcCharge.isActive()` and 
`checkClientActive`, and the replacement takes any past date down to 
disbursement (a normal charge adjustment is always the business date), so it 
can end up dated before the charge existed. Let's reuse the existing validation 
(expose it with an exclude-transaction parameter) and decide the date rule.
   > 
   > **5. The replacement loses the original's payment details** when 
`paymentDetails` is omitted (top-level `paymentTypeId` isn't supported), and 
gets a new id/`createdDate`, so it sorts after other same-date transactions 
entered later, which can change allocation with active charges. Copy the 
original's `PaymentDetail` when none is given, and document the ordering.
   > 
   > Minor: the shared request schema now lists adjust-only fields for undo, 
`transactionDate` is required even for a zero-amount adjust, and the step def 
stores its result under `LOAN_REPAYMENT_UNDO_RESPONSE`. The CI failures look 
like infra (docker registry download, an untouched avro checkstyle), but need a 
re-run.
   > 
   > Recommendation: CHANGES_REQUESTED
   
   Thanks for the feedback, addressed as follows:
   
   1. Double replay — Fixed: mark reverse + create replacement → single 
reprocess → one status transition / one adjust event.
   
   2. Risky-path tests — Deferring to QA.
   
   3. External id — Aligned with term loans.
   
   4. Charge adjustment — Fixed: reuse shared entrance validation + replacement 
date must not be before charge due date.
   
   5. Payment details — Fixed: omit → copy into a new `PaymentDetail` row.
   
   Minor — `transactionDate` optional for amount 0, schema/step-def cleaned up.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to