fix(savings-product): move savings interest paid to expenses mapping

This commit is contained in:
2026-10-01 14:01:24 +05:30
parent 4dee1db360
commit 1ffac4b1e5
2 changed files with 28 additions and 24 deletions
@@ -88,7 +88,7 @@ export class SavingProductAccountingStepComponent implements OnInit {
liabilityAccountOptions: GLAccount[] = [];
expenseAccountOptions: GLAccount[] = [];
incomeAccountOptions: GLAccount[] = [];
/** Savings Interest Paid nets to nil each posting, so it may be a liability clearing GL or an expense GL. */
/** Savings Interest Paid sits under Expenses and offers expense GLs; it nets to nil at each posting. */
paidAccountOptions: GLAccount[] = [];
assetAccountOptions: GLAccount[] = [];
paymentTypeOptions: any[] = [];
@@ -116,7 +116,7 @@ export class SavingProductAccountingStepComponent implements OnInit {
this.liabilityAccountOptions = accountingMappingOptions.liabilityAccountOptions || [];
this.expenseAccountOptions = accountingMappingOptions.expenseAccountOptions || [];
this.incomeAccountOptions = accountingMappingOptions.incomeAccountOptions || [];
this.paidAccountOptions = this.liabilityAccountOptions.concat(this.expenseAccountOptions);
this.paidAccountOptions = this.expenseAccountOptions;
this.paymentTypeOptions = this.savingProductsTemplate?.paymentTypeOptions || [];
this.fundSourceAccountOptions = this.assetAccountOptions.concat(this.liabilityAccountOptions);
this.buildAccountingSectionConfigs();
@@ -204,9 +204,9 @@ export class SavingProductAccountingStepComponent implements OnInit {
// Backend serializes as 'otherGlMappingsMap'; fall back to 'otherGlMappings' for compatibility
const glMappings = mappings.otherGlMappingsMap || mappings.otherGlMappings;
this.setOtherGlMappings('assetsOtherGlMappings', glMappings?.assets || [], this.assetAccountOptions);
// Payable and Paid are liability rows, saved under liabilities. A product saved while they sat
// under expenses still carries them there, so both buckets are read and the named entries are
// stripped out of either one's "Other" rows.
// Payable is a liability row, saved under liabilities; Paid an expense row, saved under
// expenses. Products saved before either move carry them in the other bucket, so both buckets
// are read and the named entries are stripped out of either one's "Other" rows.
const fromLiabilities = this.extractNamedGlMapping(
this.extractNamedGlMapping(
glMappings?.liabilities || [],
@@ -219,12 +219,13 @@ export class SavingProductAccountingStepComponent implements OnInit {
this.paidAccountOptions
);
this.setOtherGlMappings('liabilitiesOtherGlMappings', fromLiabilities, this.liabilityAccountOptions);
const fromExpenses = [
SAVINGS_INTEREST_PAYABLE_ACCOUNT_NAME,
SAVINGS_INTEREST_PAID_ACCOUNT_NAME
].reduce(
(remaining, name) => remaining.filter((mapping: any) => mapping?.accountName !== name),
glMappings?.expenses || []
const fromExpenses = this.extractNamedGlMapping(
(glMappings?.expenses || []).filter(
(mapping: any) => mapping?.accountName !== SAVINGS_INTEREST_PAYABLE_ACCOUNT_NAME
),
SAVINGS_INTEREST_PAID_ACCOUNT_NAME,
'savingsInterestPaidAccountId',
this.paidAccountOptions
);
this.setOtherGlMappings('expensesOtherGlMappings', fromExpenses, this.expenseAccountOptions);
this.setOtherGlMappings('incomeOtherGlMappings', glMappings?.income || [], this.incomeAccountOptions);
@@ -340,14 +341,18 @@ export class SavingProductAccountingStepComponent implements OnInit {
SAVINGS_INTEREST_PAYABLE_ACCOUNT_NAME,
this.liabilityAccountOptions
),
...mapOtherGlMappings('liabilitiesOtherGlMappings', this.liabilityAccountOptions)
],
// The backend finds Savings Interest Paid by name in any bucket; it sits under expenses
// because that is where the screen shows it.
expenses: [
...namedAsOtherGlMapping(
'savingsInterestPaidAccountId',
SAVINGS_INTEREST_PAID_ACCOUNT_NAME,
this.paidAccountOptions
),
...mapOtherGlMappings('liabilitiesOtherGlMappings', this.liabilityAccountOptions)
...mapOtherGlMappings('expensesOtherGlMappings', this.expenseAccountOptions)
],
expenses: mapOtherGlMappings('expensesOtherGlMappings', this.expenseAccountOptions),
income: mapOtherGlMappings('incomeOtherGlMappings', this.incomeAccountOptions)
};
@@ -537,16 +542,6 @@ export class SavingProductAccountingStepComponent implements OnInit {
options: this.liabilityAccountOptions,
required: true
},
{
// A pass-through between the payable and the members that closes each posting at nil, so a
// liability clearing GL and an expense GL both work; both kinds are offered.
key: 'savingsInterestPaidAccountId',
label: 'Savings Interest Paid',
inputLabel: 'Savings interest paid',
controlName: 'savingsInterestPaidAccountId',
options: this.paidAccountOptions,
required: true
},
{
key: 'interestPayableAccountId',
label: 'Interest Payable Account',
@@ -582,6 +577,15 @@ export class SavingProductAccountingStepComponent implements OnInit {
options: this.expenseAccountOptions,
required: true
},
{
// A pass-through between the payable and the members that closes each posting at nil.
key: 'savingsInterestPaidAccountId',
label: 'Savings Interest Paid',
inputLabel: 'Savings interest paid',
controlName: 'savingsInterestPaidAccountId',
options: this.paidAccountOptions,
required: true
},
{
// Cash has no paise, so a closing balance of 9,883.79 is handed over as 9,883 and the
// 79 paise land here rather than on the member's own ledger.
+1 -1
View File
@@ -10,7 +10,7 @@
export default {
'mifos_x': {
'version': '261001',
'hash': '4f02f24a'
'hash': 'b6994c0b'
},
'allow_switching_backend_instance': true
};