saving , current and RD account code update

This commit is contained in:
Nitesh Yadav
2026-04-23 11:20:35 +05:30
26 changed files with 43076 additions and 44411 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -216,8 +216,9 @@ public class DepositProductDataValidator {
validateRecurringDepositUpdate(element, baseDataValidator);
// RD products now use the CBS base chart as a read-only template, so
// product updates no longer require a charts payload.
if (!hasRdSlabsForUpdate) {
validateChartsData(element, baseDataValidator);
validateDepositAmountForUpdate(element, baseDataValidator);
}
@@ -140,7 +140,7 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
final Collection<EnumOptionData> withdrawalFeeTypeOptions = this.dropdownReadPlatformService.retrievewithdrawalFeeTypeOptions();
final Collection<SavingsAccountTransactionData> transactions = null;
final Collection<ChargeData> productCharges = this.chargeReadPlatformService.retrieveSavingsProductCharges(productId);
final Collection<ChargeData> productCharges = this.chargeReadPlatformService.retrieveCurrentProductCharges(productId);
final Collection<SavingsAccountChargeData> charges = fromChargesToSavingsCharges(productCharges);
final boolean feeChargesOnly = false;
@@ -170,6 +170,44 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions,
charges, chargeOptions);
// Re-apply CBS fields from full product data (withTemplateOptions creates a new object and loses setter fields)
final SavingsProductData productData = this.currentProductReadPlatformService.retrieveOne(productId);
if (productData != null) {
// Feature flags
template.setDormancyAlert(productData.getDormancyAlert() != null && productData.getDormancyAlert());
template.setBalanceSwapOption(productData.getBalanceSwapOption() != null && productData.getBalanceSwapOption());
template.setMsme(productData.getMsme() != null && productData.getMsme());
template.setNominationFacility(productData.getNominationFacility() != null && productData.getNominationFacility());
template.setAutoDebitFacility(productData.getAutoDebitFacility() != null && productData.getAutoDebitFacility());
template.setAutoPost(productData.getAutoPost() != null && productData.getAutoPost());
template.setFrequencyFixDay(productData.getFrequencyFixDay());
template.setLastInterestDate(productData.getLastInterestDate());
template.setInterestCalculateSelector(productData.getInterestCalculateSelector());
template.setAveragePeriod(productData.getAveragePeriod());
template.setAccountClosedZeroBalanceInDayClosing(
productData.getAccountClosedZeroBalanceInDayClosing() != null && productData.getAccountClosedZeroBalanceInDayClosing());
// Facility data
template.setAccountFacilityConfig(productData.getAccountFacilityConfig());
template.setAccountFacilityLimits(productData.getAccountFacilityLimits());
template.setDepositLimitKyc(productData.getDepositLimitKyc());
// Classification fields
template.setAccountType(productData.getAccountType());
template.setCustomerSegment(productData.getCustomerSegment());
template.setProductCode(productData.getProductCode());
template.setEffectiveDate(productData.getEffectiveDate());
template.setEffectiveTo(productData.getEffectiveTo());
template.setEndDate(productData.getEndDate());
template.setIntroducerRequired(productData.getIntroducerRequired());
template.setShareLinkingEnabled(productData.getShareLinkingEnabled());
// Settings fields
template.setEnableLockinPeriod(productData.getEnableLockinPeriod());
template.setBalanceFrequency(productData.getBalanceFrequency());
template.setAvgBalanceCalcPeriod(productData.getAvgBalanceCalcPeriod());
template.setValidForPeriod(productData.getValidForPeriod());
template.setOdAccountClosedZeroBalanceInDayClosing(
productData.getOdAccountClosedZeroBalanceInDayClosing() != null && productData.getOdAccountClosedZeroBalanceInDayClosing());
}
} else {
String clientName = null;
@@ -247,7 +285,22 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
sqlBuilder.append("cp.min_required_balance as minRequiredBalance, ");
sqlBuilder.append("cp.enforce_min_required_balance as enforceMinRequiredBalance, ");
sqlBuilder.append("0 as maxAllowedLienLimit, ");
sqlBuilder.append("0 as lienAllowed ");
sqlBuilder.append("0 as lienAllowed, ");
sqlBuilder.append("cp.dormancy_alert as dormancyAlert, ");
sqlBuilder.append("cp.balance_swap_option as balanceSwapOption, ");
sqlBuilder.append("cp.msme as msme, ");
sqlBuilder.append("cp.nomination_facility as nominationFacility, ");
sqlBuilder.append("cp.auto_debit_facility as autoDebitFacility, ");
sqlBuilder.append("cp.auto_post as autoPost, ");
sqlBuilder.append("cp.frequency_fix_day as frequencyFixDay, ");
sqlBuilder.append("cp.last_interest_date as lastInterestDate, ");
sqlBuilder.append("cp.interest_calculate_selector as interestCalculateSelector, ");
sqlBuilder.append("cp.average_period as averagePeriod, ");
sqlBuilder.append("cp.account_closed_zero_balance_in_day_closing as accountClosedZeroBalanceInDayClosing, ");
sqlBuilder.append("cp.is_dormancy_tracking_active as isDormancyTrackingActive, ");
sqlBuilder.append("cp.days_to_inactive as daysToInactive, ");
sqlBuilder.append("cp.days_to_dormancy as daysToDormancy, ");
sqlBuilder.append("cp.days_to_escheat as daysToEscheat ");
sqlBuilder.append("from m_current_product cp ");
sqlBuilder.append("join m_currency curr on curr.code = cp.currency_code ");
sqlBuilder.append("left join m_tax_group tg on tg.id = cp.tax_group_id ");
@@ -346,14 +399,26 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
final SavingsAccountSubStatusEnumData subStatus = null;
final String reasonForBlock = null;
final LocalDate lastActiveTransactionDate = null;
final boolean isDormancyTrackingActive = false;
final Integer daysToInactive = null;
final Integer daysToDormancy = null;
final Integer daysToEscheat = null;
final boolean isDormancyTrackingActive = rs.getBoolean("isDormancyTrackingActive");
final Integer daysToInactive = JdbcSupport.getInteger(rs, "daysToInactive");
final Integer daysToDormancy = JdbcSupport.getInteger(rs, "daysToDormancy");
final Integer daysToEscheat = JdbcSupport.getInteger(rs, "daysToEscheat");
final boolean dormancyAlert = rs.getBoolean("dormancyAlert");
final boolean balanceSwapOption = rs.getBoolean("balanceSwapOption");
final boolean msme = rs.getBoolean("msme");
final boolean nominationFacility = rs.getBoolean("nominationFacility");
final boolean autoDebitFacility = rs.getBoolean("autoDebitFacility");
final boolean autoPost = rs.getBoolean("autoPost");
final Integer frequencyFixDay = JdbcSupport.getInteger(rs, "frequencyFixDay");
final LocalDate lastInterestDate = JdbcSupport.getLocalDate(rs, "lastInterestDate");
final Integer interestCalculateSelector = JdbcSupport.getInteger(rs, "interestCalculateSelector");
final String averagePeriod = rs.getString("averagePeriod");
final boolean accountClosedZeroBalanceInDayClosing = rs.getBoolean("accountClosedZeroBalanceInDayClosing");
final SavingsAccountApplicationTimelineData timeline = SavingsAccountApplicationTimelineData.templateDefault();
final EnumOptionData depositType = null;
return SavingsAccountData.instance(null, null, depositType, null, groupId, groupName, clientId, clientName, productId,
final SavingsAccountData accountData = SavingsAccountData.instance(null, null, depositType, null, groupId, groupName, clientId, clientName, productId,
productName, fieldOfficerId, fieldOfficerName, status, subStatus, reasonForBlock, timeline, currency,
nominalAnnualIterestRate, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
@@ -361,6 +426,19 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
maxAllowedLienLimit, lienAllowed, minBalanceForInterestCalculation, onHoldFunds, nominalAnnualInterestRateOverdraft,
minOverdraftForInterestCalculation, withHoldTax, taxGroupData, lastActiveTransactionDate, isDormancyTrackingActive,
daysToInactive, daysToDormancy, daysToEscheat, savingsAmountOnHold);
accountData.setDormancyAlert(dormancyAlert);
accountData.setBalanceSwapOption(balanceSwapOption);
accountData.setMsme(msme);
accountData.setNominationFacility(nominationFacility);
accountData.setAutoDebitFacility(autoDebitFacility);
accountData.setAutoPost(autoPost);
accountData.setFrequencyFixDay(frequencyFixDay);
accountData.setLastInterestDate(lastInterestDate);
accountData.setInterestCalculateSelector(interestCalculateSelector);
accountData.setAveragePeriod(averagePeriod);
accountData.setAccountClosedZeroBalanceInDayClosing(accountClosedZeroBalanceInDayClosing);
return accountData;
}
}
@@ -382,7 +382,9 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
// retrieve chart Slabs
final InterestRateChartData productChartData = this.productChartReadPlatformService.retrieveActiveChartWithTemplate(productId);
final DepositAccountInterestRateChartData accountChart = DepositAccountInterestRateChartData.from(productChartData);
final DepositAccountInterestRateChartData accountChart = (productChartData != null)
? DepositAccountInterestRateChartData.from(productChartData)
: null;
if (depositAccountType.isFixedDeposit()) {
@@ -394,13 +396,17 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
template = FixedDepositAccountData.withInterestChart((FixedDepositAccountData) template, accountChart);
} else if (depositAccountType.isRecurringDeposit()) {
template = RecurringDepositAccountData.withTemplateOptions((RecurringDepositAccountData) template, productOptions,
// Save CBS fields from mapper result before factory methods create new objects
final RecurringDepositAccountData rdTemplateWithCbs = (RecurringDepositAccountData) template;
template = RecurringDepositAccountData.withTemplateOptions(rdTemplateWithCbs, productOptions,
fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, transactions, charges, chargeOptions, preClosurePenalInterestOnTypeOptions,
periodFrequencyTypeOptions);
template = RecurringDepositAccountData.withInterestChartAndRecurringDetails((RecurringDepositAccountData) template,
accountChart, null, null);
// Re-apply CBS product fields lost during factory method object creation
((RecurringDepositAccountData) template).copyCbsFieldsFrom(rdTemplateWithCbs);
}
@@ -1473,10 +1479,33 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
sqlBuilder.append("dptp.min_deposit_term_type_enum as minDepositTermTypeId, ");
sqlBuilder.append("dptp.max_deposit_term_type_enum as maxDepositTermTypeId, ");
sqlBuilder.append("dptp.in_multiples_of_deposit_term as inMultiplesOfDepositTerm, ");
sqlBuilder.append("dptp.in_multiples_of_deposit_term_type_enum as inMultiplesOfDepositTermTypeId ");
sqlBuilder.append("dptp.in_multiples_of_deposit_term_type_enum as inMultiplesOfDepositTermTypeId, ");
sqlBuilder.append("sa.account_type as accountType, sa.customer_segment as customerSegment, ");
sqlBuilder.append("sa.product_code as productCode, ");
sqlBuilder.append("sa.effective_date as effectiveDate, sa.effective_to as effectiveTo, sa.end_date as endDate, ");
sqlBuilder.append("sa.introducer_required as introducerRequired, sa.share_linking_enabled as shareLinkingEnabled, ");
sqlBuilder.append("sa.nomination_facility as nominationFacility, sa.dormancy_alert as dormancyAlert, ");
sqlBuilder.append("sa.interest_calculate_selector as interestCalculateSelector, ");
sqlBuilder.append("icv.code_value as interestCalculationTypeName, ");
sqlBuilder.append("sa.average_period as averagePeriod, ");
sqlBuilder.append("sa.auto_post as autoPost, sa.frequency_fix_day as frequencyFixDay, ");
sqlBuilder.append("sa.last_interest_date as lastInterestDate, sa.enable_lockin_period as enableLockinPeriod, ");
sqlBuilder.append("sa.balance_frequency as balanceFrequency, ");
sqlBuilder.append("sa.account_closed_zero_balance_in_day_closing as accountClosedZeroBalanceInDayClosing, ");
sqlBuilder.append("sa.balance_swap_option as balanceSwapOption, sa.msme as msme, ");
sqlBuilder.append("sa.auto_debit_facility as autoDebitFacility, sa.loan_facility as loanFacility, ");
sqlBuilder.append("sa.premature_withdrawal_option as prematureWithdrawalOption, sa.tenure_flexibility as tenureFlexibility, ");
sqlBuilder.append("sa.lien_marked as lienMarked, sa.maturity_instructions as maturityInstructions, ");
sqlBuilder.append("sa.credit_maturity_proceeds as creditMaturityProceeds, ");
sqlBuilder.append("sa.penalty_grace_period_missed_installments as penaltyGracePeriodMissedInstallments, ");
sqlBuilder.append("sa.panel_request_applicable as panelRequestApplicable, ");
sqlBuilder.append("sa.no_penalty_nominee_heir_closure as noPenaltyNomineeHeirClosure, ");
sqlBuilder.append("sa.deceased_settlement as deceasedSettlement, ");
sqlBuilder.append("sa.allow_debit_txn_after_due_date as allowDebitTxnAfterDueDate ");
sqlBuilder.append(this.selectTablesSql());
sqlBuilder.append("left join m_deposit_product_recurring_detail dprd on sa.id = dprd.savings_product_id ");
sqlBuilder.append("left join m_code_value icv on icv.id = sa.interest_calculate_selector ");
this.schemaSql = sqlBuilder.toString();
}
@@ -1525,12 +1554,52 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
final BigDecimal totalOverdueAmount = null;
final Integer noOfOverdueInstallments = null;
return RecurringDepositAccountData.instance(depositAccountData, preClosurePenalApplicable, preClosurePenalInterest,
final RecurringDepositAccountData result = RecurringDepositAccountData.instance(depositAccountData,
preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
depositPeriodFrequencyType, mandatoryRecommendedDepositAmount, onAccountClosureType, expectedFirstDepositOnDate,
totalOverdueAmount, noOfOverdueInstallments, isMandatoryDeposit, allowWithdrawal, adjustAdvanceTowardsFuturePayments,
isCalendarInherited);
// CBS product fields
result.setCbsProductFields(
rs.getString("accountType"),
rs.getString("customerSegment"),
rs.getString("productCode"),
JdbcSupport.getLocalDate(rs, "effectiveDate"),
JdbcSupport.getLocalDate(rs, "effectiveTo"),
JdbcSupport.getLocalDate(rs, "endDate"),
rs.getBoolean("introducerRequired"),
rs.getBoolean("shareLinkingEnabled"),
rs.getBoolean("nominationFacility"),
rs.getBoolean("dormancyAlert"),
JdbcSupport.getInteger(rs, "interestCalculateSelector"),
rs.getString("interestCalculationTypeName"),
rs.getString("averagePeriod"),
rs.getBoolean("autoPost"),
JdbcSupport.getInteger(rs, "frequencyFixDay"),
JdbcSupport.getLocalDate(rs, "lastInterestDate"),
rs.getBoolean("enableLockinPeriod"),
rs.getString("balanceFrequency"),
rs.getBoolean("accountClosedZeroBalanceInDayClosing"),
rs.getBoolean("balanceSwapOption"),
rs.getBoolean("msme"),
rs.getBoolean("autoDebitFacility"),
rs.getBoolean("loanFacility"),
rs.getBoolean("prematureWithdrawalOption"),
rs.getBoolean("tenureFlexibility"),
rs.getBoolean("lienMarked"),
rs.getBoolean("maturityInstructions"),
rs.getBoolean("creditMaturityProceeds"),
rs.getBoolean("penaltyGracePeriodMissedInstallments"),
rs.getBoolean("panelRequestApplicable"),
rs.getBoolean("noPenaltyNomineeHeirClosure"),
rs.getBoolean("deceasedSettlement"),
rs.getBoolean("allowDebitTxnAfterDueDate")
);
return result;
}
}
@@ -304,7 +304,7 @@ public class DepositProductReadPlatformServiceImpl implements DepositProductRead
sqlBuilder.append("sp.effective_date as effectiveDate, sp.effective_to as effectiveTo, sp.end_date as endDate, ");
sqlBuilder.append("sp.introducer_required as introducerRequired, sp.share_linking_enabled as shareLinkingEnabled, ");
sqlBuilder.append("sp.nomination_facility as nominationFacility, sp.dormancy_alert as dormancyAlert, ");
sqlBuilder.append("sp.interest_calculate_selector as interestCalculateSelector, ");
sqlBuilder.append("sp.interest_calculate_selector as interestCalculateSelector, icv.code_value as interestCalculationTypeName, ");
sqlBuilder.append("sp.average_period as averagePeriod, ");
sqlBuilder.append("sp.auto_post as autoPost, sp.frequency_fix_day as frequencyFixDay, ");
sqlBuilder.append("sp.last_interest_date as lastInterestDate, sp.enable_lockin_period as enableLockinPeriod, ");
@@ -325,7 +325,8 @@ public class DepositProductReadPlatformServiceImpl implements DepositProductRead
sqlBuilder.append("left join m_deposit_product_term_and_preclosure dptp on sp.id=dptp.savings_product_id ");
sqlBuilder.append("left join m_deposit_product_recurring_detail dprd on sp.id=dprd.savings_product_id ");
sqlBuilder.append("join m_currency curr on curr.code = sp.currency_code ");
sqlBuilder.append(" left join m_tax_group tg on tg.id = sp.tax_group_id ");
sqlBuilder.append(" left join m_tax_group tg on tg.id = sp.tax_group_id ");
sqlBuilder.append("left join m_code_value icv on icv.id = sp.interest_calculate_selector ");
this.schemaSql = sqlBuilder.toString();
}
@@ -414,6 +415,7 @@ public class DepositProductReadPlatformServiceImpl implements DepositProductRead
result.setNominationFacility(nominationFacility);
result.setDormancyAlert(dormancyAlert);
result.setInterestCalculateSelector(interestCalculateSelector);
result.setInterestCalculationTypeName(rs.getString("interestCalculationTypeName"));
result.setAveragePeriod(averagePeriod);
result.setAutoPost(autoPost);
result.setFrequencyFixDay(frequencyFixDay);
@@ -25,6 +25,9 @@ import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
@@ -43,6 +46,7 @@ import org.apache.fineract.portfolio.client.data.ClientData;
import org.apache.fineract.portfolio.client.service.ClientReadPlatformService;
import org.apache.fineract.portfolio.group.data.GroupGeneralData;
import org.apache.fineract.portfolio.group.service.GroupReadPlatformService;
import org.apache.fineract.portfolio.savings.SavingsApiConstants;
import org.apache.fineract.portfolio.savings.SavingsCompoundingInterestPeriodType;
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationDaysInYearType;
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationType;
@@ -62,6 +66,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.util.CollectionUtils;
@Slf4j
public class SavingsAccountTemplateReadPlatformServiceImpl implements SavingsAccountTemplateReadPlatformService {
private final PlatformSecurityContext context;
@@ -72,6 +77,7 @@ public class SavingsAccountTemplateReadPlatformServiceImpl implements SavingsAcc
private final StaffReadPlatformService staffReadPlatformService;
private final SavingsDropdownReadPlatformService dropdownReadPlatformService;
private final ChargeReadPlatformService chargeReadPlatformService;
private final CodeValueReadPlatformService codeValueReadPlatformService;
private final EntityDatatableChecksReadService entityDatatableChecksReadService;
@@ -80,7 +86,8 @@ public class SavingsAccountTemplateReadPlatformServiceImpl implements SavingsAcc
final SavingsProductReadPlatformService savingProductReadPlatformService,
final StaffReadPlatformService staffReadPlatformService, final SavingsDropdownReadPlatformService dropdownReadPlatformService,
final ChargeReadPlatformService chargeReadPlatformService,
final EntityDatatableChecksReadService entityDatatableChecksReadService, final ColumnValidator columnValidator) {
final EntityDatatableChecksReadService entityDatatableChecksReadService, final ColumnValidator columnValidator,
final CodeValueReadPlatformService codeValueReadPlatformService) {
this.context = context;
this.jdbcTemplate = jdbcTemplate;
this.clientReadPlatformService = clientReadPlatformService;
@@ -90,6 +97,7 @@ public class SavingsAccountTemplateReadPlatformServiceImpl implements SavingsAcc
this.dropdownReadPlatformService = dropdownReadPlatformService;
this.chargeReadPlatformService = chargeReadPlatformService;
this.entityDatatableChecksReadService = entityDatatableChecksReadService;
this.codeValueReadPlatformService = codeValueReadPlatformService;
}
@Override
@@ -176,6 +184,58 @@ public class SavingsAccountTemplateReadPlatformServiceImpl implements SavingsAcc
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions,
charges, chargeOptions);
// Enrich template with full CBS product data (classification, digital facilities, etc.)
try {
final SavingsProductData fullProduct = this.savingsProductReadPlatformService.retrieveOne(productId);
template.setAccountType(fullProduct.getAccountType());
template.setCustomerSegment(fullProduct.getCustomerSegment());
template.setProductCode(fullProduct.getProductCode());
template.setEffectiveDate(fullProduct.getEffectiveDate());
template.setEffectiveTo(fullProduct.getEffectiveTo());
template.setEndDate(fullProduct.getEndDate());
template.setIntroducerRequired(fullProduct.getIntroducerRequired());
template.setShareLinkingEnabled(fullProduct.getShareLinkingEnabled());
template.setNominationFacility(fullProduct.getNominationFacility());
template.setDormancyAlert(fullProduct.getDormancyAlert());
template.setInterestCalculationTypeName(fullProduct.getInterestCalculationTypeName());
template.setLastInterestDate(fullProduct.getLastInterestDate());
template.setEnableLockinPeriod(fullProduct.getEnableLockinPeriod());
template.setBalanceFrequency(fullProduct.getBalanceFrequency());
template.setAccountClosedZeroBalanceInDayClosing(fullProduct.getAccountClosedZeroBalanceInDayClosing());
template.setBalanceSwapOption(fullProduct.getBalanceSwapOption());
template.setMsme(fullProduct.getMsme());
template.setAutoDebitFacility(fullProduct.getAutoDebitFacility());
template.setAvgBalanceCalcPeriod(fullProduct.getAvgBalanceCalcPeriod());
template.setValidForPeriod(fullProduct.getValidForPeriod());
template.setOdAccountClosedZeroBalanceInDayClosing(fullProduct.getOdAccountClosedZeroBalanceInDayClosing());
template.setAccountFacilityConfig(fullProduct.getAccountFacilityConfig());
template.setAccountFacilityLimits(fullProduct.getAccountFacilityLimits());
template.setDepositLimitKyc(fullProduct.getDepositLimitKyc());
// CBS Term fields
template.setInterestCalculateSelector(fullProduct.getInterestCalculateSelector());
template.setAveragePeriod(fullProduct.getAveragePeriod());
template.setAutoPost(fullProduct.getAutoPost());
template.setFrequencyFixDay(fullProduct.getFrequencyFixDay());
// CBS dropdown options (fetched from code values, same as product template page)
final Collection<EnumOptionData> interestCalculationTypeOption = this.codeValueReadPlatformService
.retrieveCodeValuesByCode(SavingsApiConstants.INTEREST_CALCULATION_TYPE_OPTION).stream()
.map(cv -> new EnumOptionData(cv.getId(),
"interestCalculationTypeOption." + cv.getName().toLowerCase(Locale.ROOT).replace(' ', '_'),
cv.getName()))
.toList();
template.setInterestCalculationTypeOption(interestCalculationTypeOption);
final Collection<EnumOptionData> periodFrequencyOptions = this.codeValueReadPlatformService
.retrieveCodeValuesByCode(SavingsApiConstants.PERIOD_FREQUENCY).stream()
.map(cv -> new EnumOptionData(cv.getId(),
"periodFrequencyType." + cv.getName().toLowerCase(Locale.ROOT).replace(' ', '_'),
cv.getName()))
.toList();
template.setPeriodFrequencyOptions(periodFrequencyOptions);
} catch (final Exception e) {
log.warn("Failed to enrich savings account template with CBS product data for productId={}: {}", productId, e.getMessage());
}
} else {
String clientName = null;
@@ -213,7 +213,7 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
sqlBuilder.append("sp.effective_date as effectiveDate, sp.effective_to as effectiveTo, sp.end_date as endDate, ");
sqlBuilder.append("sp.introducer_required as introducerRequired, sp.share_linking_enabled as shareLinkingEnabled, ");
sqlBuilder.append("sp.nomination_facility as nominationFacility, sp.dormancy_alert as dormancyAlert, ");
sqlBuilder.append("sp.interest_calculate_selector as interestCalculateSelector, sp.average_period as averagePeriod, ");
sqlBuilder.append("sp.interest_calculate_selector as interestCalculateSelector, icv.code_value as interestCalculationTypeName, sp.average_period as averagePeriod, ");
sqlBuilder.append("sp.auto_post as autoPost, sp.frequency_fix_day as frequencyFixDay, sp.last_interest_date as lastInterestDate, ");
sqlBuilder.append("sp.enable_lockin_period as enableLockinPeriod, ");
sqlBuilder.append("sp.balance_frequency as balanceFrequency, ");
@@ -221,7 +221,8 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
sqlBuilder.append("from m_savings_product sp ");
sqlBuilder.append("join m_currency curr on curr.code = sp.currency_code ");
sqlBuilder.append("left join m_tax_group tg on tg.id = sp.tax_group_id ");
sqlBuilder.append("left join m_tax_group tg on tg.id = sp.tax_group_id ");
sqlBuilder.append("left join m_code_value icv on icv.id = sp.interest_calculate_selector ");
this.schemaSql = sqlBuilder.toString();
}
@@ -328,6 +329,7 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
productData.setNominationFacility(rs.getBoolean("nominationFacility"));
productData.setDormancyAlert(rs.getBoolean("dormancyAlert"));
productData.setInterestCalculateSelector(JdbcSupport.getInteger(rs, "interestCalculateSelector"));
productData.setInterestCalculationTypeName(rs.getString("interestCalculationTypeName"));
productData.setAveragePeriod(rs.getString("averagePeriod"));
productData.setAutoPost(rs.getBoolean("autoPost"));
productData.setFrequencyFixDay(JdbcSupport.getInteger(rs, "frequencyFixDay"));
@@ -370,10 +370,10 @@ public class SavingsConfiguration {
GroupReadPlatformService groupReadPlatformService, SavingsProductReadPlatformService savingProductReadPlatformService,
StaffReadPlatformService staffReadPlatformService, SavingsDropdownReadPlatformService dropdownReadPlatformService,
ChargeReadPlatformService chargeReadPlatformService, EntityDatatableChecksReadService entityDatatableChecksReadService,
ColumnValidator columnValidator) {
ColumnValidator columnValidator, CodeValueReadPlatformService codeValueReadPlatformService) {
return new SavingsAccountTemplateReadPlatformServiceImpl(context, jdbcTemplate, clientReadPlatformService, groupReadPlatformService,
savingProductReadPlatformService, staffReadPlatformService, dropdownReadPlatformService, chargeReadPlatformService,
entityDatatableChecksReadService, columnValidator);
entityDatatableChecksReadService, columnValidator, codeValueReadPlatformService);
}
@Bean