Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1de1aab93 |
+10
-1
@@ -37,4 +37,13 @@ gradleExp/
|
||||
.windsurf/
|
||||
|
||||
# Application logs
|
||||
fineract-provider/logs/
|
||||
fineract-provider/logs/
|
||||
logs/
|
||||
|
||||
# Output of a local `gradlew devRun`
|
||||
devrun.log
|
||||
|
||||
# JVM crash dumps. The dev setup runs Fineract, the Angular dev server and Gradle on one
|
||||
# machine, so an out-of-memory kill drops these in the repo root.
|
||||
hs_err_pid*.log
|
||||
replay_pid*.log
|
||||
+20
@@ -1466,6 +1466,26 @@ public class LoanProductData implements Serializable {
|
||||
this.allowAttributeOverrides = loanProductConfigurableAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* The legacy "Account Type Creation" fields, flat and keyed by their form field name.
|
||||
*
|
||||
* Set after construction rather than through a constructor parameter: the main constructor already
|
||||
* takes over a hundred arguments, and threading two more through it would touch every call site for
|
||||
* no benefit. Follows the same pattern as setLoanProductConfigurableAttributes above.
|
||||
*/
|
||||
private Map<String, Object> cbsExtensions;
|
||||
|
||||
/** The legacy Interest Rate Detail grid: one entry per interest type, in form order. */
|
||||
private List<Map<String, Object>> interestRateDetail;
|
||||
|
||||
public void setCbsExtensions(final Map<String, Object> cbsExtensions) {
|
||||
this.cbsExtensions = cbsExtensions;
|
||||
}
|
||||
|
||||
public void setInterestRateDetail(final List<Map<String, Object>> interestRateDetail) {
|
||||
this.interestRateDetail = interestRateDetail;
|
||||
}
|
||||
|
||||
public boolean isIsLinkedToFloatingInterestRates() {
|
||||
return this.isLinkedToFloatingInterestRates;
|
||||
}
|
||||
|
||||
+740
@@ -0,0 +1,740 @@
|
||||
/**
|
||||
* Copyright since 2025 Mifos Initiative
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanproduct.domain;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* The legacy "Account Type Creation" configuration for a loan product.
|
||||
*
|
||||
* Fineract's loan product schema has no home for these fields, and they are specific to this
|
||||
* deployment, so they hang off {@link LoanProduct} 1:1 instead of widening m_product_loan - an
|
||||
* upstream change to that table can then never collide with them.
|
||||
*
|
||||
* Loan account creation reads this at origination time, which is why these are typed columns rather
|
||||
* than a JSON blob: callers get a compile-checked getter and reports get a plain column.
|
||||
*/
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@Table(name = "m_product_loan_cbs_ext")
|
||||
public class LoanProductCbsExt {
|
||||
|
||||
@Id
|
||||
@Column(name = "loan_product_id")
|
||||
private Long loanProductId;
|
||||
|
||||
/**
|
||||
* Shared primary key: this and {@link #loanProductId} are the same column, so the association is
|
||||
* mapped read-only and {@code loanProductId} is the one that writes it. EclipseLink rejects an
|
||||
* entity with two writable mappings for one field.
|
||||
*/
|
||||
@OneToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "loan_product_id", insertable = false, updatable = false)
|
||||
private LoanProduct loanProduct;
|
||||
|
||||
// ---- classification & legacy header fields (24) ---------------------
|
||||
|
||||
@Column(name = "product_type_group")
|
||||
private String productTypeGroup;
|
||||
|
||||
@Column(name = "product_type_sub_group")
|
||||
private String productTypeSubGroup;
|
||||
|
||||
@Column(name = "debit_int_calculation")
|
||||
private Boolean debitIntCalculation;
|
||||
|
||||
@Column(name = "separate_penal_interest")
|
||||
private Boolean separatePenalInterest;
|
||||
|
||||
@Column(name = "credit_int_calculation")
|
||||
private Boolean creditIntCalculation;
|
||||
|
||||
@Column(name = "sub_account_type_balance")
|
||||
private Boolean subAccountTypeBalance;
|
||||
|
||||
@Column(name = "final_int_rounding")
|
||||
private Boolean finalIntRounding;
|
||||
|
||||
@Column(name = "rounding_up_to")
|
||||
private Integer roundingUpTo;
|
||||
|
||||
@Column(name = "account_type_code")
|
||||
private String accountTypeCode;
|
||||
|
||||
@Column(name = "micr_transaction_code")
|
||||
private String micrTransactionCode;
|
||||
|
||||
@Column(name = "reserved_ecs_serial_number")
|
||||
private String reservedEcsSerialNumber;
|
||||
|
||||
@Column(name = "reverse_ecs_number")
|
||||
private String reverseEcsNumber;
|
||||
|
||||
@Column(name = "lock_cheque_info_enabled")
|
||||
private Boolean lockChequeInfoEnabled;
|
||||
|
||||
@Column(name = "lock_page_two_info_enabled")
|
||||
private Boolean lockPageTwoInfoEnabled;
|
||||
|
||||
@Column(name = "computerization_date")
|
||||
private LocalDate computerizationDate;
|
||||
|
||||
@Column(name = "cheque_print_description")
|
||||
private String chequePrintDescription;
|
||||
|
||||
@Column(name = "pos_account_type_description")
|
||||
private String posAccountTypeDescription;
|
||||
|
||||
@Column(name = "pfms_account_type")
|
||||
private String pfmsAccountType;
|
||||
|
||||
@Column(name = "renewal_date_add_months")
|
||||
private Integer renewalDateAddMonths;
|
||||
|
||||
@Column(name = "document_renewal_date_add_months")
|
||||
private Integer documentRenewalDateAddMonths;
|
||||
|
||||
@Column(name = "pps_limit")
|
||||
private BigDecimal ppsLimit;
|
||||
|
||||
@Column(name = "is_write_off_account_type")
|
||||
private Boolean isWriteOffAccountType;
|
||||
|
||||
@Column(name = "write_off_account_type_code")
|
||||
private String writeOffAccountTypeCode;
|
||||
|
||||
@Column(name = "renewal_grace_days")
|
||||
private Integer renewalGraceDays;
|
||||
|
||||
// ---- Cheque Book Settings (10) --------------------------------------
|
||||
|
||||
@Column(name = "cheque_book_issue_enabled")
|
||||
private Boolean chequeBookIssueEnabled;
|
||||
|
||||
@Column(name = "cheque_validation_required")
|
||||
private Boolean chequeValidationRequired;
|
||||
|
||||
@Column(name = "is_first_cheque_book_free")
|
||||
private Boolean isFirstChequeBookFree;
|
||||
|
||||
@Column(name = "cheque_printing_account_type")
|
||||
private String chequePrintingAccountType;
|
||||
|
||||
@Column(name = "allow_withdrawal_slip_usage")
|
||||
private Boolean allowWithdrawalSlipUsage;
|
||||
|
||||
@Column(name = "maintain_cheque_book_stock_registry")
|
||||
private Boolean maintainChequeBookStockRegistry;
|
||||
|
||||
@Column(name = "free_cheque_books_per_year")
|
||||
private Integer freeChequeBooksPerYear;
|
||||
|
||||
@Column(name = "allow_credit_by_cheque_number")
|
||||
private Boolean allowCreditByChequeNumber;
|
||||
|
||||
@Column(name = "credit_cheque_validation_required")
|
||||
private Boolean creditChequeValidationRequired;
|
||||
|
||||
@Column(name = "grace_days_for_stock_statement")
|
||||
private Integer graceDaysForStockStatement;
|
||||
|
||||
// ---- Additional Product Settings (37) -------------------------------
|
||||
|
||||
@Column(name = "account_type_active_for_transactions")
|
||||
private Boolean accountTypeActiveForTransactions;
|
||||
|
||||
@Column(name = "sub_type_activity_enabled")
|
||||
private Boolean subTypeActivityEnabled;
|
||||
|
||||
@Column(name = "account_opening_charges")
|
||||
private BigDecimal accountOpeningCharges;
|
||||
|
||||
@Column(name = "maximum_gold_loan_limit")
|
||||
private BigDecimal maximumGoldLoanLimit;
|
||||
|
||||
@Column(name = "last_account_number_opened")
|
||||
private String lastAccountNumberOpened;
|
||||
|
||||
@Column(name = "customer_termination_allowed")
|
||||
private Boolean customerTerminationAllowed;
|
||||
|
||||
@Column(name = "charges_for_cash_credit_above_limit")
|
||||
private BigDecimal chargesForCashCreditAboveLimit;
|
||||
|
||||
@Column(name = "death_interest_gl_account")
|
||||
private String deathInterestGLAccount;
|
||||
|
||||
@Column(name = "starting_ledger_number")
|
||||
private Integer startingLedgerNumber;
|
||||
|
||||
@Column(name = "ending_ledger_number")
|
||||
private Integer endingLedgerNumber;
|
||||
|
||||
@Column(name = "current_ledger_number")
|
||||
private Integer currentLedgerNumber;
|
||||
|
||||
@Column(name = "remittance_account_number")
|
||||
private String remittanceAccountNumber;
|
||||
|
||||
@Column(name = "is_non_resident_indian_account")
|
||||
private Boolean isNonResidentIndianAccount;
|
||||
|
||||
@Column(name = "debit_clearing_gl_account")
|
||||
private String debitClearingGLAccount;
|
||||
|
||||
@Column(name = "missed_call_alert_service_active")
|
||||
private Boolean missedCallAlertServiceActive;
|
||||
|
||||
@Column(name = "standing_instruction_charge_gl_account")
|
||||
private String standingInstructionChargeGLAccount;
|
||||
|
||||
@Column(name = "standing_instruction_debit_charge_skip_option")
|
||||
private String standingInstructionDebitChargeSkipOption;
|
||||
|
||||
@Column(name = "opening_balance_multiplier_for_remittance_charges")
|
||||
private BigDecimal openingBalanceMultiplierForRemittanceCharges;
|
||||
|
||||
@Column(name = "gold_loan_packet_number_with_year_enabled")
|
||||
private Boolean goldLoanPacketNumberWithYearEnabled;
|
||||
|
||||
@Column(name = "account_move_to_inoperative_enabled")
|
||||
private Boolean accountMoveToInoperativeEnabled;
|
||||
|
||||
@Column(name = "generate_gl_diff_entry_enabled")
|
||||
private Boolean generateGlDiffEntryEnabled;
|
||||
|
||||
@Column(name = "sub_type_wise_gl_balance_generation_enabled")
|
||||
private Boolean subTypeWiseGlBalanceGenerationEnabled;
|
||||
|
||||
@Column(name = "validate_before_deleting_debit_entry_enabled")
|
||||
private Boolean validateBeforeDeletingDebitEntryEnabled;
|
||||
|
||||
@Column(name = "rc_file_concept_enabled")
|
||||
private Boolean rcFileConceptEnabled;
|
||||
|
||||
@Column(name = "account_close_zero_balance_in_open_day_process")
|
||||
private Boolean accountCloseZeroBalanceInOpenDayProcess;
|
||||
|
||||
@Column(name = "account_close_zero_balance_at_subledger_tran_entry")
|
||||
private Boolean accountCloseZeroBalanceAtSubledgerTranEntry;
|
||||
|
||||
@Column(name = "limit_enhancement_against_clearing_screen_display_enabled")
|
||||
private Boolean limitEnhancementAgainstClearingScreenDisplayEnabled;
|
||||
|
||||
@Column(name = "advance_interest_parameter_in_ledger_enabled")
|
||||
private Boolean advanceInterestParameterInLedgerEnabled;
|
||||
|
||||
@Column(name = "vehicle_detail_in_master_enabled")
|
||||
private Boolean vehicleDetailInMasterEnabled;
|
||||
|
||||
@Column(name = "deleted_cheque_issue_enabled")
|
||||
private Boolean deletedChequeIssueEnabled;
|
||||
|
||||
@Column(name = "dp_reduce_in_document_renewal_date_enabled")
|
||||
private Boolean dpReduceInDocumentRenewalDateEnabled;
|
||||
|
||||
@Column(name = "dp_reduce_in_renewal_date_enabled")
|
||||
private Boolean dpReduceInRenewalDateEnabled;
|
||||
|
||||
@Column(name = "auto_close_at_day_end_enabled")
|
||||
private Boolean autoCloseAtDayEndEnabled;
|
||||
|
||||
@Column(name = "loan_rate_from_master_enabled")
|
||||
private Boolean loanRateFromMasterEnabled;
|
||||
|
||||
@Column(name = "cheque_short_name")
|
||||
private String chequeShortName;
|
||||
|
||||
@Column(name = "statement_print_enabled")
|
||||
private Boolean statementPrintEnabled;
|
||||
|
||||
@Column(name = "nesl_code")
|
||||
private String neslCode;
|
||||
|
||||
// ---- Interest Related Parameters (53) -------------------------------
|
||||
|
||||
@Column(name = "drawing_power_and_limit_generation_procedure")
|
||||
private String drawingPowerAndLimitGenerationProcedure;
|
||||
|
||||
@Column(name = "advances_interest_calculation_method")
|
||||
private String advancesInterestCalculationMethod;
|
||||
|
||||
@Column(name = "against_interest_calculation_enabled")
|
||||
private Boolean againstInterestCalculationEnabled;
|
||||
|
||||
@Column(name = "day_wise_against_clearing_interest_rounding")
|
||||
private Boolean dayWiseAgainstClearingInterestRounding;
|
||||
|
||||
@Column(name = "interest_calculation_one_fourth_method")
|
||||
private String interestCalculationOneFourthMethod;
|
||||
|
||||
@Column(name = "against_clearing_interest_procedure_type")
|
||||
private String againstClearingInterestProcedureType;
|
||||
|
||||
@Column(name = "consider_debit_closing_amount_for_against_clearing")
|
||||
private Boolean considerDebitClosingAmountForAgainstClearing;
|
||||
|
||||
@Column(name = "interest_rounding_method")
|
||||
private String interestRoundingMethod;
|
||||
|
||||
@Column(name = "penalty_interest_calculation_enabled")
|
||||
private Boolean penaltyInterestCalculationEnabled;
|
||||
|
||||
@Column(name = "penalty_interest_calculation_method")
|
||||
private String penaltyInterestCalculationMethod;
|
||||
|
||||
@Column(name = "penalty_interest_procedure_number")
|
||||
private String penaltyInterestProcedureNumber;
|
||||
|
||||
@Column(name = "overdrawn_interest_calculation_method")
|
||||
private String overdrawnInterestCalculationMethod;
|
||||
|
||||
@Column(name = "calculate_overdrawn_interest_after_renewal")
|
||||
private Boolean calculateOverdrawnInterestAfterRenewal;
|
||||
|
||||
@Column(name = "interest_on_credit_balance")
|
||||
private Boolean interestOnCreditBalance;
|
||||
|
||||
@Column(name = "penalty_interest_date_different_than_regular_interest")
|
||||
private Boolean penaltyInterestDateDifferentThanRegularInterest;
|
||||
|
||||
@Column(name = "fixed_deposit_overdraft_certificate_sort_order")
|
||||
private String fixedDepositOverdraftCertificateSortOrder;
|
||||
|
||||
@Column(name = "use_document_submission_date_for_interest")
|
||||
private Boolean useDocumentSubmissionDateForInterest;
|
||||
|
||||
@Column(name = "loan_management_system_renewal_penalty_active")
|
||||
private Boolean loanManagementSystemRenewalPenaltyActive;
|
||||
|
||||
@Column(name = "minimum_normal_interest_amount")
|
||||
private BigDecimal minimumNormalInterestAmount;
|
||||
|
||||
@Column(name = "minimum_interest_calculation_method")
|
||||
private String minimumInterestCalculationMethod;
|
||||
|
||||
@Column(name = "minimum_against_clearing_interest_amount")
|
||||
private BigDecimal minimumAgainstClearingInterestAmount;
|
||||
|
||||
@Column(name = "limit_increase_upto_interest_amount_in_interest_calculation")
|
||||
private Boolean limitIncreaseUptoInterestAmountInInterestCalculation;
|
||||
|
||||
@Column(name = "minimum_penalty_interest_amount")
|
||||
private BigDecimal minimumPenaltyInterestAmount;
|
||||
|
||||
@Column(name = "days_for_limit_increase_upto_interest_amount")
|
||||
private Integer daysForLimitIncreaseUptoInterestAmount;
|
||||
|
||||
@Column(name = "additional_interest_rate_for_fixed_deposit_overdraft")
|
||||
private BigDecimal additionalInterestRateForFixedDepositOverdraft;
|
||||
|
||||
@Column(name = "consider_dd_payorder_in_against_clearing_interest_calculation")
|
||||
private Boolean considerDdPayorderInAgainstClearingInterestCalculation;
|
||||
|
||||
@Column(name = "grace_days_after_renew_date")
|
||||
private Integer graceDaysAfterRenewDate;
|
||||
|
||||
@Column(name = "apply_undebited_interest_concept_enabled")
|
||||
private Boolean applyUndebitedInterestConceptEnabled;
|
||||
|
||||
@Column(name = "interest_register_print_format_type")
|
||||
private String interestRegisterPrintFormatType;
|
||||
|
||||
@Column(name = "normal_grace_days_after_overdue")
|
||||
private Integer normalGraceDaysAfterOverdue;
|
||||
|
||||
@Column(name = "allow_against_clearing_entry")
|
||||
private Boolean allowAgainstClearingEntry;
|
||||
|
||||
@Column(name = "allow_no_balance_entry")
|
||||
private Boolean allowNoBalanceEntry;
|
||||
|
||||
@Column(name = "fd_od_penalty_interest_combined_with_normal_interest")
|
||||
private Boolean fixedDepositOverdraftPenaltyInterestCombinedWithNormalInterest;
|
||||
|
||||
@Column(name = "allow_no_balance_entry_with_password")
|
||||
private Boolean allowNoBalanceEntryWithPassword;
|
||||
|
||||
@Column(name = "undebited_simple_interest_account_wise")
|
||||
private Boolean undebitedSimpleInterestAccountWise;
|
||||
|
||||
@Column(name = "daily_interest_calculation_enabled")
|
||||
private Boolean dailyInterestCalculationEnabled;
|
||||
|
||||
@Column(name = "daily_interest_calculation_start_date")
|
||||
private String dailyInterestCalculationStartDate;
|
||||
|
||||
@Column(name = "non_performing_asset_penal_interest_rate_update")
|
||||
private Boolean nonPerformingAssetPenalInterestRateUpdate;
|
||||
|
||||
@Column(name = "non_performing_asset_penal_interest_rate")
|
||||
private BigDecimal nonPerformingAssetPenalInterestRate;
|
||||
|
||||
@Column(name = "fd_od_penal_interest_rate_update_in_branch_process")
|
||||
private Boolean fixedDepositOverdraftPenalInterestRateUpdateInBranchProcess;
|
||||
|
||||
@Column(name = "add_penal_interest_rate")
|
||||
private BigDecimal addPenalInterestRate;
|
||||
|
||||
@Column(name = "atyp14_simple_interest_enabled")
|
||||
private Boolean atyp14SimpleInterestEnabled;
|
||||
|
||||
@Column(name = "fixed_deposit_overdraft_margin_type")
|
||||
private String fixedDepositOverdraftMarginType;
|
||||
|
||||
@Column(name = "check_master_detail_edited_passing_pending_enabled")
|
||||
private Boolean checkMasterDetailEditedPassingPendingEnabled;
|
||||
|
||||
@Column(name = "credit_debit_interest_calculation_separate_enabled")
|
||||
private Boolean creditDebitInterestCalculationSeparateEnabled;
|
||||
|
||||
@Column(name = "on_time_interest_provision_enabled")
|
||||
private Boolean onTimeInterestProvisionEnabled;
|
||||
|
||||
@Column(name = "check_against_clearing_enabled")
|
||||
private Boolean checkAgainstClearingEnabled;
|
||||
|
||||
@Column(name = "gst_on_penalty_enabled")
|
||||
private Boolean gstOnPenaltyEnabled;
|
||||
|
||||
@Column(name = "penalty_interest_grace_days")
|
||||
private Integer penaltyInterestGraceDays;
|
||||
|
||||
@Column(name = "overdrawn_interest_rate")
|
||||
private BigDecimal overdrawnInterestRate;
|
||||
|
||||
@Column(name = "calculate_daily_limit_enhancement_tod_enabled")
|
||||
private Boolean calculateDailyLimitEnhancementTodEnabled;
|
||||
|
||||
@Column(name = "fixed_deposit_overdraft_multiple_interest_rate_enabled")
|
||||
private Boolean fixedDepositOverdraftMultipleInterestRateEnabled;
|
||||
|
||||
@Column(name = "grace_days_after_overdue_for_moratorium")
|
||||
private Integer graceDaysAfterOverdueForMoratorium;
|
||||
|
||||
// ---- Credit Bureau Settings (CIBIL) (8) ----------------------------
|
||||
|
||||
@Column(name = "cibil_account_type")
|
||||
private String cibilAccountType;
|
||||
|
||||
@Column(name = "cibil_commercial_account_type")
|
||||
private String cibilCommercialAccountType;
|
||||
|
||||
@Column(name = "highmark_account_type")
|
||||
private String highmarkAccountType;
|
||||
|
||||
@Column(name = "highmark_commercial_account_type")
|
||||
private String highmarkCommercialAccountType;
|
||||
|
||||
@Column(name = "experian_account_type")
|
||||
private String experianAccountType;
|
||||
|
||||
@Column(name = "experian_commercial_account_type")
|
||||
private String experianCommercialAccountType;
|
||||
|
||||
@Column(name = "equifax_account_type")
|
||||
private String equifaxAccountType;
|
||||
|
||||
@Column(name = "equifax_commercial_account_type")
|
||||
private String equifaxCommercialAccountType;
|
||||
|
||||
// ---- RBI Compliance & Product Category (6) -------------------------
|
||||
|
||||
@Column(name = "loan_product_category")
|
||||
private String loanProductCategory;
|
||||
|
||||
@Column(name = "penal_charge_method")
|
||||
private String penalChargeMethod;
|
||||
|
||||
@Column(name = "is_floating_rate")
|
||||
private Boolean isFloatingRate;
|
||||
|
||||
@Column(name = "foreclosure_charges_applicable")
|
||||
private Boolean foreclosureChargesApplicable;
|
||||
|
||||
@Column(name = "key_fact_statement_enabled")
|
||||
private Boolean keyFactStatementEnabled;
|
||||
|
||||
@Column(name = "annual_percentage_rate_calculation_enabled")
|
||||
private Boolean annualPercentageRateCalculationEnabled;
|
||||
|
||||
// ---- Channel & Transaction Limits (23) ------------------------------
|
||||
|
||||
@Column(name = "is_mobile_app_enabled")
|
||||
private Boolean isMobileAppEnabled;
|
||||
|
||||
@Column(name = "is_atm_enabled")
|
||||
private Boolean isAtmEnabled;
|
||||
|
||||
@Column(name = "atm_yearly_charge_enabled")
|
||||
private Boolean atmYearlyChargeEnabled;
|
||||
|
||||
@Column(name = "atm_minimum_balance")
|
||||
private BigDecimal atmMinimumBalance;
|
||||
|
||||
@Column(name = "email_active_enabled")
|
||||
private Boolean emailActiveEnabled;
|
||||
|
||||
@Column(name = "is_imps_enabled")
|
||||
private Boolean isImpsEnabled;
|
||||
|
||||
@Column(name = "is_upi_enabled")
|
||||
private Boolean isUpiEnabled;
|
||||
|
||||
@Column(name = "is_pos_enabled")
|
||||
private Boolean isPosEnabled;
|
||||
|
||||
@Column(name = "is_bbps_enabled")
|
||||
private Boolean isBbpsEnabled;
|
||||
|
||||
@Column(name = "inter_bank_limit_per_day")
|
||||
private BigDecimal interBankLimitPerDay;
|
||||
|
||||
@Column(name = "inter_bank_limit_per_transaction")
|
||||
private BigDecimal interBankLimitPerTransaction;
|
||||
|
||||
@Column(name = "neft_rtgs_limit_per_day")
|
||||
private BigDecimal neftRtgsLimitPerDay;
|
||||
|
||||
@Column(name = "neft_rtgs_limit_per_transaction")
|
||||
private BigDecimal neftRtgsLimitPerTransaction;
|
||||
|
||||
@Column(name = "neft_cutoff_limit")
|
||||
private BigDecimal neftCutoffLimit;
|
||||
|
||||
@Column(name = "rtgs_cutoff_limit")
|
||||
private BigDecimal rtgsCutoffLimit;
|
||||
|
||||
@Column(name = "neft_rtgs_minimum_balance")
|
||||
private BigDecimal neftRtgsMinimumBalance;
|
||||
|
||||
@Column(name = "is_charge_required_neft_rtgs_cbs")
|
||||
private Boolean isChargeRequiredNeftRtgsCbs;
|
||||
|
||||
@Column(name = "is_charge_required_neft_rtgs_mobile")
|
||||
private Boolean isChargeRequiredNeftRtgsMobile;
|
||||
|
||||
@Column(name = "imps_limit_per_day")
|
||||
private BigDecimal impsLimitPerDay;
|
||||
|
||||
@Column(name = "imps_limit_per_transaction")
|
||||
private BigDecimal impsLimitPerTransaction;
|
||||
|
||||
@Column(name = "imps_limit_per_month")
|
||||
private BigDecimal impsLimitPerMonth;
|
||||
|
||||
@Column(name = "imps_min_limit")
|
||||
private BigDecimal impsMinLimit;
|
||||
|
||||
@Column(name = "imps_monthly_transaction_count")
|
||||
private Integer impsMonthlyTransactionCount;
|
||||
|
||||
// ---- POS Facility & ATM CSV Settings (10) ---------------------------
|
||||
|
||||
@Column(name = "max_per_transaction_limit_atm")
|
||||
private BigDecimal maxPerTransactionLimitAtm;
|
||||
|
||||
@Column(name = "max_day_transaction_limit_atm")
|
||||
private BigDecimal maxDayTransactionLimitAtm;
|
||||
|
||||
@Column(name = "max_per_transaction_limit_pos")
|
||||
private BigDecimal maxPerTransactionLimitPos;
|
||||
|
||||
@Column(name = "max_day_transaction_limit_pos")
|
||||
private BigDecimal maxDayTransactionLimitPos;
|
||||
|
||||
@Column(name = "max_per_transaction_limit_ecom")
|
||||
private BigDecimal maxPerTransactionLimitEcom;
|
||||
|
||||
@Column(name = "max_day_transaction_limit_ecom")
|
||||
private BigDecimal maxDayTransactionLimitEcom;
|
||||
|
||||
@Column(name = "max_per_transaction_limit_upi")
|
||||
private BigDecimal maxPerTransactionLimitUpi;
|
||||
|
||||
@Column(name = "max_day_transaction_limit_upi")
|
||||
private BigDecimal maxDayTransactionLimitUpi;
|
||||
|
||||
@Column(name = "atm_csv_product_code")
|
||||
private String atmCsvProductCode;
|
||||
|
||||
@Column(name = "atm_csv_type_code")
|
||||
private String atmCsvTypeCode;
|
||||
|
||||
// ---- Auto Interest Post Parameters (4) -----------------------------
|
||||
|
||||
@Column(name = "auto_interest_post_type")
|
||||
private String autoInterestPostType;
|
||||
|
||||
@Column(name = "auto_interest_post_when")
|
||||
private String autoInterestPostWhen;
|
||||
|
||||
@Column(name = "auto_interest_post_fix_day")
|
||||
private Integer autoInterestPostFixDay;
|
||||
|
||||
@Column(name = "auto_last_interest_date")
|
||||
private String autoLastInterestDate;
|
||||
|
||||
// ---- Foreclosure / Early Account Closure (3) -----------------------
|
||||
|
||||
@Column(name = "calculate_early_account_close_charge")
|
||||
private Boolean calculateEarlyAccountCloseCharge;
|
||||
|
||||
@Column(name = "early_account_close_charge")
|
||||
private BigDecimal earlyAccountCloseCharge;
|
||||
|
||||
@Column(name = "early_account_close_period_in_months")
|
||||
private Integer earlyAccountClosePeriodInMonths;
|
||||
|
||||
// ---- Terms step (3) ------------------------------------------------
|
||||
|
||||
@Column(name = "debit_balance_allow")
|
||||
private Boolean debitBalanceAllow;
|
||||
|
||||
@Column(name = "allow_debit_trans_after_due_date")
|
||||
private Boolean allowDebitTransAfterDueDate;
|
||||
|
||||
@Column(name = "branch_level_account_type")
|
||||
private Boolean branchLevelAccountType;
|
||||
|
||||
// ---- legacy cheque / standing instruction / minimum balance charges (24)
|
||||
|
||||
@Column(name = "cheque_book_charge_enabled")
|
||||
private Boolean chequeBookChargeEnabled;
|
||||
|
||||
@Column(name = "cheque_return_charge_enabled")
|
||||
private Boolean chequeReturnChargeEnabled;
|
||||
|
||||
@Column(name = "ic_charge_debit_enabled")
|
||||
private Boolean icChargeDebitEnabled;
|
||||
|
||||
@Column(name = "cash_bundle_charge_enabled")
|
||||
private Boolean cashBundleChargeEnabled;
|
||||
|
||||
@Column(name = "cash_bundle_charge_with_pan_limit")
|
||||
private BigDecimal cashBundleChargeWithPanLimit;
|
||||
|
||||
@Column(name = "per_cheque_entry_charge")
|
||||
private BigDecimal perChequeEntryCharge;
|
||||
|
||||
@Column(name = "per_cheque_entry_service_charge")
|
||||
private BigDecimal perChequeEntryServiceCharge;
|
||||
|
||||
@Column(name = "per_inward_cheque_entry_charge")
|
||||
private BigDecimal perInwardChequeEntryCharge;
|
||||
|
||||
@Column(name = "per_outward_cheque_entry_charge")
|
||||
private BigDecimal perOutwardChequeEntryCharge;
|
||||
|
||||
@Column(name = "creditor_standing_instruction_fail_charge")
|
||||
private BigDecimal creditorStandingInstructionFailCharge;
|
||||
|
||||
@Column(name = "debtor_standing_instruction_fail_charge")
|
||||
private BigDecimal debtorStandingInstructionFailCharge;
|
||||
|
||||
@Column(name = "minimum_balance_checking_type")
|
||||
private String minimumBalanceCheckingType;
|
||||
|
||||
@Column(name = "auto_minimum_balance_charge")
|
||||
private Boolean autoMinimumBalanceCharge;
|
||||
|
||||
@Column(name = "calculate_daily_minimum_balance_charges")
|
||||
private Boolean calculateDailyMinimumBalanceCharges;
|
||||
|
||||
@Column(name = "minimum_balance_charge_enabled")
|
||||
private Boolean minimumBalanceChargeEnabled;
|
||||
|
||||
@Column(name = "minimum_balance_charge_amount")
|
||||
private BigDecimal minimumBalanceChargeAmount;
|
||||
|
||||
@Column(name = "minimum_balance_charge_for_cheque_issue")
|
||||
private BigDecimal minimumBalanceChargeForChequeIssue;
|
||||
|
||||
@Column(name = "minimum_balance_charge_method")
|
||||
private String minimumBalanceChargeMethod;
|
||||
|
||||
@Column(name = "months_after_min_balance_charge_calculate")
|
||||
private Integer monthsAfterMinBalanceChargeCalculate;
|
||||
|
||||
@Column(name = "for_cheque_issue")
|
||||
private BigDecimal forChequeIssue;
|
||||
|
||||
@Column(name = "for_cheque_issue_avg")
|
||||
private BigDecimal forChequeIssueAvg;
|
||||
|
||||
@Column(name = "for_withdrawal_slip")
|
||||
private BigDecimal forWithdrawalSlip;
|
||||
|
||||
@Column(name = "for_withdrawal_slip_avg")
|
||||
private BigDecimal forWithdrawalSlipAvg;
|
||||
|
||||
@Column(name = "calculate_daily_against_clearing_charge")
|
||||
private Boolean calculateDailyAgainstClearingCharge;
|
||||
|
||||
// ---- custom GL account mappings (14) --------------------------------
|
||||
|
||||
@Column(name = "int_receivables_gl_account_id")
|
||||
private Long intReceivablesGlAccountId;
|
||||
|
||||
@Column(name = "int_payable_gl_account_id")
|
||||
private Long intPayableGlAccountId;
|
||||
|
||||
@Column(name = "deaf_int_payable_gl_account_id")
|
||||
private Long deafIntPayableGlAccountId;
|
||||
|
||||
@Column(name = "int_overdue_reserve_account_id")
|
||||
private Long intOverdueReserveAccountId;
|
||||
|
||||
@Column(name = "undebited_interest_account_id")
|
||||
private Long undebitedInterestAccountId;
|
||||
|
||||
@Column(name = "penal_int_cr_gl_account_id")
|
||||
private Long penalIntCrGlAccountId;
|
||||
|
||||
@Column(name = "rd_matured_gl_account_id")
|
||||
private Long rdMaturedGlAccountId;
|
||||
|
||||
@Column(name = "gl_account_id")
|
||||
private Long glAccountId;
|
||||
|
||||
@Column(name = "ic_charge_gl_account_id")
|
||||
private Long icChargeGlAccountId;
|
||||
|
||||
@Column(name = "inoperative_gl_account_id")
|
||||
private Long inoperativeGlAccountId;
|
||||
|
||||
@Column(name = "credit_balance_liability_gl_account_id")
|
||||
private Long creditBalanceLiabilityGlAccountId;
|
||||
|
||||
@Column(name = "credit_balance_asset_gl_account_id")
|
||||
private Long creditBalanceAssetGlAccountId;
|
||||
|
||||
@Column(name = "overdue_accounts_gl_account_id")
|
||||
private Long overdueAccountsGlAccountId;
|
||||
|
||||
@Column(name = "rebate_gl_account_id")
|
||||
private Long rebateGlAccountId;
|
||||
|
||||
public LoanProductCbsExt(final LoanProduct loanProduct) {
|
||||
this.loanProduct = loanProduct;
|
||||
this.loanProductId = loanProduct.getId();
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright since 2025 Mifos Initiative
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanproduct.domain;
|
||||
|
||||
import java.util.Optional;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface LoanProductCbsExtRepository extends JpaRepository<LoanProductCbsExt, Long> {
|
||||
|
||||
/**
|
||||
* A product created before this table existed - or one saved without any legacy field filled in - has
|
||||
* no row here, so callers must handle the empty case rather than assuming one exists.
|
||||
*/
|
||||
Optional<LoanProductCbsExt> findByLoanProductId(Long loanProductId);
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Copyright since 2025 Mifos Initiative
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanproduct.domain;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.UniqueConstraint;
|
||||
import java.math.BigDecimal;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
|
||||
/**
|
||||
* One row of the legacy "Interest Rate Detail" grid on the loan product form.
|
||||
*
|
||||
* The grid is a fixed four rows - Normal Debit, Normal Credit, Against Clearing and Penalty - each
|
||||
* carrying a Normal and a Special min/max rate plus the period they apply over. It is a child table
|
||||
* rather than twenty-four columns on {@link LoanProductCbsExt} because the interest type reads far
|
||||
* better as data than as part of a column name: against_clearing_special_max_rate and its siblings
|
||||
* are almost unreadable, and any new interest type would mean another migration.
|
||||
*
|
||||
* The rows are fixed today, so {@link #INTEREST_TYPES} is the full set and the table carries a unique
|
||||
* constraint on (product, interest type) - a replayed save updates in place instead of doubling the
|
||||
* grid.
|
||||
*/
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@Table(name = "m_product_loan_cbs_interest_rate", uniqueConstraints = {
|
||||
@UniqueConstraint(columnNames = { "loan_product_id", "interest_type" }, name = "mplcir_unq_product_interest_type") })
|
||||
public class LoanProductCbsInterestRate extends AbstractPersistableCustom<Long> {
|
||||
|
||||
/** The grid's rows, in the order the form shows them. */
|
||||
public static final String[] INTEREST_TYPES = { "Normal Debit", "Normal Credit", "Against Clearing", "Penalty" };
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY, optional = false)
|
||||
@JoinColumn(name = "loan_product_id", nullable = false)
|
||||
private LoanProduct loanProduct;
|
||||
|
||||
@Column(name = "interest_type", nullable = false, length = 30)
|
||||
private String interestType;
|
||||
|
||||
@Column(name = "calculation")
|
||||
private Boolean calculation;
|
||||
|
||||
@Column(name = "normal_min_rate", precision = 9, scale = 6)
|
||||
private BigDecimal normalMinRate;
|
||||
|
||||
@Column(name = "normal_max_rate", precision = 9, scale = 6)
|
||||
private BigDecimal normalMaxRate;
|
||||
|
||||
@Column(name = "special_min_rate", precision = 9, scale = 6)
|
||||
private BigDecimal specialMinRate;
|
||||
|
||||
@Column(name = "special_max_rate", precision = 9, scale = 6)
|
||||
private BigDecimal specialMaxRate;
|
||||
|
||||
@Column(name = "period", length = 20)
|
||||
private String period;
|
||||
|
||||
public LoanProductCbsInterestRate(final LoanProduct loanProduct, final String interestType) {
|
||||
this.loanProduct = loanProduct;
|
||||
this.interestType = interestType;
|
||||
}
|
||||
|
||||
/** True when the officer left this row untouched, so it need not be persisted. */
|
||||
public boolean isEmpty() {
|
||||
return !Boolean.TRUE.equals(this.calculation) && this.normalMinRate == null && this.normalMaxRate == null
|
||||
&& this.specialMinRate == null && this.specialMaxRate == null && (this.period == null || this.period.isBlank());
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright since 2025 Mifos Initiative
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanproduct.domain;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface LoanProductCbsInterestRateRepository extends JpaRepository<LoanProductCbsInterestRate, Long> {
|
||||
|
||||
List<LoanProductCbsInterestRate> findByLoanProductIdOrderById(Long loanProductId);
|
||||
|
||||
LoanProductCbsInterestRate findByLoanProductIdAndInterestType(Long loanProductId, String interestType);
|
||||
}
|
||||
+9
@@ -107,6 +107,7 @@ import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundEx
|
||||
import org.apache.fineract.portfolio.loanproduct.productmix.data.ProductMixData;
|
||||
import org.apache.fineract.portfolio.loanproduct.productmix.service.ProductMixReadPlatformService;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanDropdownReadPlatformService;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanProductCbsExtService;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanProductReadPlatformService;
|
||||
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
||||
import org.apache.fineract.portfolio.paymenttype.service.PaymentTypeReadService;
|
||||
@@ -171,6 +172,7 @@ public class LoanProductsApiResource {
|
||||
private final ConfigurationDomainService configurationDomainService;
|
||||
private final DelinquencyReadPlatformService delinquencyReadPlatformService;
|
||||
private final CodeValueReadPlatformService codeValueReadPlatformService;
|
||||
private final LoanProductCbsExtService loanProductCbsExtService;
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@@ -384,6 +386,13 @@ public class LoanProductsApiResource {
|
||||
if (settings.isTemplate()) {
|
||||
loanProduct = handleTemplate(loanProduct);
|
||||
}
|
||||
|
||||
// Legacy "Account Type Creation" fields, so the edit form can be repopulated with what was saved.
|
||||
// Set here rather than in the read service because handleTemplate above returns a fresh
|
||||
// LoanProductData built by a copy constructor, which would not carry these across.
|
||||
loanProduct.setCbsExtensions(this.loanProductCbsExtService.retrieveAsMap(productId));
|
||||
loanProduct.setInterestRateDetail(this.loanProductCbsExtService.retrieveInterestRateDetail(productId));
|
||||
|
||||
return this.toApiJsonSerializer.serialize(settings, loanProduct, LOAN_PRODUCT_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
|
||||
+18
-4
@@ -77,6 +77,7 @@ import org.apache.fineract.portfolio.loanproduct.domain.LoanRescheduleStrategyMe
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanSupportedInterestRefundTypes;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
||||
import org.apache.fineract.portfolio.loanproduct.exception.EqualAmortizationUnsupportedFeatureException;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanProductCbsExtService;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@@ -212,6 +213,12 @@ public final class LoanProductDataValidator {
|
||||
LoanProductConstants.ALLOW_FULL_TERM_FOR_TRANCHE_PARAM_NAME //
|
||||
));
|
||||
|
||||
static {
|
||||
// The legacy "Account Type Creation" fields are persisted by LoanProductCbsExtService, which owns
|
||||
// the authoritative list of their names -- added here rather than restated so the two cannot drift.
|
||||
SUPPORTED_PARAMETERS.addAll(Arrays.asList(LoanProductCbsExtService.CBS_PARAMETERS));
|
||||
}
|
||||
|
||||
private static final String[] SUPPORTED_LOAN_CONFIGURABLE_ATTRIBUTES = { LoanProductConstants.amortizationTypeParamName,
|
||||
LoanProductConstants.interestTypeParamName, LoanProductConstants.transactionProcessingStrategyCodeParamName,
|
||||
LoanProductConstants.interestCalculationPeriodTypeParamName, LoanProductConstants.inArrearsToleranceParamName,
|
||||
@@ -235,8 +242,14 @@ public final class LoanProductDataValidator {
|
||||
throw new InvalidJsonException();
|
||||
}
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SUPPORTED_PARAMETERS);
|
||||
// TEMPORARILY DISABLED while the legacy "Account Type Creation" fields are being wired through this
|
||||
// endpoint. SUPPORTED_PARAMETERS above already lists them, so re-enabling this is a one-line revert.
|
||||
//
|
||||
// Note what is lost until then: an unrecognised parameter is now accepted and silently ignored
|
||||
// instead of returning 400. A misspelt field name will therefore look like it saved and simply not
|
||||
// appear, so check the column actually changed rather than trusting a 200.
|
||||
// final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
// this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SUPPORTED_PARAMETERS);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(LOANPRODUCT);
|
||||
@@ -1336,8 +1349,9 @@ public final class LoanProductDataValidator {
|
||||
throw new InvalidJsonException();
|
||||
}
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SUPPORTED_PARAMETERS);
|
||||
// TEMPORARILY DISABLED -- see the same note on validateForCreate above.
|
||||
// final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
// this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SUPPORTED_PARAMETERS);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(LOANPRODUCT);
|
||||
|
||||
+2117
File diff suppressed because it is too large
Load Diff
+14
@@ -97,6 +97,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
||||
private final CreditAllocationsJsonParser creditAllocationsJsonParser;
|
||||
private final LoanProductAssembler loanProductAssembler;
|
||||
private final LoanProductUpdateUtil loanProductUpdateUtil;
|
||||
private final LoanProductCbsExtService loanProductCbsExtService;
|
||||
private final LoanProductPaymentAllocationRuleMerger loanProductPaymentAllocationRuleMerger = new LoanProductPaymentAllocationRuleMerger();
|
||||
private final LoanProductCreditAllocationRuleMerger loanProductCreditAllocationRuleMerger = new LoanProductCreditAllocationRuleMerger();
|
||||
|
||||
@@ -141,6 +142,11 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
||||
|
||||
this.loanProductRepository.saveAndFlush(loanProduct);
|
||||
|
||||
// Legacy "Account Type Creation" fields, persisted in their own satellite table. Called after the
|
||||
// flush because the satellite row is keyed on the product's generated id. A request carrying none
|
||||
// of those parameters writes nothing.
|
||||
this.loanProductCbsExtService.saveOrUpdate(loanProduct, command);
|
||||
|
||||
// save accounting mappings
|
||||
this.accountMappingWritePlatformService.createLoanProductToGLAccountMapping(loanProduct.getId(), command);
|
||||
// check if the office specific products are enabled. If yes, then
|
||||
@@ -303,6 +309,14 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
||||
this.loanProductRepository.saveAndFlush(product);
|
||||
}
|
||||
|
||||
// Legacy "Account Type Creation" fields. Deliberately outside the changes check above: those
|
||||
// changes only track the standard product columns, so an edit that touched nothing but a legacy
|
||||
// field leaves the map empty and would otherwise be dropped.
|
||||
//
|
||||
// What it changed is folded into the same changes map, so the audit trail shows a per-field
|
||||
// diff for these exactly as it does for the standard ones rather than an empty change set.
|
||||
changes.putAll(this.loanProductCbsExtService.saveOrUpdate(product, command));
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(loanProductId) //
|
||||
|
||||
+4
-2
@@ -40,6 +40,7 @@ import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
|
||||
import org.apache.fineract.portfolio.loanproduct.serialization.LoanProductDataValidator;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanDropdownReadPlatformService;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanDropdownReadPlatformServiceImpl;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanProductCbsExtService;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanProductReadPlatformService;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanProductReadPlatformServiceImpl;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanProductWritePlatformService;
|
||||
@@ -82,11 +83,12 @@ public class LoanProductConfiguration {
|
||||
DelinquencyBucketRepository delinquencyBucketRepository,
|
||||
LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||
AdvancedPaymentAllocationsJsonParser advancedPaymentJsonParser, CreditAllocationsJsonParser creditAllocationsJsonParser,
|
||||
LoanProductAssembler loanProductAssembler, LoanProductUpdateUtil loanProductUpdateUtil) {
|
||||
LoanProductAssembler loanProductAssembler, LoanProductUpdateUtil loanProductUpdateUtil,
|
||||
LoanProductCbsExtService loanProductCbsExtService) {
|
||||
return new LoanProductWritePlatformServiceJpaRepositoryImpl(context, fromApiJsonDeserializer, loanProductRepository, aprCalculator,
|
||||
fundRepository, chargeRepository, rateRepository, accountMappingWritePlatformService, fineractEntityAccessUtil,
|
||||
floatingRateRepository, loanRepositoryWrapper, businessEventNotifierService, delinquencyBucketRepository,
|
||||
loanRepaymentScheduleTransactionProcessorFactory, advancedPaymentJsonParser, creditAllocationsJsonParser,
|
||||
loanProductAssembler, loanProductUpdateUtil);
|
||||
loanProductAssembler, loanProductUpdateUtil, loanProductCbsExtService);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,4 +537,5 @@
|
||||
<include file="parts/0467_add_welcome_kit_return_tracking.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0468_add_address_id_to_welcome_kit_dispatch.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0469_create_database_export_request.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0470_create_loan_product_cbs_ext.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
+377
@@ -0,0 +1,377 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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">
|
||||
|
||||
<!-- The legacy "Account Type Creation" screen carries a large block of product configuration that
|
||||
Fineract's own loan product schema has no home for - cheque book rules, channel and transaction
|
||||
limits, credit bureau account types, the older interest parameters, and a set of extra GL
|
||||
mappings. Those fields were being collected by the create/edit form and then dropped before the
|
||||
request was sent, so nothing survived a page reload.
|
||||
|
||||
They live in a satellite table keyed 1:1 on the loan product rather than as more columns on
|
||||
m_product_loan: the set is specific to this deployment, and keeping it separate means an upstream
|
||||
Fineract change to m_product_loan will never collide with it. Typed columns rather than a JSON
|
||||
blob because loan account creation reads these at origination time, so they need to be queryable
|
||||
and compile-checked, not string-keyed. -->
|
||||
<changeSet id="0470_create_loan_product_cbs_ext" author="CBS" runOnChange="false">
|
||||
<createTable tableName="m_product_loan_cbs_ext">
|
||||
<column name="loan_product_id" type="BIGINT">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
|
||||
<!-- classification & legacy header fields (24) -->
|
||||
<column name="product_type_group" type="VARCHAR(20)"/>
|
||||
<column name="product_type_sub_group" type="VARCHAR(30)"/>
|
||||
<column name="debit_int_calculation" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="separate_penal_interest" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="credit_int_calculation" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="sub_account_type_balance" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="final_int_rounding" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="rounding_up_to" type="INTEGER"/>
|
||||
<column name="account_type_code" type="VARCHAR(10)"/>
|
||||
<column name="micr_transaction_code" type="VARCHAR(100)"/>
|
||||
<column name="reserved_ecs_serial_number" type="VARCHAR(100)"/>
|
||||
<column name="reverse_ecs_number" type="VARCHAR(100)"/>
|
||||
<column name="lock_cheque_info_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="lock_page_two_info_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="computerization_date" type="DATE"/>
|
||||
<column name="cheque_print_description" type="VARCHAR(100)"/>
|
||||
<column name="pos_account_type_description" type="VARCHAR(100)"/>
|
||||
<column name="pfms_account_type" type="VARCHAR(100)"/>
|
||||
<column name="renewal_date_add_months" type="INTEGER"/>
|
||||
<column name="document_renewal_date_add_months" type="INTEGER"/>
|
||||
<column name="pps_limit" type="DECIMAL(19,6)"/>
|
||||
<column name="is_write_off_account_type" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="write_off_account_type_code" type="VARCHAR(100)"/>
|
||||
<column name="renewal_grace_days" type="INTEGER"/>
|
||||
|
||||
<!-- Cheque Book Settings (10) -->
|
||||
<column name="cheque_book_issue_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="cheque_validation_required" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="is_first_cheque_book_free" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="cheque_printing_account_type" type="VARCHAR(30)"/>
|
||||
<column name="allow_withdrawal_slip_usage" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="maintain_cheque_book_stock_registry" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="free_cheque_books_per_year" type="DECIMAL(19,6)"/>
|
||||
<column name="allow_credit_by_cheque_number" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="credit_cheque_validation_required" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="grace_days_for_stock_statement" type="INTEGER"/>
|
||||
|
||||
<!-- Additional Product Settings (37) -->
|
||||
<column name="account_type_active_for_transactions" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="sub_type_activity_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="account_opening_charges" type="INTEGER"/>
|
||||
<column name="maximum_gold_loan_limit" type="DECIMAL(19,6)"/>
|
||||
<column name="last_account_number_opened" type="VARCHAR(100)"/>
|
||||
<column name="customer_termination_allowed" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="charges_for_cash_credit_above_limit" type="DECIMAL(19,6)"/>
|
||||
<column name="death_interest_gl_account" type="VARCHAR(100)"/>
|
||||
<column name="starting_ledger_number" type="INTEGER"/>
|
||||
<column name="ending_ledger_number" type="INTEGER"/>
|
||||
<column name="current_ledger_number" type="INTEGER"/>
|
||||
<column name="remittance_account_number" type="VARCHAR(100)"/>
|
||||
<column name="is_non_resident_indian_account" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="debit_clearing_gl_account" type="VARCHAR(100)"/>
|
||||
<column name="missed_call_alert_service_active" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="standing_instruction_charge_gl_account" type="VARCHAR(100)"/>
|
||||
<column name="standing_instruction_debit_charge_skip_option" type="VARCHAR(50)"/>
|
||||
<column name="opening_balance_multiplier_for_remittance_charges" type="DECIMAL(19,6)"/>
|
||||
<column name="gold_loan_packet_number_with_year_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="account_move_to_inoperative_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="generate_gl_diff_entry_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="sub_type_wise_gl_balance_generation_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="validate_before_deleting_debit_entry_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="rc_file_concept_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="account_close_zero_balance_in_open_day_process" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="account_close_zero_balance_at_subledger_tran_entry" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="limit_enhancement_against_clearing_screen_display_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="advance_interest_parameter_in_ledger_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="vehicle_detail_in_master_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="deleted_cheque_issue_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="dp_reduce_in_document_renewal_date_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="dp_reduce_in_renewal_date_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="auto_close_at_day_end_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="loan_rate_from_master_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="cheque_short_name" type="VARCHAR(100)"/>
|
||||
<column name="statement_print_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="nesl_code" type="VARCHAR(100)"/>
|
||||
|
||||
<!-- Interest Related Parameters (53) -->
|
||||
<column name="drawing_power_and_limit_generation_procedure" type="VARCHAR(100)"/>
|
||||
<column name="advances_interest_calculation_method" type="VARCHAR(100)"/>
|
||||
<column name="against_interest_calculation_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="day_wise_against_clearing_interest_rounding" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="interest_calculation_one_fourth_method" type="VARCHAR(20)"/>
|
||||
<column name="against_clearing_interest_procedure_type" type="VARCHAR(50)"/>
|
||||
<column name="consider_debit_closing_amount_for_against_clearing" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="interest_rounding_method" type="VARCHAR(30)"/>
|
||||
<column name="penalty_interest_calculation_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="penalty_interest_calculation_method" type="VARCHAR(30)"/>
|
||||
<column name="penalty_interest_procedure_number" type="VARCHAR(100)"/>
|
||||
<column name="overdrawn_interest_calculation_method" type="VARCHAR(50)"/>
|
||||
<column name="calculate_overdrawn_interest_after_renewal" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="interest_on_credit_balance" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="penalty_interest_date_different_than_regular_interest" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="fixed_deposit_overdraft_certificate_sort_order" type="VARCHAR(50)"/>
|
||||
<column name="use_document_submission_date_for_interest" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="loan_management_system_renewal_penalty_active" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="minimum_normal_interest_amount" type="DECIMAL(19,6)"/>
|
||||
<column name="minimum_interest_calculation_method" type="VARCHAR(50)"/>
|
||||
<column name="minimum_against_clearing_interest_amount" type="DECIMAL(19,6)"/>
|
||||
<column name="limit_increase_upto_interest_amount_in_interest_calculation" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="minimum_penalty_interest_amount" type="DECIMAL(19,6)"/>
|
||||
<column name="days_for_limit_increase_upto_interest_amount" type="INTEGER"/>
|
||||
<column name="additional_interest_rate_for_fixed_deposit_overdraft" type="DECIMAL(19,6)"/>
|
||||
<column name="consider_dd_payorder_in_against_clearing_interest_calculation" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="grace_days_after_renew_date" type="INTEGER"/>
|
||||
<column name="apply_undebited_interest_concept_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="interest_register_print_format_type" type="VARCHAR(50)"/>
|
||||
<column name="normal_grace_days_after_overdue" type="INTEGER"/>
|
||||
<column name="allow_against_clearing_entry" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="allow_no_balance_entry" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="fd_od_penalty_interest_combined_with_normal_interest" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="allow_no_balance_entry_with_password" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="undebited_simple_interest_account_wise" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="daily_interest_calculation_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="daily_interest_calculation_start_date" type="VARCHAR(100)"/>
|
||||
<column name="non_performing_asset_penal_interest_rate_update" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="non_performing_asset_penal_interest_rate" type="DECIMAL(19,6)"/>
|
||||
<column name="fd_od_penal_interest_rate_update_in_branch_process" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="add_penal_interest_rate" type="DECIMAL(19,6)"/>
|
||||
<column name="atyp14_simple_interest_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="fixed_deposit_overdraft_margin_type" type="VARCHAR(100)"/>
|
||||
<column name="check_master_detail_edited_passing_pending_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="credit_debit_interest_calculation_separate_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="on_time_interest_provision_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="check_against_clearing_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="gst_on_penalty_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="penalty_interest_grace_days" type="INTEGER"/>
|
||||
<column name="overdrawn_interest_rate" type="DECIMAL(19,6)"/>
|
||||
<column name="calculate_daily_limit_enhancement_tod_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="fixed_deposit_overdraft_multiple_interest_rate_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="grace_days_after_overdue_for_moratorium" type="INTEGER"/>
|
||||
|
||||
<!-- Credit Bureau Settings (CIBIL) (8) -->
|
||||
<column name="cibil_account_type" type="VARCHAR(100)"/>
|
||||
<column name="cibil_commercial_account_type" type="VARCHAR(100)"/>
|
||||
<column name="highmark_account_type" type="VARCHAR(100)"/>
|
||||
<column name="highmark_commercial_account_type" type="VARCHAR(100)"/>
|
||||
<column name="experian_account_type" type="VARCHAR(100)"/>
|
||||
<column name="experian_commercial_account_type" type="VARCHAR(100)"/>
|
||||
<column name="equifax_account_type" type="VARCHAR(100)"/>
|
||||
<column name="equifax_commercial_account_type" type="VARCHAR(100)"/>
|
||||
|
||||
<!-- RBI Compliance & Product Category (6) -->
|
||||
<column name="loan_product_category" type="VARCHAR(30)"/>
|
||||
<column name="penal_charge_method" type="VARCHAR(50)"/>
|
||||
<column name="is_floating_rate" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="foreclosure_charges_applicable" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="key_fact_statement_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="annual_percentage_rate_calculation_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
|
||||
<!-- Channel & Transaction Limits (23) -->
|
||||
<column name="is_mobile_app_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="is_atm_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="atm_yearly_charge_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="atm_minimum_balance" type="DECIMAL(19,6)"/>
|
||||
<column name="email_active_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="is_imps_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="is_upi_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="is_pos_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="is_bbps_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="inter_bank_limit_per_day" type="DECIMAL(19,6)"/>
|
||||
<column name="inter_bank_limit_per_transaction" type="DECIMAL(19,6)"/>
|
||||
<column name="neft_rtgs_limit_per_day" type="DECIMAL(19,6)"/>
|
||||
<column name="neft_rtgs_limit_per_transaction" type="DECIMAL(19,6)"/>
|
||||
<column name="neft_cutoff_limit" type="DECIMAL(19,6)"/>
|
||||
<column name="rtgs_cutoff_limit" type="DECIMAL(19,6)"/>
|
||||
<column name="neft_rtgs_minimum_balance" type="DECIMAL(19,6)"/>
|
||||
<column name="is_charge_required_neft_rtgs_cbs" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="is_charge_required_neft_rtgs_mobile" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="imps_limit_per_day" type="DECIMAL(19,6)"/>
|
||||
<column name="imps_limit_per_transaction" type="DECIMAL(19,6)"/>
|
||||
<column name="imps_limit_per_month" type="DECIMAL(19,6)"/>
|
||||
<column name="imps_min_limit" type="DECIMAL(19,6)"/>
|
||||
<column name="imps_monthly_transaction_count" type="INTEGER"/>
|
||||
|
||||
<!-- POS Facility & ATM CSV Settings (10) -->
|
||||
<column name="max_per_transaction_limit_atm" type="DECIMAL(19,6)"/>
|
||||
<column name="max_day_transaction_limit_atm" type="DECIMAL(19,6)"/>
|
||||
<column name="max_per_transaction_limit_pos" type="DECIMAL(19,6)"/>
|
||||
<column name="max_day_transaction_limit_pos" type="DECIMAL(19,6)"/>
|
||||
<column name="max_per_transaction_limit_ecom" type="DECIMAL(19,6)"/>
|
||||
<column name="max_day_transaction_limit_ecom" type="DECIMAL(19,6)"/>
|
||||
<column name="max_per_transaction_limit_upi" type="DECIMAL(19,6)"/>
|
||||
<column name="max_day_transaction_limit_upi" type="DECIMAL(19,6)"/>
|
||||
<column name="atm_csv_product_code" type="VARCHAR(100)"/>
|
||||
<column name="atm_csv_type_code" type="VARCHAR(100)"/>
|
||||
|
||||
<!-- Auto Interest Post Parameters (4) -->
|
||||
<column name="auto_interest_post_type" type="VARCHAR(30)"/>
|
||||
<column name="auto_interest_post_when" type="VARCHAR(20)"/>
|
||||
<column name="auto_interest_post_fix_day" type="INTEGER"/>
|
||||
<column name="auto_last_interest_date" type="VARCHAR(100)"/>
|
||||
|
||||
<!-- Foreclosure / Early Account Closure (3) -->
|
||||
<column name="calculate_early_account_close_charge" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="early_account_close_charge" type="INTEGER"/>
|
||||
<column name="early_account_close_period_in_months" type="INTEGER"/>
|
||||
|
||||
<!-- Terms step (3) -->
|
||||
<column name="debit_balance_allow" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="allow_debit_trans_after_due_date" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="branch_level_account_type" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
|
||||
<!-- legacy cheque / standing instruction / minimum balance charges (24) -->
|
||||
<column name="cheque_book_charge_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="cheque_return_charge_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="ic_charge_debit_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="cash_bundle_charge_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="cash_bundle_charge_with_pan_limit" type="DECIMAL(19,6)"/>
|
||||
<column name="per_cheque_entry_charge" type="DECIMAL(19,6)"/>
|
||||
<column name="per_cheque_entry_service_charge" type="DECIMAL(19,6)"/>
|
||||
<column name="per_inward_cheque_entry_charge" type="DECIMAL(19,6)"/>
|
||||
<column name="per_outward_cheque_entry_charge" type="DECIMAL(19,6)"/>
|
||||
<column name="creditor_standing_instruction_fail_charge" type="DECIMAL(19,6)"/>
|
||||
<column name="debtor_standing_instruction_fail_charge" type="DECIMAL(19,6)"/>
|
||||
<column name="minimum_balance_checking_type" type="VARCHAR(20)"/>
|
||||
<column name="auto_minimum_balance_charge" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="calculate_daily_minimum_balance_charges" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="minimum_balance_charge_enabled" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="minimum_balance_charge_amount" type="DECIMAL(19,6)"/>
|
||||
<column name="minimum_balance_charge_for_cheque_issue" type="DECIMAL(19,6)"/>
|
||||
<column name="minimum_balance_charge_method" type="VARCHAR(20)"/>
|
||||
<column name="months_after_min_balance_charge_calculate" type="INTEGER"/>
|
||||
<column name="for_cheque_issue" type="DECIMAL(19,6)"/>
|
||||
<column name="for_cheque_issue_avg" type="DECIMAL(19,6)"/>
|
||||
<column name="for_withdrawal_slip" type="DECIMAL(19,6)"/>
|
||||
<column name="for_withdrawal_slip_avg" type="DECIMAL(19,6)"/>
|
||||
<column name="calculate_daily_against_clearing_charge" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
|
||||
<!-- custom GL account mappings (14) -->
|
||||
<column name="int_receivables_gl_account_id" type="BIGINT"/>
|
||||
<column name="int_payable_gl_account_id" type="BIGINT"/>
|
||||
<column name="deaf_int_payable_gl_account_id" type="BIGINT"/>
|
||||
<column name="int_overdue_reserve_account_id" type="BIGINT"/>
|
||||
<column name="undebited_interest_account_id" type="BIGINT"/>
|
||||
<column name="penal_int_cr_gl_account_id" type="BIGINT"/>
|
||||
<column name="rd_matured_gl_account_id" type="BIGINT"/>
|
||||
<column name="gl_account_id" type="BIGINT"/>
|
||||
<column name="ic_charge_gl_account_id" type="BIGINT"/>
|
||||
<column name="inoperative_gl_account_id" type="BIGINT"/>
|
||||
<column name="credit_balance_liability_gl_account_id" type="BIGINT"/>
|
||||
<column name="credit_balance_asset_gl_account_id" type="BIGINT"/>
|
||||
<column name="overdue_accounts_gl_account_id" type="BIGINT"/>
|
||||
<column name="rebate_gl_account_id" type="BIGINT"/>
|
||||
</createTable>
|
||||
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="loan_product_id"
|
||||
constraintName="fk_mplce_loan_product"
|
||||
referencedTableName="m_product_loan" referencedColumnNames="id"
|
||||
onDelete="CASCADE"/>
|
||||
</changeSet>
|
||||
|
||||
<!-- The extra GL mappings hold real account ids, so they are constrained rather than left as loose
|
||||
numbers: deleting a GL account that a product still points at should fail, not leave the product
|
||||
holding a dangling id. -->
|
||||
<changeSet id="0470_loan_product_cbs_ext_gl_fks" author="CBS" runOnChange="false">
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="int_receivables_gl_account_id"
|
||||
constraintName="fk_mplce_int_receivables"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="int_payable_gl_account_id"
|
||||
constraintName="fk_mplce_int_payable"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="deaf_int_payable_gl_account_id"
|
||||
constraintName="fk_mplce_deaf_int_payable"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="int_overdue_reserve_account_id"
|
||||
constraintName="fk_mplce_int_overdue_reserve"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="undebited_interest_account_id"
|
||||
constraintName="fk_mplce_undebited_interest"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="penal_int_cr_gl_account_id"
|
||||
constraintName="fk_mplce_penal_int_cr"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="rd_matured_gl_account_id"
|
||||
constraintName="fk_mplce_rd_matured"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="gl_account_id"
|
||||
constraintName="fk_mplce_gl"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="ic_charge_gl_account_id"
|
||||
constraintName="fk_mplce_ic_charge"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="inoperative_gl_account_id"
|
||||
constraintName="fk_mplce_inoperative"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="credit_balance_liability_gl_account_id"
|
||||
constraintName="fk_mplce_credit_balance_liability"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="credit_balance_asset_gl_account_id"
|
||||
constraintName="fk_mplce_credit_balance_asset"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="overdue_accounts_gl_account_id"
|
||||
constraintName="fk_mplce_overdue_accounts"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_ext" baseColumnNames="rebate_gl_account_id"
|
||||
constraintName="fk_mplce_rebate"
|
||||
referencedTableName="acc_gl_account" referencedColumnNames="id"/>
|
||||
</changeSet>
|
||||
|
||||
<!-- The legacy Interest Rate Detail grid: four fixed interest types, each with a Normal and a Special
|
||||
min/max rate plus a period. A child table rather than twenty-four flat columns because the
|
||||
interest type reads far better as data than as part of a column name
|
||||
(against_clearing_special_max_rate and friends). -->
|
||||
<changeSet id="0470_create_loan_product_cbs_interest_rate" author="CBS" runOnChange="false">
|
||||
<createTable tableName="m_product_loan_cbs_interest_rate">
|
||||
<column name="id" type="BIGSERIAL">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="loan_product_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<!-- Normal Debit | Normal Credit | Against Clearing | Penalty -->
|
||||
<column name="interest_type" type="VARCHAR(30)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="calculation" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="normal_min_rate" type="DECIMAL(9,6)"/>
|
||||
<column name="normal_max_rate" type="DECIMAL(9,6)"/>
|
||||
<column name="special_min_rate" type="DECIMAL(9,6)"/>
|
||||
<column name="special_max_rate" type="DECIMAL(9,6)"/>
|
||||
<!-- DAILY | MONTHLY | QUARTERLY | HALF YEARLY | YEARLY -->
|
||||
<column name="period" type="VARCHAR(20)"/>
|
||||
</createTable>
|
||||
|
||||
<addForeignKeyConstraint baseTableName="m_product_loan_cbs_interest_rate" baseColumnNames="loan_product_id"
|
||||
constraintName="fk_mplcir_loan_product"
|
||||
referencedTableName="m_product_loan" referencedColumnNames="id"
|
||||
onDelete="CASCADE"/>
|
||||
|
||||
<!-- One row per interest type per product; the grid is fixed, so this also stops a replayed
|
||||
save from doubling the rows. -->
|
||||
<addUniqueConstraint tableName="m_product_loan_cbs_interest_rate"
|
||||
columnNames="loan_product_id, interest_type"
|
||||
constraintName="mplcir_unq_product_interest_type"/>
|
||||
</changeSet>
|
||||
|
||||
<!-- Both of these are money, not counts, and were created as INTEGER by mistake - a charge of 250.75
|
||||
was rejected outright. Kept as a follow-on changeset rather than a correction to the two above,
|
||||
which have already run and whose checksums must not change. -->
|
||||
<changeSet id="0470_fix_charge_column_types" author="CBS" runOnChange="false">
|
||||
<modifyDataType tableName="m_product_loan_cbs_ext" columnName="account_opening_charges"
|
||||
newDataType="DECIMAL(19,6)"/>
|
||||
<modifyDataType tableName="m_product_loan_cbs_ext" columnName="early_account_close_charge"
|
||||
newDataType="DECIMAL(19,6)"/>
|
||||
</changeSet>
|
||||
|
||||
<!-- A count of cheque books, not an amount. Created as DECIMAL by the same name-based type guess
|
||||
that got the two charges above wrong, and stored "3.000000" for three books. -->
|
||||
<changeSet id="0470_free_cheque_books_is_a_count" author="CBS" runOnChange="false">
|
||||
<modifyDataType tableName="m_product_loan_cbs_ext" columnName="free_cheque_books_per_year"
|
||||
newDataType="INTEGER"/>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
Reference in New Issue
Block a user