Adam Saghy created FINERACT-2937:
------------------------------------
Summary: Keep a loan-level copy of the external asset owner loan
product attributes, taken when the loan is sold
Key: FINERACT-2937
URL: https://issues.apache.org/jira/browse/FINERACT-2937
Project: Apache Fineract
Issue Type: Improvement
Components: Investor
Affects Versions: 1.15.0
Reporter: Adam Saghy
Assignee: Adam Saghy
*Background*
The external asset owner behaviour of a loan is set by its loan product
attributes: EXCLUDED_TRANSACTION_TYPES, BUY_DOWN_FEE_AMORTIZATION_STRATEGY,
CAPITALIZED_INCOME_AMORTIZATION_STRATEGY and SETTLEMENT_MODEL. Today these are
read live from the loan product every time they are needed. So if someone
changes an attribute on the product, every loan already sold under the old
configuration changes its behaviour from that moment on.
This breaks consistency on loans that have already been sold. For example:
* A buy down fee is tagged to the investor before EXCLUDED_TRANSACTION_TYPES
is changed. Its later amortization, adjustment or reversal entries are then
left untagged.
* The investor's trial balance ends up holding a deferred income liability
that is never released, and the originator's books carry the opposite side.
* The same kind of split happens when an amortization strategy is changed on a
loan that is already owned.
*Goal*
The configuration in force when a loan is first sold stays with that loan for
the rest of its life, whatever later happens to the product.
*Scope*
# *Copy at sale (create if it doesn't exist)*
** When a sale is executed and the loan has no loan-level copy yet, copy all
of the product's external asset owner attributes (keys and values) to the loan.
This happens just before the sale's journal entries are posted.
** If the loan already has a copy, keep it as is. A resale to another investor
does not refresh it.
** A buyback keeps the copy. It stays on the loan and is reused if the loan is
sold again.
** Loans sold before this feature have no copy. They get one the next time
they are sold, taken from the product's attributes at that moment.
** Attributes not configured on the product when the copy is taken are not
copied, and their default behaviour applies.
# *Use the loan-level copy*
** Everything that currently reads these attributes from the product must read
the loan-level copy instead whenever one exists. This covers:
*** tagging journal entries to the owner
*** enriching events with externalOwnerId
*** the buy down fee amortization strategy
*** the capitalized income amortization strategy
*** the settlement model
** The product-level value is used only for loans that have no loan-level copy.
# *Correction API (last resort)*
** Add an endpoint to read a loan's external asset owner attributes, by loan
id and by loan external id.
** Add an endpoint to change a single loan-level attribute on a single loan.
** Changes go through the same validation and normalisation as the
product-level attributes.
** Changes need a dedicated permission, separate from the product-attribute
permissions.
** Changes run through the command pipeline so they are audited and support
maker-checker.
** Document the change endpoint as an exceptional correction tool, not part of
the normal workflow.
*Acceptance criteria*
* The first sale of a loan creates a loan-level copy of every external asset
owner attribute configured on the product at that moment.
* A resale, a buyback or a later sale does not change an existing copy.
* A loan sold before this feature gets its copy the next time it is sold, and
reads from the product until then.
* Changing or deleting a product-level attribute has no effect on the journal
entries, events or amortization of a loan that has a copy.
* Changing a loan-level attribute through the new API affects only that loan,
and only activity from that point onwards.
* A change to a loan-level attribute is audited and needs the dedicated
permission.
* Integration and E2E tests cover:
** a product change after the sale, which must not affect the loan
** a resale and a buyback, where the copy must stay unchanged
** a sale followed by a buyback and a new sale, where the original copy is
reused
** a loan-level change through the API
** a loan with no copy that is sold, which must get one
--
This message was sent by Atlassian Jira
(v8.20.10#820010)