From 1ffac4b1e513f4b9fdcca1161a6ee15bf8fd0c07 Mon Sep 17 00:00:00 2001 From: keshav Date: Thu, 1 Oct 2026 14:01:24 +0530 Subject: [PATCH] fix(savings-product): move savings interest paid to expenses mapping --- ...aving-product-accounting-step.component.ts | 50 ++++++++++--------- src/environments/.env.ts | 2 +- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/app/products/saving-products/saving-product-stepper/saving-product-accounting-step/saving-product-accounting-step.component.ts b/src/app/products/saving-products/saving-product-stepper/saving-product-accounting-step/saving-product-accounting-step.component.ts index c374eb301..a46c736b8 100644 --- a/src/app/products/saving-products/saving-product-stepper/saving-product-accounting-step/saving-product-accounting-step.component.ts +++ b/src/app/products/saving-products/saving-product-stepper/saving-product-accounting-step/saving-product-accounting-step.component.ts @@ -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. diff --git a/src/environments/.env.ts b/src/environments/.env.ts index 29388afe4..0bcf1486e 100644 --- a/src/environments/.env.ts +++ b/src/environments/.env.ts @@ -10,7 +10,7 @@ export default { 'mifos_x': { 'version': '261001', - 'hash': '4f02f24a' + 'hash': 'b6994c0b' }, 'allow_switching_backend_instance': true };