feat: senior citizen interest rate fix for FD/RD accounts + CBS table renames
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-1) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, build-core) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, cucumber) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (progressive-loan, build-progressive-loan) (push) Canceled after 0s
Fineract Docker Builds / build (false, docker-compose-postgresql.yml, postgresql) (push) Canceled after 0s
Fineract Docker Builds / build (true, docker-compose.yml, mariadb) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-2) (push) Canceled after 0s
Fineract Documentation build / build (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 1 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 10 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 2 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 3 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 4 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 5 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 6 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 7 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 8 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 9 of 10) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-5) (push) Canceled after 0s
Fineract Liquibase Only mode - PostgreSQL / test (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with ActiveMQ (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with Kafka (push) Canceled after 0s

- Apply senior citizen rate override in FixedDepositAccount and RecurringDepositAccount
  getEffectiveInterestRateAsFraction() so maturity is calculated at correct rate (e.g. 7.5%)
  instead of chart slab rate on every event: submit, activate, posting, pre-closure, maturity
- Override getEffectiveInterestRateAsFractionAccrual() in both FD/RD to keep accrual
  consistent with maturity calculation — independent of DB nominalAnnualInterestRate value
- Add isSeniorCitizen and seniorCitizenInterestRate fields to SavingsAccount entity with
  JPA mapping and accessor methods; updateNominalAnnualInterestRate() helper added
- Extend DepositsApiConstants whitelist and SavingsAccountAssembler.applyCbsFields()
  to read and persist senior citizen fields from API request as final override step
- Add DepositAccountAssembler early-stage rate override for senior citizen accounts
- Liquibase migration 2015: add is_senior_citizen and senior_citizen_interest_rate columns
  to m_savings_account table
- Liquibase migration 0300: rename fd_base_interest_rate tables to CBS naming convention
- Update CBS copyright header in FdBaseInterestRateEffective and FdBaseInterestRateSlabHistory

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jaanu423
2026-05-21 20:57:17 +05:30
co-authored by Claude Sonnet 4.6
parent 9f627bde61
commit ea2dfd789d
12 changed files with 3820 additions and 3665 deletions
@@ -3969,6 +3969,12 @@ public class SavingsAccount extends AbstractAuditableWithUTCDateTimeCustom<Long>
@Column(name = "auto_debit_facility", nullable = false, columnDefinition = "boolean default false")
private Boolean autoDebitFacility = false;
@Column(name = "is_senior_citizen", nullable = false, columnDefinition = "boolean default false")
private boolean isSeniorCitizen = false;
@Column(name = "senior_citizen_interest_rate", scale = 6, precision = 19, nullable = true)
private BigDecimal seniorCitizenInterestRate;
@jakarta.persistence.OneToOne(cascade = jakarta.persistence.CascadeType.ALL, mappedBy = "savingsAccount", orphanRemoval = true, fetch = FetchType.LAZY)
private SavingsAccountFacilityConfig facilityConfig;
@@ -4041,4 +4047,16 @@ public class SavingsAccount extends AbstractAuditableWithUTCDateTimeCustom<Long>
public Boolean getAutoDebitFacility() { return autoDebitFacility; }
public void setAutoDebitFacility(Boolean v) { this.autoDebitFacility = v; }
public boolean isSeniorCitizen() { return isSeniorCitizen; }
public void setSeniorCitizen(boolean v) { this.isSeniorCitizen = v; }
public BigDecimal getSeniorCitizenInterestRate() { return seniorCitizenInterestRate; }
public void setSeniorCitizenInterestRate(BigDecimal v) { this.seniorCitizenInterestRate = v; }
public void updateNominalAnnualInterestRate(BigDecimal rate) {
if (rate != null && rate.compareTo(BigDecimal.ZERO) > 0) {
this.nominalAnnualInterestRate = rate;
}
}
}
@@ -1,40 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
<!-- Sequence is starting from 2000 to make it easier to move existing liquibase changesets here -->
<include file="parts/2001_add_savings_accrual_job.xml" relativeToChangelogFile="true" />
<include file="parts/2002_add_savings_accrual_permission.xml" relativeToChangelogFile="true" />
<include file="parts/2003_add_accrued_till_date_to_savings_account.xml" relativeToChangelogFile="true" />
<include file="parts/2004_add_savings_account_cob_infrastructure.xml" relativeToChangelogFile="true" />
<include file="parts/2005_add_savings_product_classification_code_values.xml" relativeToChangelogFile="true" />
<include file="parts/2006_add_period_frequency_options.xml" relativeToChangelogFile="true" />
<include file="parts/2007_add_interest_calculation_type_option.xml" relativeToChangelogFile="true" />
<include file="parts/2008_add_other_gl_mappings_to_savings_product.xml" relativeToChangelogFile="true" />
<include file="parts/2009_add_gl_account_id_to_savings_product.xml" relativeToChangelogFile="true" />
<include file="parts/2010_add_savings_account_cbs_fields.xml" relativeToChangelogFile="true" />
<include file="parts/2011_add_facility_charge_mapping.xml" relativeToChangelogFile="true" />
<include file="parts/2012_add_current_account_permissions.xml" relativeToChangelogFile="true" />
<include file="parts/2013_add_missing_current_account_columns.xml" relativeToChangelogFile="true" />
<include file="parts/2014_add_is_mandatory_to_joint_holders.xml" relativeToChangelogFile="true" />
</databaseChangeLog>
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
<!-- Sequence is starting from 2000 to make it easier to move existing liquibase changesets here -->
<include file="parts/2001_add_savings_accrual_job.xml" relativeToChangelogFile="true" />
<include file="parts/2002_add_savings_accrual_permission.xml" relativeToChangelogFile="true" />
<include file="parts/2003_add_accrued_till_date_to_savings_account.xml" relativeToChangelogFile="true" />
<include file="parts/2004_add_savings_account_cob_infrastructure.xml" relativeToChangelogFile="true" />
<include file="parts/2005_add_savings_product_classification_code_values.xml" relativeToChangelogFile="true" />
<include file="parts/2006_add_period_frequency_options.xml" relativeToChangelogFile="true" />
<include file="parts/2007_add_interest_calculation_type_option.xml" relativeToChangelogFile="true" />
<include file="parts/2008_add_other_gl_mappings_to_savings_product.xml" relativeToChangelogFile="true" />
<include file="parts/2009_add_gl_account_id_to_savings_product.xml" relativeToChangelogFile="true" />
<include file="parts/2010_add_savings_account_cbs_fields.xml" relativeToChangelogFile="true" />
<include file="parts/2011_add_facility_charge_mapping.xml" relativeToChangelogFile="true" />
<include file="parts/2012_add_current_account_permissions.xml" relativeToChangelogFile="true" />
<include file="parts/2013_add_missing_current_account_columns.xml" relativeToChangelogFile="true" />
<include file="parts/2014_add_is_mandatory_to_joint_holders.xml" relativeToChangelogFile="true" />
<include file="parts/2015_add_senior_citizen_to_savings_account.xml" relativeToChangelogFile="true" />
</databaseChangeLog>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.
-->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
<changeSet id="2015_add_senior_citizen_to_savings_account" author="CBS">
<preConditions onFail="MARK_RAN">
<tableExists tableName="m_savings_account"/>
<not><columnExists tableName="m_savings_account" columnName="is_senior_citizen"/></not>
</preConditions>
<addColumn tableName="m_savings_account">
<column name="is_senior_citizen" type="BOOLEAN" defaultValueBoolean="false">
<constraints nullable="false"/>
</column>
<column name="senior_citizen_interest_rate" type="DECIMAL(19,6)">
<constraints nullable="true"/>
</column>
</addColumn>
</changeSet>
</databaseChangeLog>