feat: update TDS config, RBI reserve, current products, OSS returns, and dormancy services
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 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 - 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 Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-3) (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

This commit is contained in:
2026-09-24 18:06:29 +05:30
parent d2e13cc7b9
commit 4b9093007f
56 changed files with 8174 additions and 2749 deletions
@@ -49,8 +49,10 @@ public class SavingsProductAccountingDataValidator {
.notNull().integerGreaterThanZero();
}
// A current product maps no cash GL: its deposits and withdrawals post cash to the branch cash GL
// (Financial Activity mapping), so Savings Reference is validated there only when supplied.
if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(), element)
|| ignoreExistenceValidation) {
|| (ignoreExistenceValidation && !accountType.equals(DepositAccountType.CURRENT_DEPOSIT))) {
final Long savingsReferenceAccountId = fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue())
@@ -64,8 +66,11 @@ public class SavingsProductAccountingDataValidator {
baseDataValidator.reset().parameter(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue())
.value(transfersInSuspenseAccountId).notNull().integerGreaterThanZero();
}
// A current account pays no interest, so its product has no Interest On Savings expense account:
// validated there only when actually supplied.
final boolean paysInterest = !accountType.equals(DepositAccountType.CURRENT_DEPOSIT);
if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(), element)
|| ignoreExistenceValidation) {
|| (ignoreExistenceValidation && paysInterest)) {
final Long interestOnSavingsAccountId = fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue())
@@ -20,6 +20,7 @@ package org.apache.fineract.portfolio.savings.domain;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import java.math.BigDecimal;
import lombok.Getter;
import lombok.Setter;
@@ -36,4 +37,19 @@ public class CurrentOnlyEditFields {
@Column(name = "od_account_closed_zero_balance_in_day_closing")
private Boolean odAccountClosedZeroBalanceInDayClosing;
@Column(name = "od_min_limit")
private BigDecimal odMinLimit;
@Column(name = "od_security_type")
private String odSecurityType;
@Column(name = "od_excess_allowed")
private Boolean odExcessAllowed;
@Column(name = "od_excess_limit_percent")
private BigDecimal odExcessLimitPercent;
@Column(name = "od_penal_rate")
private BigDecimal odPenalRate;
}
@@ -771,6 +771,26 @@ public final class ProductPendingEditFieldMapper {
f.setOdAccountClosedZeroBalanceInDayClosing(command.booleanObjectValueOfParameterNamed("odAccountClosedZeroBalanceInDayClosing"));
present.add("odAccountClosedZeroBalanceInDayClosing");
}
if (command.hasParameter("odMinLimit")) {
f.setOdMinLimit(command.bigDecimalValueOfParameterNamed("odMinLimit"));
present.add("odMinLimit");
}
if (command.hasParameter("odSecurityType")) {
f.setOdSecurityType(command.stringValueOfParameterNamed("odSecurityType"));
present.add("odSecurityType");
}
if (command.hasParameter("odExcessAllowed")) {
f.setOdExcessAllowed(command.booleanObjectValueOfParameterNamed("odExcessAllowed"));
present.add("odExcessAllowed");
}
if (command.hasParameter("odExcessLimitPercent")) {
f.setOdExcessLimitPercent(command.bigDecimalValueOfParameterNamed("odExcessLimitPercent"));
present.add("odExcessLimitPercent");
}
if (command.hasParameter("odPenalRate")) {
f.setOdPenalRate(command.bigDecimalValueOfParameterNamed("odPenalRate"));
present.add("odPenalRate");
}
return present;
}
@@ -781,6 +801,11 @@ public final class ProductPendingEditFieldMapper {
putString(root, submitted, "avgBalanceCalcPeriod", f.getAvgBalanceCalcPeriod());
putString(root, submitted, "validForPeriod", f.getValidForPeriod());
putBoolean(root, submitted, "odAccountClosedZeroBalanceInDayClosing", f.getOdAccountClosedZeroBalanceInDayClosing());
putNumber(root, submitted, "odMinLimit", f.getOdMinLimit());
putString(root, submitted, "odSecurityType", f.getOdSecurityType());
putBoolean(root, submitted, "odExcessAllowed", f.getOdExcessAllowed());
putNumber(root, submitted, "odExcessLimitPercent", f.getOdExcessLimitPercent());
putNumber(root, submitted, "odPenalRate", f.getOdPenalRate());
}
public static Set<String> populateShareOnlyFields(final JsonCommand command, final ShareOnlyEditFields f) {
@@ -55,4 +55,5 @@
<include file="parts/2031_add_savings_account_edit_approval_permissions.xml" relativeToChangelogFile="true" />
<include file="parts/2032_add_share_account_id_to_savings_account.xml" relativeToChangelogFile="true" />
<include file="parts/2032_remove_withdrawal_facility.xml" relativeToChangelogFile="true" />
<include file="parts/2033_add_current_product_od_scheme_pending_columns.xml" relativeToChangelogFile="true" />
</databaseChangeLog>
@@ -0,0 +1,58 @@
<?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.
-->
<!--
A current product edit waits in m_savings_product_temp as typed columns until a checker approves
it, then is replayed field by field. The OD scheme's two new fields (0577 on m_current_product)
need their own columns here too, or an approved edit silently drops them.
-->
<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 author="fineract" id="2033-1">
<preConditions onFail="MARK_RAN">
<and>
<tableExists tableName="m_savings_product_temp" />
<not>
<columnExists tableName="m_savings_product_temp" columnName="od_min_limit" />
</not>
</and>
</preConditions>
<addColumn tableName="m_savings_product_temp">
<column name="od_min_limit" type="DECIMAL(19,6)" />
<column name="od_security_type" type="VARCHAR(20)" />
</addColumn>
</changeSet>
<changeSet author="fineract" id="2033-2">
<preConditions onFail="MARK_RAN">
<and>
<tableExists tableName="m_savings_product_temp" />
<not>
<columnExists tableName="m_savings_product_temp" columnName="od_excess_allowed" />
</not>
</and>
</preConditions>
<addColumn tableName="m_savings_product_temp">
<column name="od_excess_allowed" type="BOOLEAN" />
<column name="od_excess_limit_percent" type="DECIMAL(19,6)" />
<column name="od_penal_rate" type="DECIMAL(19,6)" />
</addColumn>
</changeSet>
</databaseChangeLog>