Skip to content

Commit

Permalink
Enhance documentation for splitPrincipal function and add new test ca…
Browse files Browse the repository at this point in the history
…se for incomplete amortization schedule handling
  • Loading branch information
77it committed Jan 6, 2025
1 parent 58ed1ec commit 40b884b
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/engine/ledger/ledger.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@ class Ledger {
const _value = toBigInt(newSimObjectDto.value, this.#decimalPlaces, this.#roundingModeIsRound);
const _writingValue = _value; // writingValue is equal to value

// `splitPrincipal` is used to split a principal value in indefinite and amortization schedule values
// distributing it proportionally across the amortization schedule if needed.
const { principalIndefiniteExpiryDate, principalAmortizationSchedule } = splitPrincipal(
newSimObjectDto, {
decimalPlaces: this.#decimalPlaces,
Expand Down
11 changes: 10 additions & 1 deletion src/engine/simobject/utils/simobject_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,16 @@ function simObjectToJsonDumpDto (simObject) {
}

/**
* This function is used to split a principal value in indefinite and amortization schedule values.
* This function is used to split a principal value in indefinite and amortization schedule values
* distributing it proportionally across the amortization schedule if needed.
*
* Steps:
* 1. Convert input values to BigInt.
* 2. If the sum of the indefinite expiry date principal and the amortization schedule principal equals the total value, return values.
* 3. If the indefinite expiry date principal is zero and the amortization schedule is empty, set the indefinite expiry date principal to the total value.
* 4a. If the amortization schedule is not empty and the values do not match, calculate the residual value and distribute it proportionally across the amortization schedule.
* 4b. If the sum of the amortization schedule is not equal to the value to split, add the difference to the last value of the amortization schedule.
*
* @param {Object} p
* @param {number} p.value - principal value to split
* @param {number} p.bs_Principal__PrincipalToPay_IndefiniteExpiryDate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,28 @@ t('splitPrincipal() tests #1, split with Indefinite + Schedule', async () => {
assert.deepStrictEqual(principalAmortizationSchedule, expectedPrincipalAmortizationSchedule);
});

t('splitPrincipal() tests #1bis, split with Indefinite + Incomplete Schedule', async () => {
const value = 1000;
const bs_Principal__PrincipalToPay_IndefiniteExpiryDate = 6;
const bs_Principal__PrincipalToPay_AmortizationSchedule__Principal = [100, 100, 100];

const { principalIndefiniteExpiryDate, principalAmortizationSchedule } = splitPrincipal({
value,
bs_Principal__PrincipalToPay_IndefiniteExpiryDate,
bs_Principal__PrincipalToPay_AmortizationSchedule__Principal
}, {
decimalPlaces,
roundingModeIsRound
}
);

const expectedPrincipalIndefiniteExpiryDate = 6_0000n;
const expectedPrincipalAmortizationSchedule = [331_3333n, 331_3333n, 331_3334n];

assert.deepStrictEqual(principalIndefiniteExpiryDate, expectedPrincipalIndefiniteExpiryDate);
assert.deepStrictEqual(principalAmortizationSchedule, expectedPrincipalAmortizationSchedule);
});

t('splitPrincipal() tests #2, split with Indefinite + Schedule testing conversion to number', async () => {
const value = 999;
const bs_Principal__PrincipalToPay_IndefiniteExpiryDate = 10;
Expand Down

0 comments on commit 40b884b

Please sign in to comment.