current account saving account ,rd account code udpate
This commit is contained in:
+2
@@ -459,6 +459,8 @@ public final class DepositsApiConstants {
|
||||
// CBS product fields — included in template response when productId is provided
|
||||
recurringDepositResponseData.add("accountType");
|
||||
recurringDepositResponseData.add("customerSegment");
|
||||
recurringDepositResponseData.add("accountTypeOptions");
|
||||
recurringDepositResponseData.add("customerSegmentOptions");
|
||||
recurringDepositResponseData.add("productCode");
|
||||
recurringDepositResponseData.add(SavingsApiConstants.glAccountIdParamName);
|
||||
recurringDepositResponseData.add("glAccountName");
|
||||
|
||||
+27
@@ -281,4 +281,31 @@ public class SavingsApiConstants {
|
||||
public static final String avgBalanceCalcPeriodParamName = "avgBalanceCalcPeriod";
|
||||
public static final String validForPeriodParamName = "validForPeriod";
|
||||
public static final String odAccountClosedZeroBalanceInDayClosingParamName = "odAccountClosedZeroBalanceInDayClosing";
|
||||
|
||||
// Status of Account fields
|
||||
public static final String accountStatusParamName = "accountStatus";
|
||||
public static final String modeOfOperationParamName = "modeOfOperation";
|
||||
public static final String guardianClientIdParamName = "guardianClientId";
|
||||
public static final String specialCategoryParamName = "specialCategory";
|
||||
public static final String weakerSectionParamName = "weakerSection";
|
||||
public static final String guardianNameParamName = "guardianName";
|
||||
public static final String guardianCifNumberParamName = "guardianCifNumber";
|
||||
public static final String guardianRelationshipParamName = "guardianRelationship";
|
||||
public static final String minorDateOfBirthParamName = "minorDateOfBirth";
|
||||
|
||||
// Introducer fields
|
||||
public static final String introducerIdParamName = "introducerId";
|
||||
public static final String introducerNameParamName = "introducerName";
|
||||
public static final String introducerCifNumberParamName = "introducerCifNumber";
|
||||
|
||||
// Joint holders
|
||||
public static final String jointHoldersParamName = "jointHolders";
|
||||
|
||||
// Nominee
|
||||
public static final String nomineeParamName = "nominee";
|
||||
|
||||
// Deposit Account Link (DAL)
|
||||
public static final String linkedAccountIdParamName = "linkedAccountId";
|
||||
public static final String linkedAccountTypeParamName = "linkedAccountType";
|
||||
public static final String linkedAccountNoParamName = "linkedAccountNo";
|
||||
}
|
||||
|
||||
+266
-21
@@ -33,6 +33,7 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.infrastructure.core.jersey.serializer.legacy.JsonLocalDateArrayFormat;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
|
||||
@@ -125,9 +126,31 @@ public final class SavingsAccountData implements Serializable {
|
||||
|
||||
private List<DatatableData> datatables = null;
|
||||
|
||||
// CBS Account fields (saved per account)
|
||||
private String cbsAccountType;
|
||||
private String accountStatus;
|
||||
private String modeOfOperation;
|
||||
private String specialCategory;
|
||||
private String weakerSection;
|
||||
private String guardianName;
|
||||
private String guardianCifNumber;
|
||||
private String guardianRelationship;
|
||||
private LocalDate minorDateOfBirth;
|
||||
private Long guardianClientId;
|
||||
private Long introducerClientId;
|
||||
private String introducerName;
|
||||
private String introducerCifNumber;
|
||||
private Map<String, Object> nomineeData;
|
||||
private Long linkedAccountId;
|
||||
private String linkedAccountType;
|
||||
private String linkedAccountNo;
|
||||
private List<java.util.Map<String, Object>> jointHolders;
|
||||
|
||||
// CBS Product fields (populated in template response from selected product)
|
||||
private String accountType;
|
||||
private String customerSegment;
|
||||
private Collection<CodeValueData> accountTypeOptions;
|
||||
private Collection<CodeValueData> customerSegmentOptions;
|
||||
private String productCode;
|
||||
private LocalDate effectiveDate;
|
||||
private LocalDate effectiveTo;
|
||||
@@ -728,37 +751,41 @@ public final class SavingsAccountData implements Serializable {
|
||||
public static SavingsAccountData withTemplateOptions(final SavingsAccountData account, final SavingsAccountData template,
|
||||
final Collection<SavingsAccountTransactionData> transactions, final Collection<SavingsAccountChargeData> charges) {
|
||||
|
||||
if (template == null) {
|
||||
final Collection<SavingsProductData> productOptions = null;
|
||||
final Collection<StaffData> fieldOfficerOptions = null;
|
||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
|
||||
final Collection<ChargeData> chargeOptions = null;
|
||||
final Collection<SavingsProductData> productOptions = template == null ? null : template.productOptions;
|
||||
final Collection<StaffData> fieldOfficerOptions = template == null ? null : template.fieldOfficerOptions;
|
||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = template == null ? null
|
||||
: template.interestCompoundingPeriodTypeOptions;
|
||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = template == null ? null
|
||||
: template.interestPostingPeriodTypeOptions;
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = template == null ? null
|
||||
: template.interestCalculationTypeOptions;
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = template == null ? null
|
||||
: template.interestCalculationDaysInYearTypeOptions;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = template == null ? null
|
||||
: template.lockinPeriodFrequencyTypeOptions;
|
||||
final Collection<EnumOptionData> withdrawalFeeTypeOptions = template == null ? null
|
||||
: template.withdrawalFeeTypeOptions;
|
||||
final Collection<ChargeData> chargeOptions = template == null ? null : template.chargeOptions;
|
||||
|
||||
return withTemplateOptions(account, productOptions, fieldOfficerOptions, interestCompoundingPeriodTypeOptions,
|
||||
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions, charges, chargeOptions);
|
||||
}
|
||||
|
||||
return new SavingsAccountData(account.id, account.accountNo, account.depositType, account.externalId, account.groupId,
|
||||
final SavingsAccountData result = new SavingsAccountData(account.id, account.accountNo, account.depositType, account.externalId,
|
||||
account.groupId,
|
||||
account.groupName, account.clientId, account.clientName, account.savingsProductId, account.savingsProductName,
|
||||
account.fieldOfficerId, account.fieldOfficerName, account.status, account.subStatus, account.reasonForBlock,
|
||||
account.timeline, account.currency, account.nominalAnnualInterestRate, account.interestCompoundingPeriodType,
|
||||
account.interestPostingPeriodType, account.interestCalculationType, account.interestCalculationDaysInYearType,
|
||||
account.minRequiredOpeningBalance, account.lockinPeriodFrequency, account.lockinPeriodFrequencyType,
|
||||
account.withdrawalFeeForTransfers, account.summary, transactions, template.productOptions, template.fieldOfficerOptions,
|
||||
template.interestCompoundingPeriodTypeOptions, template.interestPostingPeriodTypeOptions,
|
||||
template.interestCalculationTypeOptions, template.interestCalculationDaysInYearTypeOptions,
|
||||
template.lockinPeriodFrequencyTypeOptions, template.withdrawalFeeTypeOptions, charges, template.chargeOptions,
|
||||
account.withdrawalFeeForTransfers, account.summary, transactions, productOptions, fieldOfficerOptions,
|
||||
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, charges, chargeOptions,
|
||||
account.allowOverdraft, account.overdraftLimit, account.minRequiredBalance, account.enforceMinRequiredBalance,
|
||||
account.maxAllowedLienLimit, account.lienAllowed, account.minBalanceForInterestCalculation, account.onHoldFunds,
|
||||
account.nominalAnnualInterestRateOverdraft, account.minOverdraftForInterestCalculation, account.withHoldTax,
|
||||
account.taxGroup, account.lastActiveTransactionDate, account.isDormancyTrackingActive, account.daysToInactive,
|
||||
account.daysToDormancy, account.daysToEscheat, account.savingsAmountOnHold);
|
||||
copyPresentationFields(result, template);
|
||||
copyPresentationFields(result, account);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static SavingsAccountData withTemplateOptions(final SavingsAccountData account,
|
||||
@@ -771,7 +798,8 @@ public final class SavingsAccountData implements Serializable {
|
||||
final Collection<SavingsAccountTransactionData> transactions, final Collection<SavingsAccountChargeData> charges,
|
||||
final Collection<ChargeData> chargeOptions) {
|
||||
|
||||
return new SavingsAccountData(account.id, account.accountNo, account.depositType, account.externalId, account.groupId,
|
||||
final SavingsAccountData result = new SavingsAccountData(account.id, account.accountNo, account.depositType, account.externalId,
|
||||
account.groupId,
|
||||
account.groupName, account.clientId, account.clientName, account.savingsProductId, account.savingsProductName,
|
||||
account.fieldOfficerId, account.fieldOfficerName, account.status, account.subStatus, account.reasonForBlock,
|
||||
account.timeline, account.currency, account.nominalAnnualInterestRate, account.interestCompoundingPeriodType,
|
||||
@@ -786,6 +814,223 @@ public final class SavingsAccountData implements Serializable {
|
||||
account.minOverdraftForInterestCalculation, account.withHoldTax, account.taxGroup, account.lastActiveTransactionDate,
|
||||
account.isDormancyTrackingActive, account.daysToInactive, account.daysToDormancy, account.daysToEscheat,
|
||||
account.savingsAmountOnHold);
|
||||
copyPresentationFields(result, account);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void copyPresentationFields(final SavingsAccountData target, final SavingsAccountData source) {
|
||||
if (source == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (source.previewAccountNo != null) {
|
||||
target.setPreviewAccountNo(source.previewAccountNo);
|
||||
}
|
||||
if (source.cbsAccountType != null) {
|
||||
target.setCbsAccountType(source.cbsAccountType);
|
||||
}
|
||||
if (source.customerSegment != null) {
|
||||
target.setCustomerSegment(source.customerSegment);
|
||||
}
|
||||
if (source.accountStatus != null) {
|
||||
target.setAccountStatus(source.accountStatus);
|
||||
}
|
||||
if (source.modeOfOperation != null) {
|
||||
target.setModeOfOperation(source.modeOfOperation);
|
||||
}
|
||||
if (source.specialCategory != null) {
|
||||
target.setSpecialCategory(source.specialCategory);
|
||||
}
|
||||
if (source.weakerSection != null) {
|
||||
target.setWeakerSection(source.weakerSection);
|
||||
}
|
||||
if (source.guardianName != null) {
|
||||
target.setGuardianName(source.guardianName);
|
||||
}
|
||||
if (source.guardianCifNumber != null) {
|
||||
target.setGuardianCifNumber(source.guardianCifNumber);
|
||||
}
|
||||
if (source.guardianRelationship != null) {
|
||||
target.setGuardianRelationship(source.guardianRelationship);
|
||||
}
|
||||
if (source.minorDateOfBirth != null) {
|
||||
target.setMinorDateOfBirth(source.minorDateOfBirth);
|
||||
}
|
||||
if (source.guardianClientId != null) {
|
||||
target.setGuardianClientId(source.guardianClientId);
|
||||
}
|
||||
if (source.introducerClientId != null) {
|
||||
target.setIntroducerClientId(source.introducerClientId);
|
||||
}
|
||||
if (source.introducerName != null) {
|
||||
target.setIntroducerName(source.introducerName);
|
||||
}
|
||||
if (source.introducerCifNumber != null) {
|
||||
target.setIntroducerCifNumber(source.introducerCifNumber);
|
||||
}
|
||||
if (source.nomineeData != null) {
|
||||
target.setNomineeData(source.nomineeData);
|
||||
}
|
||||
if (source.linkedAccountId != null) {
|
||||
target.setLinkedAccountId(source.linkedAccountId);
|
||||
}
|
||||
if (source.linkedAccountType != null) {
|
||||
target.setLinkedAccountType(source.linkedAccountType);
|
||||
}
|
||||
if (source.linkedAccountNo != null) {
|
||||
target.setLinkedAccountNo(source.linkedAccountNo);
|
||||
}
|
||||
if (source.jointHolders != null) {
|
||||
target.setJointHolders(new ArrayList<>(source.jointHolders));
|
||||
}
|
||||
|
||||
if (source.accountType != null) {
|
||||
target.setAccountType(source.accountType);
|
||||
}
|
||||
if (source.customerSegmentOptions != null) {
|
||||
target.setCustomerSegmentOptions(source.customerSegmentOptions);
|
||||
}
|
||||
if (source.accountTypeOptions != null) {
|
||||
target.setAccountTypeOptions(source.accountTypeOptions);
|
||||
}
|
||||
if (source.productCode != null) {
|
||||
target.setProductCode(source.productCode);
|
||||
}
|
||||
if (source.effectiveDate != null) {
|
||||
target.setEffectiveDate(source.effectiveDate);
|
||||
}
|
||||
if (source.effectiveTo != null) {
|
||||
target.setEffectiveTo(source.effectiveTo);
|
||||
}
|
||||
if (source.endDate != null) {
|
||||
target.setEndDate(source.endDate);
|
||||
}
|
||||
if (source.introducerRequired != null) {
|
||||
target.setIntroducerRequired(source.introducerRequired);
|
||||
}
|
||||
if (source.shareLinkingEnabled != null) {
|
||||
target.setShareLinkingEnabled(source.shareLinkingEnabled);
|
||||
}
|
||||
if (source.nominationFacility != null) {
|
||||
target.setNominationFacility(source.nominationFacility);
|
||||
}
|
||||
if (source.dormancyAlert != null) {
|
||||
target.setDormancyAlert(source.dormancyAlert);
|
||||
}
|
||||
if (source.isDormancyTrackingActiveFromProduct != null) {
|
||||
target.setIsDormancyTrackingActiveFromProduct(source.isDormancyTrackingActiveFromProduct);
|
||||
}
|
||||
if (source.daysToInactiveFromProduct != null) {
|
||||
target.setDaysToInactiveFromProduct(source.daysToInactiveFromProduct);
|
||||
}
|
||||
if (source.daysToDormancyFromProduct != null) {
|
||||
target.setDaysToDormancyFromProduct(source.daysToDormancyFromProduct);
|
||||
}
|
||||
if (source.daysToEscheatFromProduct != null) {
|
||||
target.setDaysToEscheatFromProduct(source.daysToEscheatFromProduct);
|
||||
}
|
||||
if (source.interestCalculationTypeName != null) {
|
||||
target.setInterestCalculationTypeName(source.interestCalculationTypeName);
|
||||
}
|
||||
if (source.enableLockinPeriod != null) {
|
||||
target.setEnableLockinPeriod(source.enableLockinPeriod);
|
||||
}
|
||||
if (source.balanceFrequency != null) {
|
||||
target.setBalanceFrequency(source.balanceFrequency);
|
||||
}
|
||||
if (source.accountClosedZeroBalanceInDayClosing != null) {
|
||||
target.setAccountClosedZeroBalanceInDayClosing(source.accountClosedZeroBalanceInDayClosing);
|
||||
}
|
||||
if (source.balanceSwapOption != null) {
|
||||
target.setBalanceSwapOption(source.balanceSwapOption);
|
||||
}
|
||||
if (source.msme != null) {
|
||||
target.setMsme(source.msme);
|
||||
}
|
||||
if (source.autoDebitFacility != null) {
|
||||
target.setAutoDebitFacility(source.autoDebitFacility);
|
||||
}
|
||||
if (source.avgBalanceCalcPeriod != null) {
|
||||
target.setAvgBalanceCalcPeriod(source.avgBalanceCalcPeriod);
|
||||
}
|
||||
if (source.validForPeriod != null) {
|
||||
target.setValidForPeriod(source.validForPeriod);
|
||||
}
|
||||
if (source.odAccountClosedZeroBalanceInDayClosing != null) {
|
||||
target.setOdAccountClosedZeroBalanceInDayClosing(source.odAccountClosedZeroBalanceInDayClosing);
|
||||
}
|
||||
if (source.lastInterestDate != null) {
|
||||
target.setLastInterestDate(source.lastInterestDate);
|
||||
}
|
||||
if (source.accountFacilityConfig != null) {
|
||||
target.setAccountFacilityConfig(source.accountFacilityConfig);
|
||||
}
|
||||
if (source.accountFacilityLimits != null) {
|
||||
target.setAccountFacilityLimits(source.accountFacilityLimits);
|
||||
}
|
||||
if (source.depositLimitKyc != null) {
|
||||
target.setDepositLimitKyc(source.depositLimitKyc);
|
||||
}
|
||||
if (source.interestCalculateSelector != null) {
|
||||
target.setInterestCalculateSelector(source.interestCalculateSelector);
|
||||
}
|
||||
if (source.averagePeriod != null) {
|
||||
target.setAveragePeriod(source.averagePeriod);
|
||||
}
|
||||
if (source.autoPost != null) {
|
||||
target.setAutoPost(source.autoPost);
|
||||
}
|
||||
if (source.frequencyFixDay != null) {
|
||||
target.setFrequencyFixDay(source.frequencyFixDay);
|
||||
}
|
||||
if (source.interestCalculationTypeOption != null) {
|
||||
target.setInterestCalculationTypeOption(source.interestCalculationTypeOption);
|
||||
}
|
||||
if (source.periodFrequencyOptions != null) {
|
||||
target.setPeriodFrequencyOptions(source.periodFrequencyOptions);
|
||||
}
|
||||
if (source.productId != null) {
|
||||
target.setProductId(source.productId);
|
||||
}
|
||||
if (source.locale != null) {
|
||||
target.setLocale(source.locale);
|
||||
}
|
||||
if (source.dateFormat != null) {
|
||||
target.setDateFormat(source.dateFormat);
|
||||
}
|
||||
if (source.rowIndex != null) {
|
||||
target.setRowIndex(source.rowIndex);
|
||||
}
|
||||
if (source.submittedOnDate != null) {
|
||||
target.setSubmittedOnDate(source.submittedOnDate);
|
||||
}
|
||||
if (source.startInterestCalculationDate != null) {
|
||||
target.setStartInterestCalculationDate(source.startInterestCalculationDate);
|
||||
}
|
||||
if (source.activatedOnDate != null) {
|
||||
target.setActivatedOnDate(source.activatedOnDate);
|
||||
}
|
||||
if (source.lockedInUntilDate != null) {
|
||||
target.setLockedInUntilDate(source.lockedInUntilDate);
|
||||
}
|
||||
if (source.officeId != null) {
|
||||
target.setOfficeId(source.officeId);
|
||||
}
|
||||
if (source.clientData != null) {
|
||||
target.setClientData(source.clientData);
|
||||
}
|
||||
if (source.groupGeneralData != null) {
|
||||
target.setGroupGeneralData(source.groupGeneralData);
|
||||
}
|
||||
if (source.savingsProductData != null) {
|
||||
target.setSavingsProduct(source.savingsProductData);
|
||||
}
|
||||
if (source.savingsAccountSummaryData != null) {
|
||||
target.setSavingsAccountSummaryData(source.savingsAccountSummaryData);
|
||||
}
|
||||
if (source.lastSavingsAccountTransaction != null) {
|
||||
target.setLastSavingsAccountTransaction(source.lastSavingsAccountTransaction);
|
||||
}
|
||||
}
|
||||
|
||||
public static SavingsAccountData withClientTemplate(final Long clientId, final String clientName, final Long groupId,
|
||||
|
||||
+386
@@ -0,0 +1,386 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentaccount.domain;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
import org.apache.fineract.organisation.staff.domain.Staff;
|
||||
import org.apache.fineract.portfolio.client.domain.Client;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_current_account")
|
||||
@Getter
|
||||
@Setter
|
||||
public class CurrentAccount extends AbstractAuditableCustom {
|
||||
|
||||
@Column(name = "account_no", nullable = false, length = 20, unique = true)
|
||||
private String accountNo;
|
||||
|
||||
@Column(name = "external_id", length = 100)
|
||||
private String externalId;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "client_id")
|
||||
private Client client;
|
||||
|
||||
// Store product_id as plain column to avoid cross-module EclipseLink entity dependency
|
||||
@Column(name = "product_id", nullable = false)
|
||||
private Long productId;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "office_id", nullable = false)
|
||||
private Office office;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "staff_id")
|
||||
private Staff staff;
|
||||
|
||||
// Status: 100=Submitted, 200=Approved, 300=Active, 400=Withdrawn, 500=Rejected, 600=Closed
|
||||
@Column(name = "status_enum", nullable = false)
|
||||
private Integer statusEnum = 100;
|
||||
|
||||
// SubStatus: 0=None, 100=Inactive, 200=Dormant, 300=Block, 400=BlockDebit, 500=BlockCredit
|
||||
@Column(name = "sub_status_enum", nullable = false)
|
||||
private Integer subStatusEnum = 0;
|
||||
|
||||
// 1=Individual, 2=Group, 3=JLG
|
||||
@Column(name = "account_type_enum", nullable = false)
|
||||
private Integer accountTypeEnum = 1;
|
||||
|
||||
// Lifecycle dates
|
||||
@Column(name = "submittedon_date")
|
||||
private LocalDate submittedOnDate;
|
||||
|
||||
@Column(name = "approvedon_date")
|
||||
private LocalDate approvedOnDate;
|
||||
|
||||
@Column(name = "activatedon_date")
|
||||
private LocalDate activatedOnDate;
|
||||
|
||||
@Column(name = "rejectedon_date")
|
||||
private LocalDate rejectedOnDate;
|
||||
|
||||
@Column(name = "withdrawnon_date")
|
||||
private LocalDate withdrawnOnDate;
|
||||
|
||||
@Column(name = "closedon_date")
|
||||
private LocalDate closedOnDate;
|
||||
|
||||
// Currency (copied from product at account creation)
|
||||
@Column(name = "currency_code", nullable = false, length = 3)
|
||||
private String currencyCode;
|
||||
|
||||
@Column(name = "currency_digits", nullable = false)
|
||||
private Integer currencyDigits;
|
||||
|
||||
@Column(name = "currency_multiplesof")
|
||||
private Integer currencyMultiplesOf;
|
||||
|
||||
// Interest
|
||||
@Column(name = "nominal_annual_interest_rate", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal nominalAnnualInterestRate = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "interest_compounding_period_enum", nullable = false)
|
||||
private Integer interestCompoundingPeriodEnum;
|
||||
|
||||
@Column(name = "interest_posting_period_enum", nullable = false)
|
||||
private Integer interestPostingPeriodEnum;
|
||||
|
||||
@Column(name = "interest_calculation_type_enum", nullable = false)
|
||||
private Integer interestCalculationTypeEnum;
|
||||
|
||||
@Column(name = "interest_calculation_days_in_year_type_enum", nullable = false)
|
||||
private Integer interestCalculationDaysInYearTypeEnum;
|
||||
|
||||
@Column(name = "min_balance_for_interest_calculation", precision = 19, scale = 6)
|
||||
private BigDecimal minBalanceForInterestCalculation;
|
||||
|
||||
@Column(name = "start_interest_calculation_date")
|
||||
private LocalDate startInterestCalculationDate;
|
||||
|
||||
@Column(name = "accrued_till_date")
|
||||
private LocalDate accruedTillDate;
|
||||
|
||||
@Column(name = "last_interest_calculation_date")
|
||||
private LocalDate lastInterestCalculationDate;
|
||||
|
||||
@Column(name = "last_closed_business_date")
|
||||
private LocalDate lastClosedBusinessDate;
|
||||
|
||||
// Tax
|
||||
@Column(name = "withhold_tax", nullable = false)
|
||||
private boolean withholdTax = false;
|
||||
|
||||
// Balance rules
|
||||
@Column(name = "min_required_opening_balance", precision = 19, scale = 6)
|
||||
private BigDecimal minRequiredOpeningBalance;
|
||||
|
||||
@Column(name = "lockin_period_frequency")
|
||||
private Integer lockinPeriodFrequency;
|
||||
|
||||
@Column(name = "lockin_period_frequency_enum")
|
||||
private Integer lockinPeriodFrequencyEnum;
|
||||
|
||||
@Column(name = "lockedin_until_date_derived")
|
||||
private LocalDate lockedInUntilDate;
|
||||
|
||||
@Column(name = "enforce_min_required_balance", nullable = false)
|
||||
private boolean enforceMinRequiredBalance = false;
|
||||
|
||||
@Column(name = "min_required_balance", precision = 19, scale = 6)
|
||||
private BigDecimal minRequiredBalance;
|
||||
|
||||
// Overdraft
|
||||
@Column(name = "allow_overdraft", nullable = false)
|
||||
private boolean allowOverdraft = false;
|
||||
|
||||
@Column(name = "overdraft_limit", precision = 19, scale = 6)
|
||||
private BigDecimal overdraftLimit;
|
||||
|
||||
@Column(name = "nominal_annual_interest_rate_overdraft", precision = 19, scale = 6)
|
||||
private BigDecimal nominalAnnualInterestRateOverdraft;
|
||||
|
||||
@Column(name = "min_overdraft_for_interest_calculation", precision = 19, scale = 6)
|
||||
private BigDecimal minOverdraftForInterestCalculation;
|
||||
|
||||
// Lien
|
||||
@Column(name = "is_lien_allowed", nullable = false)
|
||||
private boolean lienAllowed = false;
|
||||
|
||||
@Column(name = "max_allowed_lien_limit", precision = 19, scale = 6)
|
||||
private BigDecimal maxAllowedLienLimit;
|
||||
|
||||
@Column(name = "on_hold_funds_derived", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal onHoldFundsDerived = BigDecimal.ZERO;
|
||||
|
||||
// Running balance summary
|
||||
@Column(name = "account_balance_derived", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal accountBalanceDerived = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "total_deposits_derived", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal totalDepositsDerived = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "total_withdrawals_derived", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal totalWithdrawalsDerived = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "total_interest_earned_derived", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal totalInterestEarnedDerived = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "total_interest_posted_derived", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal totalInterestPostedDerived = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "total_overdraft_interest_derived", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal totalOverdraftInterestDerived = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "total_withhold_tax_derived", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal totalWithholdTaxDerived = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "total_savings_amount_on_hold", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal totalSavingsAmountOnHold = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "withdrawal_fee_for_transfer", nullable = false)
|
||||
private boolean withdrawalFeeForTransfer = false;
|
||||
|
||||
@Column(name = "reason_for_block", length = 500)
|
||||
private String reasonForBlock;
|
||||
|
||||
// Current-account-specific fields
|
||||
@Column(name = "msme", nullable = false)
|
||||
private boolean msme = false;
|
||||
|
||||
@Column(name = "auto_debit_facility", nullable = false)
|
||||
private boolean autoDebitFacility = false;
|
||||
|
||||
@Column(name = "balance_swap_option", nullable = false)
|
||||
private boolean balanceSwapOption = false;
|
||||
|
||||
@Column(name = "establishment_date")
|
||||
private LocalDate establishmentDate;
|
||||
|
||||
@Column(name = "start_operation_date")
|
||||
private LocalDate startOperationDate;
|
||||
|
||||
@Column(name = "is_non_individual_client", nullable = false)
|
||||
private boolean nonIndividualClient = false;
|
||||
|
||||
@Column(name = "signatory_rights", length = 100)
|
||||
private String signatoryRights;
|
||||
|
||||
// CBS classification
|
||||
@Column(name = "cbs_account_type", length = 100)
|
||||
private String cbsAccountType;
|
||||
|
||||
@Column(name = "customer_segment", length = 100)
|
||||
private String customerSegment;
|
||||
|
||||
@Column(name = "account_status", length = 50)
|
||||
private String accountStatus;
|
||||
|
||||
@Column(name = "mode_of_operation", length = 50)
|
||||
private String modeOfOperation;
|
||||
|
||||
@Column(name = "special_category", length = 100)
|
||||
private String specialCategory;
|
||||
|
||||
// Introducer
|
||||
@Column(name = "introducer_client_id")
|
||||
private Long introducerClientId;
|
||||
|
||||
@Column(name = "introducer_name", length = 200)
|
||||
private String introducerName;
|
||||
|
||||
@Column(name = "introducer_cif_number", length = 50)
|
||||
private String introducerCifNumber;
|
||||
|
||||
// Nominee JSON
|
||||
@Column(name = "nominee_data", columnDefinition = "TEXT")
|
||||
private String nomineeData;
|
||||
|
||||
// Interest calculation settings
|
||||
@Column(name = "interest_calculate_selector")
|
||||
private Integer interestCalculateSelector;
|
||||
|
||||
@Column(name = "average_period", length = 20)
|
||||
private String averagePeriod;
|
||||
|
||||
@Column(name = "auto_post", nullable = false)
|
||||
private boolean autoPost = false;
|
||||
|
||||
@Column(name = "frequency_fix_day")
|
||||
private Integer frequencyFixDay;
|
||||
|
||||
@Column(name = "enable_lockin_period", nullable = false)
|
||||
private boolean enableLockinPeriod = false;
|
||||
|
||||
@Column(name = "balance_frequency", length = 50)
|
||||
private String balanceFrequency;
|
||||
|
||||
@Column(name = "avg_balance_calc_period", length = 10)
|
||||
private String avgBalanceCalcPeriod;
|
||||
|
||||
// Relationships
|
||||
@OneToMany(mappedBy = "currentAccount", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
|
||||
private List<CurrentAccountTransaction> transactions = new ArrayList<>();
|
||||
|
||||
@OneToMany(mappedBy = "currentAccount", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
|
||||
private Set<CurrentAccountCharge> charges = new HashSet<>();
|
||||
|
||||
@OneToOne(mappedBy = "currentAccount", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
|
||||
private CurrentAccountFacilityConfig facilityConfig;
|
||||
|
||||
@OneToMany(mappedBy = "currentAccount", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
|
||||
private List<CurrentAccountJointHolder> jointHolders = new ArrayList<>();
|
||||
|
||||
@OneToMany(mappedBy = "currentAccount", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
|
||||
private List<CurrentAccountPartner> partners = new ArrayList<>();
|
||||
|
||||
@OneToMany(mappedBy = "currentAccount", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
|
||||
private List<CurrentAccountOfficerHistory> officerHistory = new ArrayList<>();
|
||||
|
||||
protected CurrentAccount() {}
|
||||
|
||||
public static CurrentAccount createNew(Client client, Long productId, Office office,
|
||||
Staff staff, String accountNo, LocalDate submittedOnDate, Integer accountTypeEnum,
|
||||
String currencyCode, Integer currencyDigits, Integer currencyMultiplesOf,
|
||||
BigDecimal nominalAnnualInterestRate, Integer interestCompoundingPeriodEnum,
|
||||
Integer interestPostingPeriodEnum, Integer interestCalculationTypeEnum,
|
||||
Integer interestCalculationDaysInYearTypeEnum, boolean allowOverdraft,
|
||||
BigDecimal overdraftLimit, boolean msme, boolean autoDebitFacility,
|
||||
boolean balanceSwapOption, String customerSegment, boolean autoPost,
|
||||
Integer interestCalculateSelector, String averagePeriod, String avgBalanceCalcPeriod) {
|
||||
CurrentAccount account = new CurrentAccount();
|
||||
account.client = client;
|
||||
account.productId = productId;
|
||||
account.office = office;
|
||||
account.staff = staff;
|
||||
account.accountNo = accountNo;
|
||||
account.submittedOnDate = submittedOnDate;
|
||||
account.statusEnum = 100;
|
||||
account.subStatusEnum = 0;
|
||||
account.accountTypeEnum = accountTypeEnum != null ? accountTypeEnum : 1;
|
||||
account.currencyCode = currencyCode;
|
||||
account.currencyDigits = currencyDigits;
|
||||
account.currencyMultiplesOf = currencyMultiplesOf;
|
||||
account.nominalAnnualInterestRate = nominalAnnualInterestRate != null ? nominalAnnualInterestRate : BigDecimal.ZERO;
|
||||
account.interestCompoundingPeriodEnum = interestCompoundingPeriodEnum;
|
||||
account.interestPostingPeriodEnum = interestPostingPeriodEnum;
|
||||
account.interestCalculationTypeEnum = interestCalculationTypeEnum;
|
||||
account.interestCalculationDaysInYearTypeEnum = interestCalculationDaysInYearTypeEnum;
|
||||
account.allowOverdraft = allowOverdraft;
|
||||
account.overdraftLimit = overdraftLimit;
|
||||
account.msme = msme;
|
||||
account.autoDebitFacility = autoDebitFacility;
|
||||
account.balanceSwapOption = balanceSwapOption;
|
||||
account.customerSegment = customerSegment;
|
||||
account.autoPost = autoPost;
|
||||
account.interestCalculateSelector = interestCalculateSelector;
|
||||
account.averagePeriod = averagePeriod;
|
||||
account.avgBalanceCalcPeriod = avgBalanceCalcPeriod;
|
||||
return account;
|
||||
}
|
||||
|
||||
public boolean isActive() { return this.statusEnum != null && this.statusEnum == 300; }
|
||||
public boolean isSubmittedAndPendingApproval() { return this.statusEnum != null && this.statusEnum == 100; }
|
||||
public boolean isApproved() { return this.statusEnum != null && this.statusEnum == 200; }
|
||||
public boolean isClosed() { return this.statusEnum != null && this.statusEnum == 600; }
|
||||
|
||||
public void updateAccountNo(String accountNo) { this.accountNo = accountNo; }
|
||||
|
||||
public void approve(LocalDate approvedOnDate) {
|
||||
this.statusEnum = 200;
|
||||
this.approvedOnDate = approvedOnDate;
|
||||
}
|
||||
|
||||
public void activate(LocalDate activatedOnDate) {
|
||||
this.statusEnum = 300;
|
||||
this.activatedOnDate = activatedOnDate;
|
||||
}
|
||||
|
||||
public void reject(LocalDate rejectedOnDate) {
|
||||
this.statusEnum = 500;
|
||||
this.rejectedOnDate = rejectedOnDate;
|
||||
}
|
||||
|
||||
public void withdraw(LocalDate withdrawnOnDate) {
|
||||
this.statusEnum = 400;
|
||||
this.withdrawnOnDate = withdrawnOnDate;
|
||||
}
|
||||
|
||||
public void close(LocalDate closedOnDate) {
|
||||
this.statusEnum = 600;
|
||||
this.closedOnDate = closedOnDate;
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentaccount.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 java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.portfolio.charge.domain.Charge;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_current_account_charge")
|
||||
@Getter
|
||||
@Setter
|
||||
public class CurrentAccountCharge extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "current_account_id", nullable = false)
|
||||
private CurrentAccount currentAccount;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "charge_id", nullable = false)
|
||||
private Charge charge;
|
||||
|
||||
@Column(name = "charge_time_enum", nullable = false)
|
||||
private Integer chargeTimeEnum;
|
||||
|
||||
@Column(name = "charge_due_date")
|
||||
private LocalDate chargeDueDate;
|
||||
|
||||
@Column(name = "fee_on_month")
|
||||
private Integer feeOnMonth;
|
||||
|
||||
@Column(name = "fee_on_day")
|
||||
private Integer feeOnDay;
|
||||
|
||||
@Column(name = "fee_interval")
|
||||
private Integer feeInterval;
|
||||
|
||||
@Column(name = "charge_calculation_enum", nullable = false)
|
||||
private Integer chargeCalculationEnum;
|
||||
|
||||
@Column(name = "calculation_percentage", precision = 19, scale = 6)
|
||||
private BigDecimal calculationPercentage;
|
||||
|
||||
@Column(name = "calculation_on_amount", precision = 19, scale = 6)
|
||||
private BigDecimal calculationOnAmount;
|
||||
|
||||
@Column(name = "amount", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal amount;
|
||||
|
||||
@Column(name = "amount_paid_derived", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal amountPaidDerived = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "amount_waived_derived", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal amountWaivedDerived = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "amount_writtenoff_derived", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal amountWrittenOffDerived = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "amount_outstanding_derived", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal amountOutstandingDerived;
|
||||
|
||||
@Column(name = "is_paid_derived", nullable = false)
|
||||
private boolean paid = false;
|
||||
|
||||
@Column(name = "waived", nullable = false)
|
||||
private boolean waived = false;
|
||||
|
||||
@Column(name = "is_penalty", nullable = false)
|
||||
private boolean penalty = false;
|
||||
|
||||
@Column(name = "is_active", nullable = false)
|
||||
private boolean active = true;
|
||||
|
||||
@Column(name = "inactivated_on_date")
|
||||
private LocalDate inactivatedOnDate;
|
||||
|
||||
@Column(name = "free_withdrawal_count")
|
||||
private Integer freeWithdrawalCount;
|
||||
|
||||
@Column(name = "charge_reset_date")
|
||||
private LocalDate chargeResetDate;
|
||||
|
||||
protected CurrentAccountCharge() {}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentaccount.domain;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_current_account_facility_config")
|
||||
@Getter
|
||||
@Setter
|
||||
public class CurrentAccountFacilityConfig extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "current_account_id", nullable = false, unique = true)
|
||||
private CurrentAccount currentAccount;
|
||||
|
||||
@Column(name = "atm_facility", nullable = false)
|
||||
private boolean atmFacility = false;
|
||||
|
||||
@Column(name = "atm_withdrawal_facility", nullable = false)
|
||||
private boolean atmWithdrawalFacility = false;
|
||||
|
||||
@Column(name = "upi_facility", nullable = false)
|
||||
private boolean upiFacility = false;
|
||||
|
||||
@Column(name = "pos_transactions_facility", nullable = false)
|
||||
private boolean posTransactionsFacility = false;
|
||||
|
||||
@Column(name = "cheque_book", nullable = false)
|
||||
private boolean chequeBook = false;
|
||||
|
||||
@Column(name = "imps_facility", nullable = false)
|
||||
private boolean impsFacility = false;
|
||||
|
||||
@Column(name = "sms_alerts", nullable = false)
|
||||
private boolean smsAlerts = false;
|
||||
|
||||
@Column(name = "bbps_facility", nullable = false)
|
||||
private boolean bbpsFacility = false;
|
||||
|
||||
@Column(name = "insurance_cover", nullable = false)
|
||||
private boolean insuranceCover = false;
|
||||
|
||||
@Column(name = "bepg_facility", nullable = false)
|
||||
private boolean bepgFacility = false;
|
||||
|
||||
@Column(name = "neft_facility", nullable = false)
|
||||
private boolean neftFacility = false;
|
||||
|
||||
@Column(name = "rtgs_facility", nullable = false)
|
||||
private boolean rtgsFacility = false;
|
||||
|
||||
@Column(name = "inter_bank_total_cap_facility", nullable = false)
|
||||
private boolean interBankTotalCapFacility = false;
|
||||
|
||||
@Column(name = "withdrawal_facility", nullable = false)
|
||||
private boolean withdrawalFacility = false;
|
||||
|
||||
@Column(name = "deposit_facility_kyc", nullable = false)
|
||||
private boolean depositFacilityKyc = false;
|
||||
|
||||
@Column(name = "virtual_debit_card", nullable = false)
|
||||
private boolean virtualDebitCard = false;
|
||||
|
||||
@Column(name = "internet_banking", nullable = false)
|
||||
private boolean internetBanking = false;
|
||||
|
||||
@Column(name = "mobile_banking", nullable = false)
|
||||
private boolean mobileBanking = false;
|
||||
|
||||
protected CurrentAccountFacilityConfig() {}
|
||||
|
||||
public static CurrentAccountFacilityConfig createFor(CurrentAccount account) {
|
||||
CurrentAccountFacilityConfig cfg = new CurrentAccountFacilityConfig();
|
||||
cfg.currentAccount = account;
|
||||
return cfg;
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentaccount.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 java.math.BigDecimal;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_current_account_joint_holder")
|
||||
@Getter
|
||||
@Setter
|
||||
public class CurrentAccountJointHolder extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "current_account_id", nullable = false)
|
||||
private CurrentAccount currentAccount;
|
||||
|
||||
@Column(name = "client_id")
|
||||
private Long clientId;
|
||||
|
||||
@Column(name = "cif_number", length = 50)
|
||||
private String cifNumber;
|
||||
|
||||
@Column(name = "display_name", length = 200)
|
||||
private String displayName;
|
||||
|
||||
@Column(name = "share_percentage", precision = 5, scale = 2)
|
||||
private BigDecimal sharePercentage;
|
||||
|
||||
@Column(name = "signing_authority", length = 100)
|
||||
private String signingAuthority;
|
||||
|
||||
@Column(name = "role", length = 100)
|
||||
private String role;
|
||||
|
||||
@Column(name = "is_primary", nullable = false)
|
||||
private boolean primary = false;
|
||||
|
||||
public CurrentAccountJointHolder() {}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentaccount.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 java.time.LocalDate;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.organisation.staff.domain.Staff;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_current_account_officer_history")
|
||||
@Getter
|
||||
@Setter
|
||||
public class CurrentAccountOfficerHistory extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "current_account_id", nullable = false)
|
||||
private CurrentAccount currentAccount;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "staff_id")
|
||||
private Staff staff;
|
||||
|
||||
@Column(name = "start_date", nullable = false)
|
||||
private LocalDate startDate;
|
||||
|
||||
@Column(name = "end_date")
|
||||
private LocalDate endDate;
|
||||
|
||||
@Column(name = "created_by_id")
|
||||
private Long createdById;
|
||||
|
||||
protected CurrentAccountOfficerHistory() {}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentaccount.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 java.math.BigDecimal;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_current_account_partner")
|
||||
@Getter
|
||||
@Setter
|
||||
public class CurrentAccountPartner extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "current_account_id", nullable = false)
|
||||
private CurrentAccount currentAccount;
|
||||
|
||||
@Column(name = "client_id")
|
||||
private Long clientId;
|
||||
|
||||
@Column(name = "client_cif", length = 50)
|
||||
private String clientCif;
|
||||
|
||||
@Column(name = "client_name", length = 200)
|
||||
private String clientName;
|
||||
|
||||
@Column(name = "share_percentage", precision = 5, scale = 2)
|
||||
private BigDecimal sharePercentage;
|
||||
|
||||
@Column(name = "is_mandatory", nullable = false)
|
||||
private boolean mandatory = false;
|
||||
|
||||
public CurrentAccountPartner() {}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentaccount.domain;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface CurrentAccountRepository extends JpaRepository<CurrentAccount, Long> {
|
||||
|
||||
Optional<CurrentAccount> findByAccountNo(String accountNo);
|
||||
|
||||
Optional<CurrentAccount> findByExternalId(String externalId);
|
||||
|
||||
List<CurrentAccount> findByClientId(Long clientId);
|
||||
|
||||
@Query("SELECT MAX(ca.id) FROM CurrentAccount ca")
|
||||
Optional<Long> findMaxId();
|
||||
|
||||
@Query("SELECT ca FROM CurrentAccount ca WHERE ca.client.id = :clientId AND ca.statusEnum != 600")
|
||||
List<CurrentAccount> findActiveByClientId(@Param("clientId") Long clientId);
|
||||
}
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentaccount.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 java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_current_account_transaction")
|
||||
@Getter
|
||||
@Setter
|
||||
public class CurrentAccountTransaction extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "current_account_id", nullable = false)
|
||||
private CurrentAccount currentAccount;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "office_id", nullable = false)
|
||||
private Office office;
|
||||
|
||||
// 1=Deposit, 2=Withdrawal, 3=InterestPosting, 4=Charge, 5=ChargeWaiver, 6=Transfer, 7=Reversal
|
||||
@Column(name = "transaction_type_enum", nullable = false)
|
||||
private Integer transactionTypeEnum;
|
||||
|
||||
@Column(name = "transaction_date", nullable = false)
|
||||
private LocalDate transactionDate;
|
||||
|
||||
@Column(name = "amount", nullable = false, precision = 19, scale = 6)
|
||||
private BigDecimal amount;
|
||||
|
||||
@Column(name = "ref_no", length = 100)
|
||||
private String refNo;
|
||||
|
||||
@Column(name = "remarks", length = 500)
|
||||
private String remarks;
|
||||
|
||||
@Column(name = "is_reversed", nullable = false)
|
||||
private boolean reversed = false;
|
||||
|
||||
@Column(name = "is_reversal", nullable = false)
|
||||
private boolean reversal = false;
|
||||
|
||||
@Column(name = "original_transaction_id")
|
||||
private Long originalTransactionId;
|
||||
|
||||
@Column(name = "is_manual", nullable = false)
|
||||
private boolean manual = false;
|
||||
|
||||
@Column(name = "running_balance_derived", precision = 19, scale = 6)
|
||||
private BigDecimal runningBalanceDerived;
|
||||
|
||||
@Column(name = "cumulative_balance_derived", precision = 19, scale = 6)
|
||||
private BigDecimal cumulativeBalanceDerived;
|
||||
|
||||
@Column(name = "balance_end_date_derived")
|
||||
private LocalDate balanceEndDateDerived;
|
||||
|
||||
@Column(name = "balance_number_of_days_derived")
|
||||
private Integer balanceNumberOfDaysDerived;
|
||||
|
||||
@Column(name = "overdraft_amount_derived", precision = 19, scale = 6)
|
||||
private BigDecimal overdraftAmountDerived;
|
||||
|
||||
@Column(name = "is_lien_transaction", nullable = false)
|
||||
private boolean lienTransaction = false;
|
||||
|
||||
@Column(name = "release_id_of_hold_amount_transaction")
|
||||
private Long releaseIdOfHoldAmountTransaction;
|
||||
|
||||
@Column(name = "reason_for_block", length = 200)
|
||||
private String reasonForBlock;
|
||||
|
||||
@Column(name = "submitted_on_date")
|
||||
private LocalDate submittedOnDate;
|
||||
|
||||
@Column(name = "created_date")
|
||||
private LocalDateTime createdDate;
|
||||
|
||||
@Column(name = "created_by")
|
||||
private Long createdBy;
|
||||
|
||||
protected CurrentAccountTransaction() {}
|
||||
|
||||
public static CurrentAccountTransaction deposit(CurrentAccount account, Office office,
|
||||
BigDecimal amount, LocalDate transactionDate, String refNo) {
|
||||
CurrentAccountTransaction txn = new CurrentAccountTransaction();
|
||||
txn.currentAccount = account;
|
||||
txn.office = office;
|
||||
txn.transactionTypeEnum = 1;
|
||||
txn.amount = amount;
|
||||
txn.transactionDate = transactionDate;
|
||||
txn.refNo = refNo;
|
||||
txn.submittedOnDate = transactionDate;
|
||||
return txn;
|
||||
}
|
||||
|
||||
public static CurrentAccountTransaction withdrawal(CurrentAccount account, Office office,
|
||||
BigDecimal amount, LocalDate transactionDate, String refNo) {
|
||||
CurrentAccountTransaction txn = new CurrentAccountTransaction();
|
||||
txn.currentAccount = account;
|
||||
txn.office = office;
|
||||
txn.transactionTypeEnum = 2;
|
||||
txn.amount = amount;
|
||||
txn.transactionDate = transactionDate;
|
||||
txn.refNo = refNo;
|
||||
txn.submittedOnDate = transactionDate;
|
||||
return txn;
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentaccount.domain;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface CurrentAccountTransactionRepository extends JpaRepository<CurrentAccountTransaction, Long> {
|
||||
|
||||
List<CurrentAccountTransaction> findByCurrentAccountIdOrderByTransactionDateDescIdDesc(Long currentAccountId);
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentaccount.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.portfolio.currentaccount.domain.CurrentAccount;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Generates CBS account numbers for current accounts.
|
||||
* Format: 00 + GL_CODE(6 digits) + OFFICE_ID(2 digits) + ACCOUNT_ID(5 digits) = 15 digits
|
||||
* GL code is fetched from m_current_product.gl_account_id → m_acc_gl_account.gl_code
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CurrentAccountNumberGenerator {
|
||||
|
||||
private static final String CBS_PREFIX = "00";
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
public String generate(CurrentAccount account) {
|
||||
Long productId = account.getProductId();
|
||||
|
||||
// Fetch gl_code directly from current product → gl account
|
||||
String glCode = jdbcTemplate.query(
|
||||
"SELECT ga.gl_code FROM m_current_product cp "
|
||||
+ "JOIN m_acc_gl_account ga ON ga.id = cp.gl_account_id "
|
||||
+ "WHERE cp.id = ?",
|
||||
rs -> rs.next() ? rs.getString("gl_code") : null,
|
||||
productId);
|
||||
|
||||
if (glCode == null || glCode.isBlank()) glCode = "000000";
|
||||
|
||||
// Pad/trim GL code to 6 digits
|
||||
glCode = glCode.length() > 6
|
||||
? glCode.substring(glCode.length() - 6)
|
||||
: StringUtils.leftPad(glCode, 6, '0');
|
||||
|
||||
// Office ID — 2 digits
|
||||
String officeId = StringUtils.leftPad(account.getOffice().getId().toString(), 2, '0');
|
||||
if (officeId.length() > 2) officeId = officeId.substring(officeId.length() - 2);
|
||||
|
||||
// Account ID — 5 digits
|
||||
String accountId = StringUtils.leftPad(account.getId().toString(), 5, '0');
|
||||
if (accountId.length() > 5) accountId = accountId.substring(accountId.length() - 5);
|
||||
|
||||
return CBS_PREFIX + glCode + officeId + accountId;
|
||||
}
|
||||
|
||||
public String preview(Long productId, Long officeId) {
|
||||
String glCode = jdbcTemplate.query(
|
||||
"SELECT ga.gl_code FROM m_current_product cp "
|
||||
+ "JOIN m_acc_gl_account ga ON ga.id = cp.gl_account_id "
|
||||
+ "WHERE cp.id = ?",
|
||||
rs -> rs.next() ? rs.getString("gl_code") : null,
|
||||
productId);
|
||||
|
||||
if (glCode == null || glCode.isBlank()) glCode = "000000";
|
||||
glCode = glCode.length() > 6 ? glCode.substring(glCode.length() - 6) : StringUtils.leftPad(glCode, 6, '0');
|
||||
|
||||
String officeStr = StringUtils.leftPad(officeId != null ? officeId.toString() : "0", 2, '0');
|
||||
if (officeStr.length() > 2) officeStr = officeStr.substring(officeStr.length() - 2);
|
||||
|
||||
// Next account ID estimate from m_current_account
|
||||
Long maxId = jdbcTemplate.query(
|
||||
"SELECT MAX(id) FROM m_current_account",
|
||||
rs -> rs.next() ? rs.getLong(1) : 0L);
|
||||
String nextSeq = StringUtils.leftPad(String.valueOf((maxId != null ? maxId : 0L) + 1), 5, '0');
|
||||
if (nextSeq.length() > 5) nextSeq = nextSeq.substring(nextSeq.length() - 5);
|
||||
|
||||
return CBS_PREFIX + glCode + officeStr + nextSeq;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentaccount.service;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
|
||||
public interface CurrentAccountWritePlatformService {
|
||||
|
||||
CommandProcessingResult submitApplication(JsonCommand command);
|
||||
|
||||
CommandProcessingResult approveApplication(Long accountId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult undoApproval(Long accountId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult activate(Long accountId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult rejectApplication(Long accountId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult withdrawApplication(Long accountId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult closeAccount(Long accountId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult modifyApplication(Long accountId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult deleteApplication(Long accountId);
|
||||
}
|
||||
+9
@@ -817,6 +817,15 @@ public class CurrentProduct extends AbstractPersistableCustom<Long> {
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
public String getName() { return name; }
|
||||
public String getShortName() { return shortName; }
|
||||
public boolean isAllowOverdraft() { return allowOverdraft; }
|
||||
public BigDecimal getOverdraftLimit() { return overdraftLimit; }
|
||||
public Integer getInterestCompoundingPeriodType() { return interestCompoundingPeriodType; }
|
||||
public Integer getInterestPostingPeriodType() { return interestPostingPeriodType; }
|
||||
public Integer getInterestCalculationType() { return interestCalculationType; }
|
||||
public Integer getInterestCalculationDaysInYearType() { return interestCalculationDaysInYearType; }
|
||||
|
||||
// Dormancy/misc getters needed by validator
|
||||
public Boolean isDormancyTrackingActive() { return this.isDormancyTrackingActive; }
|
||||
public Long getDaysToInactive() { return this.daysToInactive; }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+25765
-2
File diff suppressed because it is too large
Load Diff
+32
@@ -36,10 +36,12 @@ import org.apache.fineract.portfolio.client.domain.ClientRepository;
|
||||
import org.apache.fineract.portfolio.group.domain.Group;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
|
||||
import org.apache.fineract.portfolio.currentaccount.domain.CurrentAccount;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepository;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsProductRepository;
|
||||
import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
@@ -69,6 +71,7 @@ public class AccountNumberGenerator {
|
||||
private final SavingsAccountRepository savingsAccountRepository;
|
||||
private final GLAccountRepository glAccountRepository;
|
||||
private final SavingsProductRepository savingsProductRepository;
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
public String generate(Client client, AccountNumberFormat accountNumberFormat) {
|
||||
Map<String, String> propertyMap = new HashMap<>();
|
||||
@@ -119,6 +122,35 @@ public class AccountNumberGenerator {
|
||||
return CBS_FIXED_PREFIX + glCode + officeId + accountId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate CBS account number for a current account.
|
||||
* GL code is fetched directly from m_current_product using the current account's product_id.
|
||||
* Format: 00 + GL_CODE(6) + OFFICE_ID(2) + ACCOUNT_ID(5) = 15 digits
|
||||
*/
|
||||
public String generateForCurrentAccount(CurrentAccount currentAccount) {
|
||||
Long productId = currentAccount.getProductId();
|
||||
Long glAccountId = jdbcTemplate.query(
|
||||
"SELECT gl_account_id FROM m_current_product WHERE id = ?",
|
||||
rs -> rs.next() ? rs.getLong("gl_account_id") : null,
|
||||
productId);
|
||||
|
||||
String glCode = "000000";
|
||||
if (glAccountId != null && glAccountId > 0) {
|
||||
glCode = glAccountRepository.findById(glAccountId)
|
||||
.map(gl -> StringUtils.leftPad(gl.getGlCode(), 6, '0'))
|
||||
.orElse("000000");
|
||||
}
|
||||
glCode = glCode.length() > 6 ? glCode.substring(glCode.length() - 6) : StringUtils.leftPad(glCode, 6, '0');
|
||||
|
||||
String officeId = StringUtils.leftPad(currentAccount.getOffice().getId().toString(), 2, '0');
|
||||
if (officeId.length() > 2) officeId = officeId.substring(officeId.length() - 2);
|
||||
|
||||
String accountId = StringUtils.leftPad(currentAccount.getId().toString(), 5, '0');
|
||||
if (accountId.length() > 5) accountId = accountId.substring(accountId.length() - 5);
|
||||
|
||||
return CBS_FIXED_PREFIX + glCode + officeId + accountId;
|
||||
}
|
||||
|
||||
public String previewAccountNumber(Long productId, Long officeId) {
|
||||
String glCode = "000000";
|
||||
if (productId != null) {
|
||||
|
||||
+18
-53
@@ -40,9 +40,6 @@ import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
||||
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.apache.fineract.infrastructure.core.api.ApiParameterHelper;
|
||||
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
@@ -59,6 +56,7 @@ import org.apache.fineract.portfolio.savings.SavingsApiConstants;
|
||||
import org.apache.fineract.portfolio.savings.data.SavingsAccountChargeData;
|
||||
import org.apache.fineract.portfolio.savings.data.SavingsAccountData;
|
||||
import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionData;
|
||||
import org.apache.fineract.portfolio.currentaccount.service.CurrentAccountWritePlatformService;
|
||||
import org.apache.fineract.portfolio.savings.service.CurrentAccountTemplateReadPlatformService;
|
||||
import org.apache.fineract.portfolio.savings.service.SavingsAccountChargeReadPlatformService;
|
||||
import org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformService;
|
||||
@@ -75,10 +73,10 @@ public class CurrentAccountsApiResource {
|
||||
private final CurrentAccountTemplateReadPlatformService currentAccountTemplateReadPlatformService;
|
||||
private final PlatformSecurityContext context;
|
||||
private final DefaultToApiJsonSerializer<SavingsAccountData> toApiJsonSerializer;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final SavingsAccountChargeReadPlatformService savingsAccountChargeReadPlatformService;
|
||||
private final SqlValidator sqlValidator;
|
||||
private final CurrentAccountWritePlatformService currentAccountWritePlatformService;
|
||||
|
||||
@GET
|
||||
@Path("template")
|
||||
@@ -128,8 +126,9 @@ public class CurrentAccountsApiResource {
|
||||
@Operation(summary = "Submit new current account application")
|
||||
@ApiResponse(responseCode = "200", description = "OK")
|
||||
public String submitApplication(@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createCurrentAccount().withJson(apiRequestBodyAsJson).build();
|
||||
final CommandProcessingResult result = commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
final org.apache.fineract.infrastructure.core.api.JsonCommand command =
|
||||
org.apache.fineract.infrastructure.core.api.JsonCommand.from(apiRequestBodyAsJson);
|
||||
final CommandProcessingResult result = currentAccountWritePlatformService.submitApplication(command);
|
||||
return toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@@ -164,16 +163,9 @@ public class CurrentAccountsApiResource {
|
||||
@Parameter(hidden = true) final String apiRequestBodyAsJson,
|
||||
@QueryParam("command") final String commandParam) {
|
||||
|
||||
if (is(commandParam, "updateWithHoldTax")) {
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson)
|
||||
.updateWithHoldTaxCurrentAccount(accountId).build();
|
||||
final CommandProcessingResult result = commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
return toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateCurrentAccount(accountId).withJson(apiRequestBodyAsJson)
|
||||
.build();
|
||||
final CommandProcessingResult result = commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
final org.apache.fineract.infrastructure.core.api.JsonCommand command =
|
||||
org.apache.fineract.infrastructure.core.api.JsonCommand.from(apiRequestBodyAsJson);
|
||||
final CommandProcessingResult result = currentAccountWritePlatformService.modifyApplication(accountId, command);
|
||||
return toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@@ -192,53 +184,27 @@ public class CurrentAccountsApiResource {
|
||||
jsonApiRequest = "{}";
|
||||
}
|
||||
|
||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(jsonApiRequest);
|
||||
final org.apache.fineract.infrastructure.core.api.JsonCommand command =
|
||||
org.apache.fineract.infrastructure.core.api.JsonCommand.from(jsonApiRequest);
|
||||
|
||||
CommandProcessingResult result = null;
|
||||
if (is(commandParam, "reject")) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.rejectCurrentAccountApplication(accountId).build());
|
||||
result = currentAccountWritePlatformService.rejectApplication(accountId, command);
|
||||
} else if (is(commandParam, "withdrawnByApplicant")) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.withdrawCurrentAccountApplication(accountId).build());
|
||||
result = currentAccountWritePlatformService.withdrawApplication(accountId, command);
|
||||
} else if (is(commandParam, "approve")) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.approveCurrentAccountApplication(accountId).build());
|
||||
result = currentAccountWritePlatformService.approveApplication(accountId, command);
|
||||
} else if (is(commandParam, "undoapproval")) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.undoCurrentAccountApplication(accountId).build());
|
||||
result = currentAccountWritePlatformService.undoApproval(accountId, command);
|
||||
} else if (is(commandParam, "activate")) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.currentAccountActivation(accountId).build());
|
||||
} else if (is(commandParam, "calculateInterest")) {
|
||||
result = commandsSourceWritePlatformService
|
||||
.logCommandSource(builder.withNoJsonBody().currentAccountInterestCalculation(accountId).build());
|
||||
} else if (is(commandParam, "postInterest")) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.currentAccountInterestPosting(accountId).build());
|
||||
} else if (is(commandParam, "applyAnnualFees")) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.currentAccountApplyAnnualFees(accountId).build());
|
||||
result = currentAccountWritePlatformService.activate(accountId, command);
|
||||
} else if (is(commandParam, "close")) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.closeCurrentAccountApplication(accountId).build());
|
||||
} else if (is(commandParam, "assignSavingsOfficer")) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.assignCurrentAccountOfficer(accountId).build());
|
||||
} else if (is(commandParam, "unassignSavingsOfficer")) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.unassignCurrentAccountOfficer(accountId).build());
|
||||
} else if (is(commandParam, SavingsApiConstants.COMMAND_BLOCK_DEBIT)) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.blockDebitsFromCurrentAccount(accountId).build());
|
||||
} else if (is(commandParam, SavingsApiConstants.COMMAND_UNBLOCK_DEBIT)) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.unblockDebitsFromCurrentAccount(accountId).build());
|
||||
} else if (is(commandParam, SavingsApiConstants.COMMAND_BLOCK_CREDIT)) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.blockCreditsToCurrentAccount(accountId).build());
|
||||
} else if (is(commandParam, SavingsApiConstants.COMMAND_UNBLOCK_CREDIT)) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.unblockCreditsToCurrentAccount(accountId).build());
|
||||
} else if (is(commandParam, SavingsApiConstants.COMMAND_BLOCK_ACCOUNT)) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.blockCurrentAccount(accountId).build());
|
||||
} else if (is(commandParam, SavingsApiConstants.COMMAND_UNBLOCK_ACCOUNT)) {
|
||||
result = commandsSourceWritePlatformService.logCommandSource(builder.unblockCurrentAccount(accountId).build());
|
||||
result = currentAccountWritePlatformService.closeAccount(accountId, command);
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
throw new UnrecognizedQueryParamException("command", commandParam,
|
||||
new Object[] { "reject", "withdrawnByApplicant", "approve", "undoapproval", "activate", "calculateInterest",
|
||||
"postInterest", "close", "assignSavingsOfficer", "unassignSavingsOfficer",
|
||||
SavingsApiConstants.COMMAND_BLOCK_DEBIT, SavingsApiConstants.COMMAND_UNBLOCK_DEBIT,
|
||||
SavingsApiConstants.COMMAND_BLOCK_CREDIT, SavingsApiConstants.COMMAND_UNBLOCK_CREDIT,
|
||||
SavingsApiConstants.COMMAND_BLOCK_ACCOUNT, SavingsApiConstants.COMMAND_UNBLOCK_ACCOUNT });
|
||||
new Object[] { "reject", "withdrawnByApplicant", "approve", "undoapproval", "activate", "close" });
|
||||
}
|
||||
|
||||
return toApiJsonSerializer.serialize(result);
|
||||
@@ -251,8 +217,7 @@ public class CurrentAccountsApiResource {
|
||||
@Operation(summary = "Delete a current account application")
|
||||
@ApiResponse(responseCode = "200", description = "OK")
|
||||
public String delete(@PathParam("accountId") final Long accountId) {
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteCurrentAccount(accountId).build();
|
||||
final CommandProcessingResult result = commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
final CommandProcessingResult result = currentAccountWritePlatformService.deleteApplication(accountId);
|
||||
return toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
|
||||
+128
@@ -19,7 +19,27 @@
|
||||
package org.apache.fineract.portfolio.savings.domain;
|
||||
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accountFacilityConfigParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accountNoParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accountStatusParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.guardianClientIdParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.modeOfOperationParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accountTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.customerSegmentParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.guardianCifNumberParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.guardianNameParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.guardianRelationshipParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.introducerCifNumberParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.introducerIdParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.introducerNameParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.jointHoldersParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.linkedAccountIdParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.linkedAccountNoParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.linkedAccountTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minorDateOfBirthParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nomineeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.specialCategoryParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.weakerSectionParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.allowOverdraftParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.clientIdParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.enforceMinRequiredBalanceParamName;
|
||||
@@ -45,7 +65,10 @@ import static org.apache.fineract.portfolio.savings.SavingsApiConstants.submitte
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
@@ -336,9 +359,114 @@ public class SavingsAccountAssembler {
|
||||
|
||||
account.validateAccountValuesWithProduct();
|
||||
|
||||
// CBS extended fields
|
||||
applyCbsFields(command, element, account);
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
private void applyCbsFields(final JsonCommand command, final JsonElement element, final SavingsAccount account) {
|
||||
// Product classification
|
||||
final String cbsAccountType = this.fromApiJsonHelper.extractStringNamed(accountTypeParamName, element);
|
||||
if (cbsAccountType != null) account.setCbsAccountType(cbsAccountType);
|
||||
|
||||
final String customerSegment = this.fromApiJsonHelper.extractStringNamed(customerSegmentParamName, element);
|
||||
if (customerSegment != null) account.setCustomerSegment(customerSegment);
|
||||
|
||||
// Status of Account
|
||||
final String accountStatus = this.fromApiJsonHelper.extractStringNamed(accountStatusParamName, element);
|
||||
if (accountStatus != null) account.setAccountStatus(accountStatus);
|
||||
|
||||
final String modeOfOperation = this.fromApiJsonHelper.extractStringNamed(modeOfOperationParamName, element);
|
||||
if (modeOfOperation != null) account.setModeOfOperation(modeOfOperation);
|
||||
|
||||
account.setSpecialCategory(this.fromApiJsonHelper.extractStringNamed(specialCategoryParamName, element));
|
||||
account.setWeakerSection(this.fromApiJsonHelper.extractStringNamed(weakerSectionParamName, element));
|
||||
account.setGuardianName(this.fromApiJsonHelper.extractStringNamed(guardianNameParamName, element));
|
||||
account.setGuardianCifNumber(this.fromApiJsonHelper.extractStringNamed(guardianCifNumberParamName, element));
|
||||
account.setGuardianRelationship(this.fromApiJsonHelper.extractStringNamed(guardianRelationshipParamName, element));
|
||||
|
||||
if (command.parameterExists(minorDateOfBirthParamName)) {
|
||||
final LocalDate minorDob = this.fromApiJsonHelper.extractLocalDateNamed(minorDateOfBirthParamName, element);
|
||||
account.setMinorDateOfBirth(minorDob);
|
||||
}
|
||||
|
||||
final Long guardianClientId = this.fromApiJsonHelper.extractLongNamed(guardianClientIdParamName, element);
|
||||
if (guardianClientId != null) account.setGuardianClientId(guardianClientId);
|
||||
|
||||
// Introducer
|
||||
final Long introducerId = this.fromApiJsonHelper.extractLongNamed(introducerIdParamName, element);
|
||||
if (introducerId != null) account.setIntroducerClientId(introducerId);
|
||||
account.setIntroducerName(this.fromApiJsonHelper.extractStringNamed(introducerNameParamName, element));
|
||||
account.setIntroducerCifNumber(this.fromApiJsonHelper.extractStringNamed(introducerCifNumberParamName, element));
|
||||
|
||||
// Nominee (stored as JSON string)
|
||||
if (element.getAsJsonObject().has(nomineeParamName)) {
|
||||
final JsonElement nomineeEl = element.getAsJsonObject().get(nomineeParamName);
|
||||
if (nomineeEl != null && !nomineeEl.isJsonNull()) {
|
||||
account.setNomineeData(nomineeEl.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Deposit Account Link
|
||||
final Long linkedAccountId = this.fromApiJsonHelper.extractLongNamed(linkedAccountIdParamName, element);
|
||||
if (linkedAccountId != null) account.setLinkedAccountId(linkedAccountId);
|
||||
account.setLinkedAccountType(this.fromApiJsonHelper.extractStringNamed(linkedAccountTypeParamName, element));
|
||||
account.setLinkedAccountNo(this.fromApiJsonHelper.extractStringNamed(linkedAccountNoParamName, element));
|
||||
|
||||
// Account Facility Config
|
||||
if (element.getAsJsonObject().has(accountFacilityConfigParamName)) {
|
||||
final JsonElement configEl = element.getAsJsonObject().get(accountFacilityConfigParamName);
|
||||
if (configEl != null && !configEl.isJsonNull() && configEl.isJsonObject()) {
|
||||
SavingsAccountFacilityConfig facilityConfig = account.getFacilityConfig();
|
||||
if (facilityConfig == null) {
|
||||
facilityConfig = new SavingsAccountFacilityConfig(account);
|
||||
account.setFacilityConfig(facilityConfig);
|
||||
}
|
||||
facilityConfig.updateFrom(configEl.getAsJsonObject());
|
||||
}
|
||||
}
|
||||
|
||||
// Joint holders
|
||||
if (element.getAsJsonObject().has(jointHoldersParamName)) {
|
||||
final JsonElement holdersEl = element.getAsJsonObject().get(jointHoldersParamName);
|
||||
if (holdersEl != null && !holdersEl.isJsonNull() && holdersEl.isJsonArray()) {
|
||||
final com.google.gson.JsonArray holdersArray = holdersEl.getAsJsonArray();
|
||||
final List<SavingsAccountJointHolder> holders = new ArrayList<>();
|
||||
for (int i = 0; i < holdersArray.size(); i++) {
|
||||
final JsonObject h = holdersArray.get(i).getAsJsonObject();
|
||||
final Long clientId = h.has("clientId") && !h.get("clientId").isJsonNull()
|
||||
? h.get("clientId").getAsLong() : null;
|
||||
final String cifNumber = h.has("cifNumber") && !h.get("cifNumber").isJsonNull()
|
||||
? h.get("cifNumber").getAsString() : null;
|
||||
final String displayName = h.has("displayName") && !h.get("displayName").isJsonNull()
|
||||
? h.get("displayName").getAsString() : null;
|
||||
final BigDecimal sharePercentage = h.has("sharePercentage") && !h.get("sharePercentage").isJsonNull()
|
||||
? h.get("sharePercentage").getAsBigDecimal() : null;
|
||||
final boolean isPrimary = h.has("isPrimary") && h.get("isPrimary").getAsBoolean();
|
||||
String signingAuthority = h.has("signingAuthority") && !h.get("signingAuthority").isJsonNull()
|
||||
? h.get("signingAuthority").getAsString() : null;
|
||||
String role = h.has("role") && !h.get("role").isJsonNull()
|
||||
? h.get("role").getAsString() : null;
|
||||
|
||||
if (signingAuthority == null || signingAuthority.trim().isEmpty()) {
|
||||
signingAuthority = isPrimary ? "Mandatory" : "Optional";
|
||||
}
|
||||
if (role == null || role.trim().isEmpty()) {
|
||||
role = isPrimary ? "Primary Account Holder" : "Co-Holder";
|
||||
}
|
||||
|
||||
holders.add(new SavingsAccountJointHolder(account, clientId, cifNumber, displayName,
|
||||
sharePercentage, signingAuthority, role, isPrimary));
|
||||
}
|
||||
account.getJointHolders().clear();
|
||||
account.getJointHolders().addAll(holders);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SavingsAccount assembleFrom(final Long savingsId, final boolean backdatedTxnsAllowedTill) {
|
||||
SavingsAccount account = this.savingsAccountRepository.findSavingsWithNotFoundDetection(savingsId, backdatedTxnsAllowedTill);
|
||||
return loadTransactionsToSavingsAccount(account, backdatedTxnsAllowedTill);
|
||||
|
||||
+13
-1
@@ -26,7 +26,10 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
||||
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.portfolio.savings.SavingsApiConstants;
|
||||
import org.apache.fineract.portfolio.account.service.AccountNumberGenerator;
|
||||
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
|
||||
@@ -78,6 +81,7 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
|
||||
private final ChargeReadPlatformService chargeReadPlatformService;
|
||||
private final EntityDatatableChecksReadService entityDatatableChecksReadService;
|
||||
private final AccountNumberGenerator accountNumberGenerator;
|
||||
private final CodeValueReadPlatformService codeValueReadPlatformService;
|
||||
|
||||
public CurrentAccountTemplateReadPlatformServiceImpl(final PlatformSecurityContext context, final JdbcTemplate jdbcTemplate,
|
||||
final ClientReadPlatformService clientReadPlatformService, final GroupReadPlatformService groupReadPlatformService,
|
||||
@@ -87,7 +91,8 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
|
||||
final ChargeReadPlatformService chargeReadPlatformService,
|
||||
final EntityDatatableChecksReadService entityDatatableChecksReadService,
|
||||
final ColumnValidator columnValidator,
|
||||
final AccountNumberGenerator accountNumberGenerator) {
|
||||
final AccountNumberGenerator accountNumberGenerator,
|
||||
final CodeValueReadPlatformService codeValueReadPlatformService) {
|
||||
this.context = context;
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
this.clientReadPlatformService = clientReadPlatformService;
|
||||
@@ -98,6 +103,7 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
|
||||
this.chargeReadPlatformService = chargeReadPlatformService;
|
||||
this.entityDatatableChecksReadService = entityDatatableChecksReadService;
|
||||
this.accountNumberGenerator = accountNumberGenerator;
|
||||
this.codeValueReadPlatformService = codeValueReadPlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -204,6 +210,12 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
|
||||
// Classification fields
|
||||
template.setAccountType(productData.getAccountType());
|
||||
template.setCustomerSegment(productData.getCustomerSegment());
|
||||
final Collection<CodeValueData> accountTypeOpts = this.codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(SavingsApiConstants.CURRENT_PRODUCT_ACCOUNT_TYPE);
|
||||
final Collection<CodeValueData> customerSegmentOpts = this.codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(SavingsApiConstants.CURRENT_PRODUCT_CUSTOMER_SEGMENT);
|
||||
template.setAccountTypeOptions(accountTypeOpts);
|
||||
template.setCustomerSegmentOptions(customerSegmentOpts);
|
||||
template.setProductCode(productData.getProductCode());
|
||||
template.setEffectiveDate(productData.getEffectiveDate());
|
||||
template.setEffectiveTo(productData.getEffectiveTo());
|
||||
|
||||
+370
@@ -0,0 +1,370 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.service;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.time.LocalDate;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper;
|
||||
import org.apache.fineract.organisation.staff.domain.Staff;
|
||||
import org.apache.fineract.portfolio.client.domain.Client;
|
||||
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.currentaccount.domain.CurrentAccount;
|
||||
import org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountFacilityConfig;
|
||||
import org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountJointHolder;
|
||||
import org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountPartner;
|
||||
import org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountRepository;
|
||||
import org.apache.fineract.portfolio.currentaccount.service.CurrentAccountWritePlatformService;
|
||||
import org.apache.fineract.portfolio.currentaccount.service.CurrentAccountNumberGenerator;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProduct;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductRepository;
|
||||
import org.apache.fineract.portfolio.savings.exception.SavingsAccountNotFoundException;
|
||||
import org.apache.fineract.portfolio.savings.exception.SavingsProductNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class CurrentAccountWritePlatformServiceImpl implements CurrentAccountWritePlatformService {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final CurrentAccountRepository currentAccountRepository;
|
||||
private final CurrentProductRepository currentProductRepository;
|
||||
private final ClientRepositoryWrapper clientRepository;
|
||||
private final OfficeRepositoryWrapper officeRepository;
|
||||
private final CurrentAccountNumberGenerator accountNumberGenerator;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult submitApplication(final JsonCommand command) {
|
||||
context.authenticatedUser();
|
||||
|
||||
final Long clientId = command.longValueOfParameterNamed("clientId");
|
||||
final Long productId = command.longValueOfParameterNamed("productId");
|
||||
final Long officeId = command.parameterExists("officeId") ? command.longValueOfParameterNamed("officeId") : null;
|
||||
final Long staffId = command.parameterExists("fieldOfficerId")
|
||||
&& !isBlankString(command.parsedJson().getAsJsonObject(), "fieldOfficerId")
|
||||
? command.longValueOfParameterNamed("fieldOfficerId") : null;
|
||||
|
||||
final Client client = clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
final CurrentProduct product = currentProductRepository.findById(productId)
|
||||
.orElseThrow(() -> new SavingsProductNotFoundException(productId));
|
||||
final Office office = officeId != null
|
||||
? officeRepository.findOneWithNotFoundDetection(officeId)
|
||||
: client.getOffice();
|
||||
|
||||
Staff staff = null;
|
||||
// staff loaded lazily if needed — keep null for now if not in scope
|
||||
|
||||
LocalDate submittedOnDate = command.localDateValueOfParameterNamed("submittedOnDate");
|
||||
if (submittedOnDate == null) submittedOnDate = LocalDate.now();
|
||||
|
||||
// accountType may arrive as integer or string — store null if absent/unparseable
|
||||
Integer accountTypeEnum = null;
|
||||
if (command.parameterExists("accountType")) {
|
||||
try {
|
||||
accountTypeEnum = command.integerValueOfParameterNamed("accountType");
|
||||
} catch (Exception ignored) {
|
||||
// string value like "Standard Account" — ignore, store null
|
||||
}
|
||||
}
|
||||
|
||||
// Override from request if provided, else use product defaults
|
||||
boolean msme = command.parameterExists("msme")
|
||||
? command.booleanPrimitiveValueOfParameterNamed("msme") : product.isMsme();
|
||||
boolean autoDebitFacility = command.parameterExists("autoDebitFacility")
|
||||
? command.booleanPrimitiveValueOfParameterNamed("autoDebitFacility") : product.isAutoDebitFacility();
|
||||
boolean balanceSwapOption = command.parameterExists("balanceSwapOption")
|
||||
? command.booleanPrimitiveValueOfParameterNamed("balanceSwapOption") : product.isBalanceSwapOption();
|
||||
|
||||
final CurrentAccount account = CurrentAccount.createNew(
|
||||
client, productId, office, staff, "TEMP", submittedOnDate, accountTypeEnum,
|
||||
product.currency().getCode(), product.currency().getDigitsAfterDecimal(),
|
||||
product.currency().getInMultiplesOf(),
|
||||
product.nominalAnnualInterestRate(),
|
||||
product.getInterestCompoundingPeriodType(), product.getInterestPostingPeriodType(),
|
||||
product.getInterestCalculationType(), product.getInterestCalculationDaysInYearType(),
|
||||
product.isAllowOverdraft(), product.getOverdraftLimit(),
|
||||
msme, autoDebitFacility, balanceSwapOption,
|
||||
product.getCustomerSegment(), product.isAutoPost(),
|
||||
product.getInterestCalculateSelector(), product.getAveragePeriod(),
|
||||
product.getAvgBalanceCalcPeriod());
|
||||
|
||||
if (command.parameterExists("establishmentDate")) {
|
||||
account.setEstablishmentDate(command.localDateValueOfParameterNamed("establishmentDate"));
|
||||
}
|
||||
if (command.parameterExists("startOperationDate")) {
|
||||
account.setStartOperationDate(command.localDateValueOfParameterNamed("startOperationDate"));
|
||||
}
|
||||
if (command.parameterExists("isNonIndividualClient")) {
|
||||
account.setNonIndividualClient(command.booleanPrimitiveValueOfParameterNamed("isNonIndividualClient"));
|
||||
}
|
||||
if (command.parameterExists("signatoryRights")) {
|
||||
account.setSignatoryRights(command.stringValueOfParameterNamed("signatoryRights"));
|
||||
}
|
||||
if (command.parameterExists("modeOfOperation")) {
|
||||
account.setModeOfOperation(command.stringValueOfParameterNamed("modeOfOperation"));
|
||||
}
|
||||
if (command.parameterExists("introducerName")) {
|
||||
account.setIntroducerName(command.stringValueOfParameterNamed("introducerName"));
|
||||
}
|
||||
if (command.parameterExists("introducerClientId")) {
|
||||
account.setIntroducerClientId(command.longValueOfParameterNamed("introducerClientId"));
|
||||
} else if (command.parameterExists("introducerId")) {
|
||||
account.setIntroducerClientId(command.longValueOfParameterNamed("introducerId"));
|
||||
}
|
||||
if (command.parameterExists("externalId")) {
|
||||
account.setExternalId(command.stringValueOfParameterNamed("externalId"));
|
||||
}
|
||||
if (command.parameterExists("accountStatus")) {
|
||||
account.setAccountStatus(command.stringValueOfParameterNamed("accountStatus"));
|
||||
}
|
||||
if (command.parameterExists("customerSegment")) {
|
||||
account.setCustomerSegment(command.stringValueOfParameterNamed("customerSegment"));
|
||||
}
|
||||
|
||||
// Save first to get ID
|
||||
currentAccountRepository.saveAndFlush(account);
|
||||
|
||||
// Generate account number: 00 + GL_CODE(6) + OFFICE_ID(2) + ACCOUNT_ID(5)
|
||||
final String accountNo = accountNumberGenerator.generate(account);
|
||||
account.updateAccountNo(accountNo);
|
||||
|
||||
// Facility config — UI sends "accountFacilityConfig", internal uses "facilityConfig"
|
||||
if (command.parameterExists("accountFacilityConfig") || command.parameterExists("facilityConfig")) {
|
||||
final CurrentAccountFacilityConfig facilityConfig = assembleFacilityConfig(account, command);
|
||||
account.setFacilityConfig(facilityConfig);
|
||||
}
|
||||
|
||||
// Joint holders
|
||||
if (command.parameterExists("jointHolders")) {
|
||||
assembleJointHolders(account, command);
|
||||
}
|
||||
|
||||
// Partners (non-individual)
|
||||
if (command.parameterExists("partners")) {
|
||||
assemblePartners(account, command);
|
||||
}
|
||||
|
||||
currentAccountRepository.saveAndFlush(account);
|
||||
|
||||
return new CommandProcessingResultBuilder()
|
||||
.withEntityId(account.getId())
|
||||
.withClientId(clientId)
|
||||
.withOfficeId(office.getId())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult approveApplication(final Long accountId, final JsonCommand command) {
|
||||
context.authenticatedUser();
|
||||
final CurrentAccount account = findAccount(accountId);
|
||||
LocalDate approvedOnDate = command.localDateValueOfParameterNamed("approvedOnDate");
|
||||
if (approvedOnDate == null) approvedOnDate = LocalDate.now();
|
||||
account.approve(approvedOnDate);
|
||||
currentAccountRepository.saveAndFlush(account);
|
||||
return new CommandProcessingResultBuilder().withEntityId(accountId).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult undoApproval(final Long accountId, final JsonCommand command) {
|
||||
context.authenticatedUser();
|
||||
final CurrentAccount account = findAccount(accountId);
|
||||
account.setStatusEnum(100);
|
||||
account.setApprovedOnDate(null);
|
||||
currentAccountRepository.saveAndFlush(account);
|
||||
return new CommandProcessingResultBuilder().withEntityId(accountId).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult activate(final Long accountId, final JsonCommand command) {
|
||||
context.authenticatedUser();
|
||||
final CurrentAccount account = findAccount(accountId);
|
||||
LocalDate activatedOnDate = command.localDateValueOfParameterNamed("activatedOnDate");
|
||||
if (activatedOnDate == null) activatedOnDate = LocalDate.now();
|
||||
account.activate(activatedOnDate);
|
||||
currentAccountRepository.saveAndFlush(account);
|
||||
return new CommandProcessingResultBuilder().withEntityId(accountId).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult rejectApplication(final Long accountId, final JsonCommand command) {
|
||||
context.authenticatedUser();
|
||||
final CurrentAccount account = findAccount(accountId);
|
||||
LocalDate rejectedOnDate = command.localDateValueOfParameterNamed("rejectedOnDate");
|
||||
if (rejectedOnDate == null) rejectedOnDate = LocalDate.now();
|
||||
account.reject(rejectedOnDate);
|
||||
currentAccountRepository.saveAndFlush(account);
|
||||
return new CommandProcessingResultBuilder().withEntityId(accountId).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult withdrawApplication(final Long accountId, final JsonCommand command) {
|
||||
context.authenticatedUser();
|
||||
final CurrentAccount account = findAccount(accountId);
|
||||
LocalDate withdrawnOnDate = command.localDateValueOfParameterNamed("withdrawnOnDate");
|
||||
if (withdrawnOnDate == null) withdrawnOnDate = LocalDate.now();
|
||||
account.withdraw(withdrawnOnDate);
|
||||
currentAccountRepository.saveAndFlush(account);
|
||||
return new CommandProcessingResultBuilder().withEntityId(accountId).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult closeAccount(final Long accountId, final JsonCommand command) {
|
||||
context.authenticatedUser();
|
||||
final CurrentAccount account = findAccount(accountId);
|
||||
LocalDate closedOnDate = command.localDateValueOfParameterNamed("closedOnDate");
|
||||
if (closedOnDate == null) closedOnDate = LocalDate.now();
|
||||
account.close(closedOnDate);
|
||||
currentAccountRepository.saveAndFlush(account);
|
||||
return new CommandProcessingResultBuilder().withEntityId(accountId).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult modifyApplication(final Long accountId, final JsonCommand command) {
|
||||
context.authenticatedUser();
|
||||
final CurrentAccount account = findAccount(accountId);
|
||||
if (command.parameterExists("msme")) {
|
||||
account.setMsme(command.booleanPrimitiveValueOfParameterNamed("msme"));
|
||||
}
|
||||
if (command.parameterExists("signatoryRights")) {
|
||||
account.setSignatoryRights(command.stringValueOfParameterNamed("signatoryRights"));
|
||||
}
|
||||
if (command.parameterExists("modeOfOperation")) {
|
||||
account.setModeOfOperation(command.stringValueOfParameterNamed("modeOfOperation"));
|
||||
}
|
||||
currentAccountRepository.saveAndFlush(account);
|
||||
return new CommandProcessingResultBuilder().withEntityId(accountId).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult deleteApplication(final Long accountId) {
|
||||
context.authenticatedUser();
|
||||
final CurrentAccount account = findAccount(accountId);
|
||||
currentAccountRepository.delete(account);
|
||||
return new CommandProcessingResultBuilder().withEntityId(accountId).build();
|
||||
}
|
||||
|
||||
// ─── helpers ──────────────────────────────────────────────────────────────
|
||||
|
||||
private CurrentAccount findAccount(Long accountId) {
|
||||
return currentAccountRepository.findById(accountId)
|
||||
.orElseThrow(() -> new SavingsAccountNotFoundException(accountId));
|
||||
}
|
||||
|
||||
private CurrentAccountFacilityConfig assembleFacilityConfig(CurrentAccount account, JsonCommand command) {
|
||||
final CurrentAccountFacilityConfig cfg = CurrentAccountFacilityConfig.createFor(account);
|
||||
final JsonObject root = command.parsedJson().getAsJsonObject();
|
||||
JsonObject fcJson = root.getAsJsonObject("accountFacilityConfig");
|
||||
if (fcJson == null) fcJson = root.getAsJsonObject("facilityConfig");
|
||||
if (fcJson == null) return cfg;
|
||||
|
||||
cfg.setAtmFacility(getBool(fcJson, "atmFacility"));
|
||||
cfg.setAtmWithdrawalFacility(getBool(fcJson, "atmWithdrawalFacility"));
|
||||
cfg.setUpiFacility(getBool(fcJson, "upiFacility"));
|
||||
cfg.setPosTransactionsFacility(getBool(fcJson, "posTransactionsFacility"));
|
||||
cfg.setChequeBook(getBool(fcJson, "chequeBook"));
|
||||
cfg.setImpsFacility(getBool(fcJson, "impsFacility"));
|
||||
cfg.setSmsAlerts(getBool(fcJson, "smsAlerts"));
|
||||
cfg.setBbpsFacility(getBool(fcJson, "bbpsFacility"));
|
||||
cfg.setInsuranceCover(getBool(fcJson, "insuranceCover"));
|
||||
cfg.setBepgFacility(getBool(fcJson, "bepgFacility"));
|
||||
cfg.setNeftFacility(getBool(fcJson, "neftFacility"));
|
||||
cfg.setRtgsFacility(getBool(fcJson, "rtgsFacility"));
|
||||
cfg.setInterBankTotalCapFacility(getBool(fcJson, "interBankTotalCapFacility"));
|
||||
cfg.setWithdrawalFacility(getBool(fcJson, "withdrawalFacility"));
|
||||
cfg.setDepositFacilityKyc(getBool(fcJson, "depositFacilityKyc"));
|
||||
cfg.setVirtualDebitCard(getBool(fcJson, "virtualDebitCard"));
|
||||
cfg.setInternetBanking(getBool(fcJson, "internetBanking"));
|
||||
cfg.setMobileBanking(getBool(fcJson, "mobileBanking"));
|
||||
return cfg;
|
||||
}
|
||||
|
||||
private void assembleJointHolders(CurrentAccount account, JsonCommand command) {
|
||||
final JsonArray arr = command.arrayOfParameterNamed("jointHolders");
|
||||
if (arr == null) return;
|
||||
for (JsonElement el : arr) {
|
||||
final JsonObject jo = el.getAsJsonObject();
|
||||
final CurrentAccountJointHolder holder = new CurrentAccountJointHolder();
|
||||
holder.setCurrentAccount(account);
|
||||
if (jo.has("clientId") && !jo.get("clientId").isJsonNull()) {
|
||||
holder.setClientId(jo.get("clientId").getAsLong());
|
||||
}
|
||||
if (jo.has("cifNumber") && !jo.get("cifNumber").isJsonNull()) {
|
||||
holder.setCifNumber(jo.get("cifNumber").getAsString());
|
||||
}
|
||||
if (jo.has("displayName") && !jo.get("displayName").isJsonNull()) {
|
||||
holder.setDisplayName(jo.get("displayName").getAsString());
|
||||
}
|
||||
if (jo.has("signingAuthority") && !jo.get("signingAuthority").isJsonNull()) {
|
||||
holder.setSigningAuthority(jo.get("signingAuthority").getAsString());
|
||||
}
|
||||
if (jo.has("role") && !jo.get("role").isJsonNull()) {
|
||||
holder.setRole(jo.get("role").getAsString());
|
||||
}
|
||||
account.getJointHolders().add(holder);
|
||||
}
|
||||
}
|
||||
|
||||
private void assemblePartners(CurrentAccount account, JsonCommand command) {
|
||||
final JsonArray arr = command.arrayOfParameterNamed("partners");
|
||||
if (arr == null) return;
|
||||
for (JsonElement el : arr) {
|
||||
final JsonObject jo = el.getAsJsonObject();
|
||||
final CurrentAccountPartner partner = new CurrentAccountPartner();
|
||||
partner.setCurrentAccount(account);
|
||||
if (jo.has("clientId") && !jo.get("clientId").isJsonNull()) {
|
||||
partner.setClientId(jo.get("clientId").getAsLong());
|
||||
}
|
||||
if (jo.has("clientCif") && !jo.get("clientCif").isJsonNull()) {
|
||||
partner.setClientCif(jo.get("clientCif").getAsString());
|
||||
}
|
||||
if (jo.has("clientName") && !jo.get("clientName").isJsonNull()) {
|
||||
partner.setClientName(jo.get("clientName").getAsString());
|
||||
}
|
||||
account.getPartners().add(partner);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean getBool(JsonObject obj, String key) {
|
||||
return obj.has(key) && !obj.get(key).isJsonNull() && obj.get(key).getAsBoolean();
|
||||
}
|
||||
|
||||
private boolean isBlankString(JsonObject obj, String key) {
|
||||
if (!obj.has(key) || obj.get(key).isJsonNull()) return true;
|
||||
return obj.get(key).getAsString().isBlank();
|
||||
}
|
||||
}
|
||||
+16
@@ -32,6 +32,8 @@ import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
||||
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.infrastructure.core.data.PaginationParameters;
|
||||
import org.apache.fineract.infrastructure.core.data.PaginationParametersDataValidator;
|
||||
@@ -70,6 +72,7 @@ import org.apache.fineract.portfolio.interestratechart.service.InterestRateChart
|
||||
import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData;
|
||||
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
||||
import org.apache.fineract.portfolio.paymenttype.service.PaymentTypeReadService;
|
||||
import org.apache.fineract.portfolio.savings.SavingsApiConstants;
|
||||
import org.apache.fineract.portfolio.savings.DepositAccountOnClosureType;
|
||||
import org.apache.fineract.portfolio.savings.DepositAccountType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsAccountTransactionType;
|
||||
@@ -132,6 +135,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
||||
private final CalendarReadPlatformService calendarReadPlatformService;
|
||||
private final PaymentTypeReadService paymentTypeReadPlatformService;
|
||||
private final AccountNumberGenerator accountNumberGenerator;
|
||||
private final CodeValueReadPlatformService codeValueReadPlatformService;
|
||||
|
||||
@Override
|
||||
public Collection<DepositAccountData> retrieveAll(final DepositAccountType depositAccountType,
|
||||
@@ -412,6 +416,18 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
||||
// Re-apply CBS product fields lost during factory method object creation
|
||||
((RecurringDepositAccountData) template).copyCbsFieldsFrom(rdTemplateWithCbs);
|
||||
|
||||
// Populate account type / customer segment options from code values
|
||||
try {
|
||||
final Collection<CodeValueData> accountTypeOpts = this.codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(SavingsApiConstants.RD_PRODUCT_ACCOUNT_TYPE);
|
||||
final Collection<CodeValueData> customerSegmentOpts = this.codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(SavingsApiConstants.RD_PRODUCT_CUSTOMER_SEGMENT);
|
||||
((RecurringDepositAccountData) template).setAccountTypeOptions(accountTypeOpts);
|
||||
((RecurringDepositAccountData) template).setCustomerSegmentOptions(customerSegmentOpts);
|
||||
} catch (final Exception ex) {
|
||||
log.warn("Failed to load RD account type/customer segment options: {}", ex.getMessage());
|
||||
}
|
||||
|
||||
// Generate preview account number
|
||||
try {
|
||||
final String preview = accountNumberGenerator.previewAccountNumber(productId, officeId);
|
||||
|
||||
+118
-10
@@ -215,7 +215,22 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
try {
|
||||
final String sql = "select " + this.savingAccountMapper.schema() + " where sa.id = ?";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, this.savingAccountMapper, new Object[] { accountId }); // NOSONAR
|
||||
final SavingsAccountData accountData = this.jdbcTemplate.queryForObject(sql, this.savingAccountMapper,
|
||||
new Object[] { accountId }); // NOSONAR
|
||||
|
||||
// Load joint holders
|
||||
if (accountData != null) {
|
||||
final String jointSql = "SELECT jh.id as id, jh.client_id as clientId, jh.cif_number as cifNumber, "
|
||||
+ "jh.display_name as displayName, jh.share_percentage as sharePercentage, "
|
||||
+ "jh.signing_authority as signingAuthority, jh.role as role, jh.is_primary as isPrimary "
|
||||
+ "FROM m_savings_account_joint_holders jh WHERE jh.savings_account_id = ?";
|
||||
final List<java.util.Map<String, Object>> jointHolders = this.jdbcTemplate.queryForList(jointSql, accountId);
|
||||
if (!jointHolders.isEmpty()) {
|
||||
accountData.setJointHolders(jointHolders);
|
||||
}
|
||||
}
|
||||
|
||||
return accountData;
|
||||
} catch (final EmptyResultDataAccessException e) {
|
||||
throw new SavingsAccountNotFoundException(accountId, e);
|
||||
}
|
||||
@@ -763,7 +778,43 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
sqlBuilder.append("sp.is_dormancy_tracking_active as isDormancyTrackingActive, ");
|
||||
sqlBuilder.append("sp.days_to_inactive as daysToInactive, ");
|
||||
sqlBuilder.append("sp.days_to_dormancy as daysToDormancy, ");
|
||||
sqlBuilder.append("sp.days_to_escheat as daysToEscheat ");
|
||||
sqlBuilder.append("sp.days_to_escheat as daysToEscheat, ");
|
||||
// CBS extended fields
|
||||
sqlBuilder.append("sa.cbs_account_type as cbsAccountType, ");
|
||||
sqlBuilder.append("sa.customer_segment as customerSegment, ");
|
||||
sqlBuilder.append("sa.account_status as accountStatus, ");
|
||||
sqlBuilder.append("sa.mode_of_operation as modeOfOperation, ");
|
||||
sqlBuilder.append("sa.special_category as specialCategory, ");
|
||||
sqlBuilder.append("sa.weaker_section as weakerSection, ");
|
||||
sqlBuilder.append("sa.guardian_name as guardianName, ");
|
||||
sqlBuilder.append("sa.guardian_cif_number as guardianCifNumber, ");
|
||||
sqlBuilder.append("sa.guardian_relationship as guardianRelationship, ");
|
||||
sqlBuilder.append("sa.minor_date_of_birth as minorDateOfBirth, ");
|
||||
sqlBuilder.append("sa.guardian_client_id as guardianClientId, ");
|
||||
sqlBuilder.append("sa.introducer_client_id as introducerClientId, ");
|
||||
sqlBuilder.append("sa.introducer_name as introducerName, ");
|
||||
sqlBuilder.append("sa.introducer_cif_number as introducerCifNumber, ");
|
||||
sqlBuilder.append("sa.nominee_data as nomineeData, ");
|
||||
sqlBuilder.append("sa.linked_account_id as linkedAccountId, ");
|
||||
sqlBuilder.append("sa.linked_account_type as linkedAccountType, ");
|
||||
sqlBuilder.append("sa.linked_account_no as linkedAccountNo, ");
|
||||
// Facility config fields
|
||||
sqlBuilder.append("safc.atm_facility as atmFacility, ");
|
||||
sqlBuilder.append("safc.atm_withdrawal_facility as atmWithdrawalFacility, ");
|
||||
sqlBuilder.append("safc.upi_facility as upiFacility, ");
|
||||
sqlBuilder.append("safc.pos_transactions_facility as posTransactionsFacility, ");
|
||||
sqlBuilder.append("safc.cheque_book as chequeBook, ");
|
||||
sqlBuilder.append("safc.imps_facility as impsFacility, ");
|
||||
sqlBuilder.append("safc.sms_alerts as smsAlerts, ");
|
||||
sqlBuilder.append("safc.bbps_facility as bbpsFacility, ");
|
||||
sqlBuilder.append("safc.insurance_cover as insuranceCover, ");
|
||||
sqlBuilder.append("safc.bepg_facility as bepgFacility, ");
|
||||
sqlBuilder.append("safc.neft_facility as neftFacility, ");
|
||||
sqlBuilder.append("safc.rtgs_facility as rtgsFacility, ");
|
||||
sqlBuilder.append("safc.inter_bank_total_cap_facility as interBankTotalCapFacility, ");
|
||||
sqlBuilder.append("safc.withdrawal_facility as withdrawalFacility, ");
|
||||
sqlBuilder.append("safc.deposit_facility_kyc as depositFacilityKyc, ");
|
||||
sqlBuilder.append("safc.virtual_debit_card as virtualDebitCard ");
|
||||
sqlBuilder.append("from m_savings_account sa ");
|
||||
sqlBuilder.append("join m_savings_product sp ON sa.product_id = sp.id ");
|
||||
sqlBuilder.append("join m_currency curr on curr.code = sa.currency_code ");
|
||||
@@ -777,6 +828,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
sqlBuilder.append("left join m_appuser avbu on avbu.id = sa.activatedon_userid ");
|
||||
sqlBuilder.append("left join m_appuser cbu on cbu.id = sa.closedon_userid ");
|
||||
sqlBuilder.append("left join m_tax_group tg on tg.id = sa.tax_group_id ");
|
||||
sqlBuilder.append("left join m_savings_account_facility_config safc on safc.savings_account_id = sa.id ");
|
||||
|
||||
this.schemaSql = sqlBuilder.toString();
|
||||
}
|
||||
@@ -970,14 +1022,70 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
taxGroupData = TaxGroupData.lookup(taxGroupId, taxGroupName);
|
||||
}
|
||||
|
||||
return SavingsAccountData.instance(id, accountNo, depositType, externalId, groupId, groupName, clientId, clientName, productId,
|
||||
productName, fieldOfficerId, fieldOfficerName, status, subStatus, reasonForBlock, timeline, currency,
|
||||
nominalAnnualInterestRate, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
|
||||
withdrawalFeeForTransfers, summary, allowOverdraft, overdraftLimit, minRequiredBalance, enforceMinRequiredBalance,
|
||||
maxAllowedLienLimit, lienAllowed, minBalanceForInterestCalculation, onHoldFunds, nominalAnnualInterestRateOverdraft,
|
||||
minOverdraftForInterestCalculation, withHoldTax, taxGroupData, lastActiveTransactionDate, isDormancyTrackingActive,
|
||||
daysToInactive, daysToDormancy, daysToEscheat, onHoldAmount);
|
||||
final SavingsAccountData accountData = SavingsAccountData.instance(id, accountNo, depositType, externalId, groupId, groupName,
|
||||
clientId, clientName, productId, productName, fieldOfficerId, fieldOfficerName, status, subStatus, reasonForBlock,
|
||||
timeline, currency, nominalAnnualInterestRate, interestCompoundingPeriodType, interestPostingPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, allowOverdraft, overdraftLimit, minRequiredBalance,
|
||||
enforceMinRequiredBalance, maxAllowedLienLimit, lienAllowed, minBalanceForInterestCalculation, onHoldFunds,
|
||||
nominalAnnualInterestRateOverdraft, minOverdraftForInterestCalculation, withHoldTax, taxGroupData,
|
||||
lastActiveTransactionDate, isDormancyTrackingActive, daysToInactive, daysToDormancy, daysToEscheat, onHoldAmount);
|
||||
|
||||
// CBS extended fields
|
||||
accountData.setCbsAccountType(rs.getString("cbsAccountType"));
|
||||
accountData.setCustomerSegment(rs.getString("customerSegment"));
|
||||
accountData.setAccountStatus(rs.getString("accountStatus"));
|
||||
accountData.setModeOfOperation(rs.getString("modeOfOperation"));
|
||||
accountData.setSpecialCategory(rs.getString("specialCategory"));
|
||||
accountData.setWeakerSection(rs.getString("weakerSection"));
|
||||
accountData.setGuardianName(rs.getString("guardianName"));
|
||||
accountData.setGuardianCifNumber(rs.getString("guardianCifNumber"));
|
||||
accountData.setGuardianRelationship(rs.getString("guardianRelationship"));
|
||||
accountData.setMinorDateOfBirth(JdbcSupport.getLocalDate(rs, "minorDateOfBirth"));
|
||||
accountData.setGuardianClientId(JdbcSupport.getLong(rs, "guardianClientId"));
|
||||
accountData.setIntroducerClientId(JdbcSupport.getLong(rs, "introducerClientId"));
|
||||
accountData.setIntroducerName(rs.getString("introducerName"));
|
||||
accountData.setIntroducerCifNumber(rs.getString("introducerCifNumber"));
|
||||
accountData.setLinkedAccountId(JdbcSupport.getLong(rs, "linkedAccountId"));
|
||||
accountData.setLinkedAccountType(rs.getString("linkedAccountType"));
|
||||
accountData.setLinkedAccountNo(rs.getString("linkedAccountNo"));
|
||||
|
||||
// Nominee as parsed map
|
||||
final String nomineeDataStr = rs.getString("nomineeData");
|
||||
if (nomineeDataStr != null && !nomineeDataStr.isEmpty()) {
|
||||
try {
|
||||
com.google.gson.Gson gson = new com.google.gson.Gson();
|
||||
@SuppressWarnings("unchecked")
|
||||
java.util.Map<String, Object> nomineeMap = gson.fromJson(nomineeDataStr,
|
||||
new com.google.gson.reflect.TypeToken<java.util.Map<String, Object>>() {}.getType());
|
||||
accountData.setNomineeData(nomineeMap);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
// Facility config
|
||||
final boolean hasFacilityConfig = rs.getObject("atmFacility") != null;
|
||||
if (hasFacilityConfig) {
|
||||
final java.util.Map<String, Object> facilityConfigMap = new java.util.LinkedHashMap<>();
|
||||
facilityConfigMap.put("atmFacility", rs.getBoolean("atmFacility"));
|
||||
facilityConfigMap.put("atmWithdrawalFacility", rs.getBoolean("atmWithdrawalFacility"));
|
||||
facilityConfigMap.put("upiFacility", rs.getBoolean("upiFacility"));
|
||||
facilityConfigMap.put("posTransactionsFacility", rs.getBoolean("posTransactionsFacility"));
|
||||
facilityConfigMap.put("chequeBook", rs.getBoolean("chequeBook"));
|
||||
facilityConfigMap.put("impsFacility", rs.getBoolean("impsFacility"));
|
||||
facilityConfigMap.put("smsAlerts", rs.getBoolean("smsAlerts"));
|
||||
facilityConfigMap.put("bbpsFacility", rs.getBoolean("bbpsFacility"));
|
||||
facilityConfigMap.put("insuranceCover", rs.getBoolean("insuranceCover"));
|
||||
facilityConfigMap.put("bepgFacility", rs.getBoolean("bepgFacility"));
|
||||
facilityConfigMap.put("neftFacility", rs.getBoolean("neftFacility"));
|
||||
facilityConfigMap.put("rtgsFacility", rs.getBoolean("rtgsFacility"));
|
||||
facilityConfigMap.put("interBankTotalCapFacility", rs.getBoolean("interBankTotalCapFacility"));
|
||||
facilityConfigMap.put("withdrawalFacility", rs.getBoolean("withdrawalFacility"));
|
||||
facilityConfigMap.put("depositFacilityKyc", rs.getBoolean("depositFacilityKyc"));
|
||||
facilityConfigMap.put("virtualDebitCard", rs.getBoolean("virtualDebitCard"));
|
||||
accountData.setAccountFacilityConfig(facilityConfigMap);
|
||||
}
|
||||
|
||||
return accountData;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
@@ -27,6 +27,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
||||
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
||||
@@ -194,6 +195,12 @@ public class SavingsAccountTemplateReadPlatformServiceImpl implements SavingsAcc
|
||||
final SavingsProductData fullProduct = this.savingsProductReadPlatformService.retrieveOne(productId);
|
||||
template.setAccountType(fullProduct.getAccountType());
|
||||
template.setCustomerSegment(fullProduct.getCustomerSegment());
|
||||
final Collection<CodeValueData> accountTypeOpts = this.codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(SavingsApiConstants.SAVINGS_PRODUCT_ACCOUNT_TYPE);
|
||||
final Collection<CodeValueData> customerSegmentOpts = this.codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(SavingsApiConstants.SAVINGS_PRODUCT_CUSTOMER_SEGMENT);
|
||||
template.setAccountTypeOptions(accountTypeOpts);
|
||||
template.setCustomerSegmentOptions(customerSegmentOpts);
|
||||
template.setProductCode(fullProduct.getProductCode());
|
||||
template.setEffectiveDate(fullProduct.getEffectiveDate());
|
||||
template.setEffectiveTo(fullProduct.getEffectiveTo());
|
||||
|
||||
+5
-4
@@ -228,12 +228,12 @@ public class SavingsConfiguration {
|
||||
StaffReadPlatformService staffReadPlatformService, DepositsDropdownReadPlatformService depositsDropdownReadPlatformService,
|
||||
SavingsAccountReadPlatformService savingsAccountReadPlatformService, DropdownReadPlatformService dropdownReadPlatformService,
|
||||
CalendarReadPlatformService calendarReadPlatformService, PaymentTypeReadService paymentTypeReadPlatformService,
|
||||
AccountNumberGenerator accountNumberGenerator) {
|
||||
AccountNumberGenerator accountNumberGenerator, CodeValueReadPlatformService codeValueReadPlatformService) {
|
||||
return new DepositAccountReadPlatformServiceImpl(context, jdbcTemplate, chartReadPlatformService, productChartReadPlatformService,
|
||||
paginationParametersDataValidator, sqlGenerator, paginationHelper, clientReadPlatformService, groupReadPlatformService,
|
||||
depositProductReadPlatformService, savingsDropdownReadPlatformService, chargeReadPlatformService, staffReadPlatformService,
|
||||
depositsDropdownReadPlatformService, savingsAccountReadPlatformService, dropdownReadPlatformService,
|
||||
calendarReadPlatformService, paymentTypeReadPlatformService, accountNumberGenerator);
|
||||
calendarReadPlatformService, paymentTypeReadPlatformService, accountNumberGenerator, codeValueReadPlatformService);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -385,10 +385,11 @@ public class SavingsConfiguration {
|
||||
GroupReadPlatformService groupReadPlatformService, CurrentProductReadPlatformService currentProductReadPlatformService,
|
||||
StaffReadPlatformService staffReadPlatformService, SavingsDropdownReadPlatformService dropdownReadPlatformService,
|
||||
ChargeReadPlatformService chargeReadPlatformService, EntityDatatableChecksReadService entityDatatableChecksReadService,
|
||||
ColumnValidator columnValidator, AccountNumberGenerator accountNumberGenerator) {
|
||||
ColumnValidator columnValidator, AccountNumberGenerator accountNumberGenerator,
|
||||
CodeValueReadPlatformService codeValueReadPlatformService) {
|
||||
return new CurrentAccountTemplateReadPlatformServiceImpl(context, jdbcTemplate, clientReadPlatformService, groupReadPlatformService,
|
||||
currentProductReadPlatformService, staffReadPlatformService, dropdownReadPlatformService, chargeReadPlatformService,
|
||||
entityDatatableChecksReadService, columnValidator, accountNumberGenerator);
|
||||
entityDatatableChecksReadService, columnValidator, accountNumberGenerator, codeValueReadPlatformService);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -283,4 +283,5 @@
|
||||
<include file="parts/0254_fix_ckyc_batch_audit_columns.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0255_add_ckyc_batch_id_to_client_kyc.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0273_add_gl_account_id_to_current_product.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0276_create_current_account_tables.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
+1
@@ -5,6 +5,7 @@
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<changeSet id="0272_insert_rd_base_rate_version" author="fineract">
|
||||
<validCheckSum>9:4cb4d062d4ee9464fe5a4e32023580c2</validCheckSum>
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_rd_base_interest_rate_effective</sqlCheck>
|
||||
</preConditions>
|
||||
|
||||
+393
@@ -0,0 +1,393 @@
|
||||
<?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.3.xsd">
|
||||
|
||||
<!-- =========================================================
|
||||
m_current_account — main current account table
|
||||
(fully separate from m_savings_account)
|
||||
========================================================= -->
|
||||
<changeSet id="0276_create_current_account_tables" author="system">
|
||||
|
||||
<createTable tableName="m_current_account">
|
||||
<column name="id" type="bigint" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="account_no" type="varchar(20)">
|
||||
<constraints nullable="false" unique="true" uniqueConstraintName="ca_unq_account_no"/>
|
||||
</column>
|
||||
<column name="external_id" type="varchar(100)">
|
||||
<constraints nullable="true" unique="true" uniqueConstraintName="ca_unq_external_id"/>
|
||||
</column>
|
||||
|
||||
<!-- Ownership -->
|
||||
<column name="client_id" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_ca_client" referencedTableName="m_client" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="group_id" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_ca_group" referencedTableName="m_group" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="product_id" type="bigint">
|
||||
<constraints nullable="false" foreignKeyName="fk_ca_product" referencedTableName="m_current_product" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="office_id" type="bigint">
|
||||
<constraints nullable="false" foreignKeyName="fk_ca_office" referencedTableName="m_office" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="staff_id" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_ca_staff" referencedTableName="m_staff" referencedColumnNames="id"/>
|
||||
</column>
|
||||
|
||||
<!-- Status -->
|
||||
<column name="status_enum" type="smallint" defaultValue="100">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<!-- 100=Submitted, 200=Approved, 300=Active, 400=Withdrawn, 500=Rejected, 600=Closed -->
|
||||
<column name="sub_status_enum" type="smallint" defaultValue="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<!-- 0=None, 100=Inactive, 200=Dormant, 300=Escheat, 400=Block, 500=BlockDebit, 600=BlockCredit -->
|
||||
<column name="account_type_enum" type="smallint" defaultValue="1">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<!-- 1=Individual, 2=Group, 3=JLG -->
|
||||
|
||||
<!-- Lifecycle dates -->
|
||||
<column name="submittedon_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="submittedon_userid" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_ca_submit_user" referencedTableName="m_appuser" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="approvedon_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="approvedon_userid" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_ca_approve_user" referencedTableName="m_appuser" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="activatedon_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="activatedon_userid" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_ca_activate_user" referencedTableName="m_appuser" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="rejectedon_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="rejectedon_userid" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_ca_reject_user" referencedTableName="m_appuser" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="withdrawnon_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="withdrawnon_userid" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_ca_withdraw_user" referencedTableName="m_appuser" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="closedon_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="closedon_userid" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_ca_close_user" referencedTableName="m_appuser" referencedColumnNames="id"/>
|
||||
</column>
|
||||
|
||||
<!-- Currency (copied from product at account creation) -->
|
||||
<column name="currency_code" type="varchar(3)"><constraints nullable="false"/></column>
|
||||
<column name="currency_digits" type="smallint"><constraints nullable="false"/></column>
|
||||
<column name="currency_multiplesof" type="smallint"><constraints nullable="true"/></column>
|
||||
|
||||
<!-- Interest settings (copied from product) -->
|
||||
<column name="nominal_annual_interest_rate" type="decimal(19,6)" defaultValue="0"><constraints nullable="false"/></column>
|
||||
<column name="interest_compounding_period_enum" type="smallint"><constraints nullable="false"/></column>
|
||||
<column name="interest_posting_period_enum" type="smallint"><constraints nullable="false"/></column>
|
||||
<column name="interest_calculation_type_enum" type="smallint"><constraints nullable="false"/></column>
|
||||
<column name="interest_calculation_days_in_year_type_enum" type="smallint"><constraints nullable="false"/></column>
|
||||
<column name="min_balance_for_interest_calculation" type="decimal(19,6)"><constraints nullable="true"/></column>
|
||||
<column name="start_interest_calculation_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="accrued_till_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="last_interest_calculation_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="last_closed_business_date" type="date"><constraints nullable="true"/></column>
|
||||
|
||||
<!-- Tax -->
|
||||
<column name="withhold_tax" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="tax_group_id" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_ca_tax_group" referencedTableName="m_tax_group" referencedColumnNames="id"/>
|
||||
</column>
|
||||
|
||||
<!-- Balance rules (copied from product) -->
|
||||
<column name="min_required_opening_balance" type="decimal(19,6)"><constraints nullable="true"/></column>
|
||||
<column name="lockin_period_frequency" type="smallint"><constraints nullable="true"/></column>
|
||||
<column name="lockin_period_frequency_enum" type="smallint"><constraints nullable="true"/></column>
|
||||
<column name="lockedin_until_date_derived" type="date"><constraints nullable="true"/></column>
|
||||
<column name="enforce_min_required_balance" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="min_required_balance" type="decimal(19,6)"><constraints nullable="true"/></column>
|
||||
|
||||
<!-- Overdraft (copied from product) -->
|
||||
<column name="allow_overdraft" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="overdraft_limit" type="decimal(19,6)"><constraints nullable="true"/></column>
|
||||
<column name="nominal_annual_interest_rate_overdraft" type="decimal(19,6)"><constraints nullable="true"/></column>
|
||||
<column name="min_overdraft_for_interest_calculation" type="decimal(19,6)"><constraints nullable="true"/></column>
|
||||
|
||||
<!-- Lien -->
|
||||
<column name="is_lien_allowed" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="max_allowed_lien_limit" type="decimal(19,6)"><constraints nullable="true"/></column>
|
||||
<column name="on_hold_funds_derived" type="decimal(19,6)" defaultValue="0"><constraints nullable="false"/></column>
|
||||
|
||||
<!-- Running balance summary -->
|
||||
<column name="account_balance_derived" type="decimal(19,6)" defaultValue="0"><constraints nullable="false"/></column>
|
||||
<column name="total_deposits_derived" type="decimal(19,6)" defaultValue="0"><constraints nullable="false"/></column>
|
||||
<column name="total_withdrawals_derived" type="decimal(19,6)" defaultValue="0"><constraints nullable="false"/></column>
|
||||
<column name="total_interest_earned_derived" type="decimal(19,6)" defaultValue="0"><constraints nullable="false"/></column>
|
||||
<column name="total_interest_posted_derived" type="decimal(19,6)" defaultValue="0"><constraints nullable="false"/></column>
|
||||
<column name="total_overdraft_interest_derived" type="decimal(19,6)" defaultValue="0"><constraints nullable="false"/></column>
|
||||
<column name="total_withhold_tax_derived" type="decimal(19,6)" defaultValue="0"><constraints nullable="false"/></column>
|
||||
<column name="total_savings_amount_on_hold" type="decimal(19,6)" defaultValue="0"><constraints nullable="false"/></column>
|
||||
<column name="withdrawal_fee_for_transfer" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
|
||||
<!-- Block reason -->
|
||||
<column name="reason_for_block" type="varchar(500)"><constraints nullable="true"/></column>
|
||||
|
||||
<!-- Current-account-specific fields -->
|
||||
<column name="msme" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="auto_debit_facility" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="balance_swap_option" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="establishment_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="start_operation_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="is_non_individual_client" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="signatory_rights" type="varchar(100)"><constraints nullable="true"/></column>
|
||||
|
||||
<!-- CBS account type / segment -->
|
||||
<column name="cbs_account_type" type="varchar(100)"><constraints nullable="true"/></column>
|
||||
<column name="customer_segment" type="varchar(100)"><constraints nullable="true"/></column>
|
||||
<column name="account_status" type="varchar(50)"><constraints nullable="true"/></column>
|
||||
<column name="mode_of_operation" type="varchar(50)"><constraints nullable="true"/></column>
|
||||
<column name="special_category" type="varchar(100)"><constraints nullable="true"/></column>
|
||||
|
||||
<!-- Introducer -->
|
||||
<column name="introducer_client_id" type="bigint"><constraints nullable="true"/></column>
|
||||
<column name="introducer_name" type="varchar(200)"><constraints nullable="true"/></column>
|
||||
<column name="introducer_cif_number" type="varchar(50)"><constraints nullable="true"/></column>
|
||||
|
||||
<!-- Nominee (JSON) -->
|
||||
<column name="nominee_data" type="text"><constraints nullable="true"/></column>
|
||||
|
||||
<!-- Interest calculation settings from product -->
|
||||
<column name="interest_calculate_selector" type="smallint"><constraints nullable="true"/></column>
|
||||
<column name="average_period" type="varchar(20)"><constraints nullable="true"/></column>
|
||||
<column name="auto_post" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="frequency_fix_day" type="smallint"><constraints nullable="true"/></column>
|
||||
<column name="enable_lockin_period" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="balance_frequency" type="varchar(50)"><constraints nullable="true"/></column>
|
||||
<column name="avg_balance_calc_period" type="varchar(10)"><constraints nullable="true"/></column>
|
||||
|
||||
<!-- Audit -->
|
||||
<column name="created_by" type="bigint"><constraints nullable="true"/></column>
|
||||
<column name="created_date" type="datetime"><constraints nullable="true"/></column>
|
||||
<column name="last_modified_by" type="bigint"><constraints nullable="true"/></column>
|
||||
<column name="last_modified_date" type="datetime"><constraints nullable="true"/></column>
|
||||
</createTable>
|
||||
|
||||
<!-- =========================================================
|
||||
m_current_account_transaction
|
||||
========================================================= -->
|
||||
<createTable tableName="m_current_account_transaction">
|
||||
<column name="id" type="bigint" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="current_account_id" type="bigint">
|
||||
<constraints nullable="false" foreignKeyName="fk_cat_account" referencedTableName="m_current_account" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="office_id" type="bigint">
|
||||
<constraints nullable="false" foreignKeyName="fk_cat_office" referencedTableName="m_office" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="payment_detail_id" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_cat_payment" referencedTableName="m_payment_detail" referencedColumnNames="id"/>
|
||||
</column>
|
||||
|
||||
<!-- Type: 1=Deposit, 2=Withdrawal, 3=Interest, 4=Charge, 5=ChargeWaiver, 6=Transfer, 7=Reversal -->
|
||||
<column name="transaction_type_enum" type="smallint"><constraints nullable="false"/></column>
|
||||
<column name="transaction_date" type="date"><constraints nullable="false"/></column>
|
||||
<column name="amount" type="decimal(19,6)"><constraints nullable="false"/></column>
|
||||
<column name="ref_no" type="varchar(100)"><constraints nullable="true"/></column>
|
||||
<column name="remarks" type="varchar(500)"><constraints nullable="true"/></column>
|
||||
|
||||
<!-- State -->
|
||||
<column name="is_reversed" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="is_reversal" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="original_transaction_id" type="bigint"><constraints nullable="true"/></column>
|
||||
<column name="is_manual" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
|
||||
<!-- Balance -->
|
||||
<column name="running_balance_derived" type="decimal(19,6)"><constraints nullable="true"/></column>
|
||||
<column name="cumulative_balance_derived" type="decimal(19,6)"><constraints nullable="true"/></column>
|
||||
<column name="balance_end_date_derived" type="date"><constraints nullable="true"/></column>
|
||||
<column name="balance_number_of_days_derived" type="integer"><constraints nullable="true"/></column>
|
||||
<column name="overdraft_amount_derived" type="decimal(19,6)"><constraints nullable="true"/></column>
|
||||
|
||||
<!-- Lien / Hold -->
|
||||
<column name="is_lien_transaction" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="release_id_of_hold_amount_transaction" type="bigint"><constraints nullable="true"/></column>
|
||||
<column name="reason_for_block" type="varchar(200)"><constraints nullable="true"/></column>
|
||||
|
||||
<column name="submitted_on_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="created_date" type="datetime"><constraints nullable="true"/></column>
|
||||
<column name="created_by" type="bigint"><constraints nullable="true"/></column>
|
||||
</createTable>
|
||||
|
||||
<!-- =========================================================
|
||||
m_current_account_charge
|
||||
========================================================= -->
|
||||
<createTable tableName="m_current_account_charge">
|
||||
<column name="id" type="bigint" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="current_account_id" type="bigint">
|
||||
<constraints nullable="false" foreignKeyName="fk_cac_account" referencedTableName="m_current_account" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="charge_id" type="bigint">
|
||||
<constraints nullable="false" foreignKeyName="fk_cac_charge" referencedTableName="m_charge" referencedColumnNames="id"/>
|
||||
</column>
|
||||
|
||||
<column name="charge_time_enum" type="smallint"><constraints nullable="false"/></column>
|
||||
<column name="charge_due_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="fee_on_month" type="smallint"><constraints nullable="true"/></column>
|
||||
<column name="fee_on_day" type="smallint"><constraints nullable="true"/></column>
|
||||
<column name="fee_interval" type="smallint"><constraints nullable="true"/></column>
|
||||
|
||||
<column name="charge_calculation_enum" type="smallint"><constraints nullable="false"/></column>
|
||||
<column name="calculation_percentage" type="decimal(19,6)"><constraints nullable="true"/></column>
|
||||
<column name="calculation_on_amount" type="decimal(19,6)"><constraints nullable="true"/></column>
|
||||
<column name="amount" type="decimal(19,6)"><constraints nullable="false"/></column>
|
||||
|
||||
<column name="amount_paid_derived" type="decimal(19,6)" defaultValue="0"><constraints nullable="false"/></column>
|
||||
<column name="amount_waived_derived" type="decimal(19,6)" defaultValue="0"><constraints nullable="false"/></column>
|
||||
<column name="amount_writtenoff_derived" type="decimal(19,6)" defaultValue="0"><constraints nullable="false"/></column>
|
||||
<column name="amount_outstanding_derived" type="decimal(19,6)"><constraints nullable="false"/></column>
|
||||
|
||||
<column name="is_paid_derived" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="waived" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="is_penalty" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true"><constraints nullable="false"/></column>
|
||||
<column name="inactivated_on_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="free_withdrawal_count" type="integer"><constraints nullable="true"/></column>
|
||||
<column name="charge_reset_date" type="date"><constraints nullable="true"/></column>
|
||||
</createTable>
|
||||
|
||||
<!-- =========================================================
|
||||
m_current_account_facility_config
|
||||
ATM / NEFT / RTGS / Cheque Book etc.
|
||||
========================================================= -->
|
||||
<createTable tableName="m_current_account_facility_config">
|
||||
<column name="id" type="bigint" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="current_account_id" type="bigint">
|
||||
<constraints nullable="false" unique="true" uniqueConstraintName="ca_fac_unq_account"
|
||||
foreignKeyName="fk_cafac_account" referencedTableName="m_current_account" referencedColumnNames="id"/>
|
||||
</column>
|
||||
|
||||
<column name="atm_facility" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="atm_withdrawal_facility" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="upi_facility" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="pos_transactions_facility" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="cheque_book" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="imps_facility" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="sms_alerts" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="bbps_facility" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="insurance_cover" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="bepg_facility" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="neft_facility" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="rtgs_facility" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="inter_bank_total_cap_facility" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="withdrawal_facility" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="deposit_facility_kyc" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="virtual_debit_card" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="internet_banking" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
<column name="mobile_banking" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
</createTable>
|
||||
|
||||
<!-- =========================================================
|
||||
m_current_account_joint_holder
|
||||
Joint account holders
|
||||
========================================================= -->
|
||||
<createTable tableName="m_current_account_joint_holder">
|
||||
<column name="id" type="bigint" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="current_account_id" type="bigint">
|
||||
<constraints nullable="false" foreignKeyName="fk_cajh_account" referencedTableName="m_current_account" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="client_id" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_cajh_client" referencedTableName="m_client" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="cif_number" type="varchar(50)"><constraints nullable="true"/></column>
|
||||
<column name="display_name" type="varchar(200)"><constraints nullable="true"/></column>
|
||||
<column name="share_percentage" type="decimal(5,2)"><constraints nullable="true"/></column>
|
||||
<column name="signing_authority" type="varchar(100)"><constraints nullable="true"/></column>
|
||||
<column name="role" type="varchar(100)"><constraints nullable="true"/></column>
|
||||
<column name="is_primary" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
</createTable>
|
||||
|
||||
<!-- =========================================================
|
||||
m_current_account_partner
|
||||
Partners for non-individual (business) current accounts
|
||||
========================================================= -->
|
||||
<createTable tableName="m_current_account_partner">
|
||||
<column name="id" type="bigint" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="current_account_id" type="bigint">
|
||||
<constraints nullable="false" foreignKeyName="fk_cap_account" referencedTableName="m_current_account" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="client_id" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_cap_client" referencedTableName="m_client" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="client_cif" type="varchar(50)"><constraints nullable="true"/></column>
|
||||
<column name="client_name" type="varchar(200)"><constraints nullable="true"/></column>
|
||||
<column name="share_percentage" type="decimal(5,2)"><constraints nullable="true"/></column>
|
||||
<column name="is_mandatory" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
</createTable>
|
||||
|
||||
<!-- =========================================================
|
||||
m_current_account_officer_history
|
||||
Officer assignment history
|
||||
========================================================= -->
|
||||
<createTable tableName="m_current_account_officer_history">
|
||||
<column name="id" type="bigint" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="current_account_id" type="bigint">
|
||||
<constraints nullable="false" foreignKeyName="fk_caoh_account" referencedTableName="m_current_account" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="staff_id" type="bigint">
|
||||
<constraints nullable="true" foreignKeyName="fk_caoh_staff" referencedTableName="m_staff" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="start_date" type="date"><constraints nullable="false"/></column>
|
||||
<column name="end_date" type="date"><constraints nullable="true"/></column>
|
||||
<column name="created_by_id" type="bigint"><constraints nullable="true"/></column>
|
||||
</createTable>
|
||||
|
||||
<!-- =========================================================
|
||||
m_current_account_on_hold_transaction
|
||||
On-hold / lien funds
|
||||
========================================================= -->
|
||||
<createTable tableName="m_current_account_on_hold_transaction">
|
||||
<column name="id" type="bigint" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="current_account_id" type="bigint">
|
||||
<constraints nullable="false" foreignKeyName="fk_caoht_account" referencedTableName="m_current_account" referencedColumnNames="id"/>
|
||||
</column>
|
||||
<column name="amount" type="decimal(19,6)"><constraints nullable="false"/></column>
|
||||
<!-- 1=Hold, 2=Release -->
|
||||
<column name="transaction_type_enum" type="smallint"><constraints nullable="false"/></column>
|
||||
<column name="transaction_date" type="date"><constraints nullable="false"/></column>
|
||||
<column name="is_reversed" type="boolean" defaultValueBoolean="false"><constraints nullable="false"/></column>
|
||||
</createTable>
|
||||
|
||||
<!-- Indexes for fast lookup -->
|
||||
<createIndex indexName="idx_ca_client_id" tableName="m_current_account">
|
||||
<column name="client_id"/>
|
||||
</createIndex>
|
||||
<createIndex indexName="idx_ca_product_id" tableName="m_current_account">
|
||||
<column name="product_id"/>
|
||||
</createIndex>
|
||||
<createIndex indexName="idx_ca_status" tableName="m_current_account">
|
||||
<column name="status_enum"/>
|
||||
</createIndex>
|
||||
<createIndex indexName="idx_cat_account_id" tableName="m_current_account_transaction">
|
||||
<column name="current_account_id"/>
|
||||
</createIndex>
|
||||
<createIndex indexName="idx_cat_date" tableName="m_current_account_transaction">
|
||||
<column name="transaction_date"/>
|
||||
</createIndex>
|
||||
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+11
@@ -151,6 +151,15 @@
|
||||
<class>org.apache.fineract.portfolio.self.pockets.domain.PocketAccountMapping</class>
|
||||
<class>org.apache.fineract.portfolio.self.registration.domain.SelfServiceRegistration</class>
|
||||
|
||||
<!-- Current Account Entities -->
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccount</class>
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountTransaction</class>
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountCharge</class>
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountFacilityConfig</class>
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountJointHolder</class>
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountPartner</class>
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountOfficerHistory</class>
|
||||
|
||||
<!-- Charge Module Entities -->
|
||||
<class>org.apache.fineract.portfolio.charge.domain.Charge</class>
|
||||
|
||||
@@ -263,6 +272,8 @@
|
||||
<class>org.apache.fineract.portfolio.savings.domain.SavingsProductDepositLimitKyc</class>
|
||||
<class>org.apache.fineract.portfolio.savings.domain.SavingsProductFacilityConfig</class>
|
||||
<class>org.apache.fineract.portfolio.savings.domain.SavingsProductFacilityLimit</class>
|
||||
<class>org.apache.fineract.portfolio.savings.domain.SavingsAccountFacilityConfig</class>
|
||||
<class>org.apache.fineract.portfolio.savings.domain.SavingsAccountJointHolder</class>
|
||||
|
||||
<!-- Progressive Loan Module Entities -->
|
||||
<class>org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeBalance</class>
|
||||
|
||||
+7
-1
@@ -30,6 +30,7 @@ import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationC
|
||||
import org.apache.fineract.infrastructure.configuration.data.GlobalConfigurationPropertyData;
|
||||
import org.apache.fineract.infrastructure.configuration.service.ConfigurationReadPlatformService;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepository;
|
||||
import org.apache.fineract.portfolio.account.service.AccountNumberGenerator;
|
||||
import org.apache.fineract.portfolio.client.domain.Client;
|
||||
import org.apache.fineract.portfolio.client.domain.ClientRepository;
|
||||
@@ -39,6 +40,7 @@ import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepository;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsProduct;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsProductRepository;
|
||||
import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount;
|
||||
import org.apache.fineract.portfolio.shareproducts.domain.ShareProduct;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -50,6 +52,8 @@ public class AccountNumberGeneratorTest {
|
||||
private ClientRepository clientRepo;
|
||||
private LoanRepository loanRepo;
|
||||
private SavingsAccountRepository savingsRepo;
|
||||
private GLAccountRepository glAccountRepo;
|
||||
private SavingsProductRepository savingsProductRepo;
|
||||
|
||||
private AccountNumberGenerator generator;
|
||||
|
||||
@@ -59,8 +63,10 @@ public class AccountNumberGeneratorTest {
|
||||
clientRepo = mock(ClientRepository.class);
|
||||
loanRepo = mock(LoanRepository.class);
|
||||
savingsRepo = mock(SavingsAccountRepository.class);
|
||||
glAccountRepo = mock(GLAccountRepository.class);
|
||||
savingsProductRepo = mock(SavingsProductRepository.class);
|
||||
|
||||
generator = new AccountNumberGenerator(configService, clientRepo, loanRepo, savingsRepo);
|
||||
generator = new AccountNumberGenerator(configService, clientRepo, loanRepo, savingsRepo, glAccountRepo, savingsProductRepo);
|
||||
|
||||
GlobalConfigurationPropertyData accountLengthConfig = mock(GlobalConfigurationPropertyData.class);
|
||||
when(accountLengthConfig.getValue()).thenReturn(Long.valueOf("9"));
|
||||
|
||||
+8
-2
@@ -82,13 +82,19 @@ public class SavingsApiSetConstants extends SavingsApiConstants {
|
||||
"minBalanceForInterestCalculation", "minOverdraftForInterestCalculation",
|
||||
"periodFrequencyOptions",
|
||||
// CBS Product fields
|
||||
"accountType", "customerSegment", "productCode", "glAccountId", "glAccountName", "effectiveTo", "endDate", "introducerRequired", "shareLinkingEnabled",
|
||||
"accountType", "customerSegment", "accountTypeOptions", "customerSegmentOptions", "productCode", "glAccountId", "glAccountName", "effectiveTo", "endDate", "introducerRequired", "shareLinkingEnabled",
|
||||
"nominationFacility", "dormancyAlert", "enableLockinPeriod", "balanceFrequency",
|
||||
"accountClosedZeroBalanceInDayClosing", "accountFacilityConfig", "accountFacilityLimits", "depositLimitKyc",
|
||||
"interestCalculateSelector", "averagePeriod", "autoPost", "frequencyFixDay", "lastInterestDate",
|
||||
"balanceSwapOption", "msme", "autoDebitFacility", "interestCalculationTypeOption",
|
||||
"effectiveDate", "isDormancyTrackingActive", "daysToInactive", "daysToDormancy", "daysToEscheat",
|
||||
"avgBalanceCalcPeriod", "validForPeriod", "odAccountClosedZeroBalanceInDayClosing"));
|
||||
"avgBalanceCalcPeriod", "validForPeriod", "odAccountClosedZeroBalanceInDayClosing",
|
||||
// CBS Account fields
|
||||
"cbsAccountType", "accountStatus", "modeOfOperation", "specialCategory", "weakerSection",
|
||||
"guardianName", "guardianCifNumber", "guardianRelationship", "guardianClientId", "minorDateOfBirth",
|
||||
"introducerClientId", "introducerName", "introducerCifNumber",
|
||||
"nomineeData", "linkedAccountId", "linkedAccountType", "linkedAccountNo",
|
||||
"jointHolders"));
|
||||
|
||||
protected static final Set<String> SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<>(
|
||||
Arrays.asList(idParamName, "accountId", accountNoParamName, "currency", "amount", dateParamName, paymentDetailDataParamName,
|
||||
|
||||
+13
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.savings.data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collection;
|
||||
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
@@ -86,6 +87,8 @@ public final class RecurringDepositAccountData extends DepositAccountData {
|
||||
// CBS product fields (populated from product template)
|
||||
private String accountType;
|
||||
private String customerSegment;
|
||||
private Collection<CodeValueData> accountTypeOptions;
|
||||
private Collection<CodeValueData> customerSegmentOptions;
|
||||
private String productCode;
|
||||
private LocalDate effectiveDate;
|
||||
private LocalDate effectiveTo;
|
||||
@@ -122,10 +125,20 @@ public final class RecurringDepositAccountData extends DepositAccountData {
|
||||
private Boolean deceasedSettlement;
|
||||
private Boolean allowDebitTxnAfterDueDate;
|
||||
|
||||
public void setAccountTypeOptions(Collection<CodeValueData> accountTypeOptions) {
|
||||
this.accountTypeOptions = accountTypeOptions;
|
||||
}
|
||||
|
||||
public void setCustomerSegmentOptions(Collection<CodeValueData> customerSegmentOptions) {
|
||||
this.customerSegmentOptions = customerSegmentOptions;
|
||||
}
|
||||
|
||||
public void copyCbsFieldsFrom(final RecurringDepositAccountData src) {
|
||||
if (src == null) return;
|
||||
this.accountType = src.accountType;
|
||||
this.customerSegment = src.customerSegment;
|
||||
this.accountTypeOptions = src.accountTypeOptions;
|
||||
this.customerSegmentOptions = src.customerSegmentOptions;
|
||||
this.productCode = src.productCode;
|
||||
this.effectiveDate = src.effectiveDate;
|
||||
this.effectiveTo = src.effectiveTo;
|
||||
|
||||
+9
-1
@@ -39,7 +39,15 @@ public class SavingsAccountConstant extends SavingsApiConstants {
|
||||
withdrawalFeeForTransfersParamName, feeAmountParamName, feeOnMonthDayParamName, chargesParamName, allowOverdraftParamName,
|
||||
overdraftLimitParamName, minRequiredBalanceParamName, enforceMinRequiredBalanceParamName, lienAllowedParamName,
|
||||
maxAllowedLienLimitParamName, nominalAnnualInterestRateOverdraftParamName, minOverdraftForInterestCalculationParamName,
|
||||
withHoldTaxParamName, datatables, gsimApplicationId, gsimLastApplication));
|
||||
withHoldTaxParamName, datatables, gsimApplicationId, gsimLastApplication,
|
||||
// CBS Account fields
|
||||
"accountType", "customerSegment", accountStatusParamName, modeOfOperationParamName,
|
||||
specialCategoryParamName, weakerSectionParamName,
|
||||
guardianNameParamName, guardianCifNumberParamName, guardianRelationshipParamName,
|
||||
guardianClientIdParamName, minorDateOfBirthParamName,
|
||||
introducerIdParamName, introducerNameParamName, introducerCifNumberParamName,
|
||||
nomineeParamName, linkedAccountIdParamName, linkedAccountTypeParamName, linkedAccountNoParamName,
|
||||
accountFacilityConfigParamName, jointHoldersParamName));
|
||||
|
||||
/**
|
||||
* These parameters will match the class level parameters of {@link SavingsAccountData}. Where possible, we try to
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ package org.apache.fineract.portfolio.savings.domain;
|
||||
import jakarta.persistence.DiscriminatorValue;
|
||||
import jakarta.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
@Entity(name = "SavingsCurrentAccount")
|
||||
@DiscriminatorValue("400")
|
||||
public class CurrentAccount extends SavingsAccount {
|
||||
|
||||
|
||||
+122
@@ -3900,4 +3900,126 @@ public class SavingsAccount extends AbstractAuditableWithUTCDateTimeCustom<Long>
|
||||
public DepositAccountType depositAccountType() {
|
||||
return DepositAccountType.fromInt(100);
|
||||
}
|
||||
|
||||
// ─── CBS extended fields ───────────────────────────────────────────────────
|
||||
|
||||
@Column(name = "cbs_account_type", length = 100)
|
||||
private String cbsAccountType;
|
||||
|
||||
@Column(name = "customer_segment", length = 100)
|
||||
private String customerSegment;
|
||||
|
||||
@Column(name = "account_status", length = 50)
|
||||
private String accountStatus;
|
||||
|
||||
@Column(name = "mode_of_operation", length = 50)
|
||||
private String modeOfOperation;
|
||||
|
||||
@Column(name = "special_category", length = 100)
|
||||
private String specialCategory;
|
||||
|
||||
@Column(name = "weaker_section", length = 100)
|
||||
private String weakerSection;
|
||||
|
||||
@Column(name = "guardian_name", length = 200)
|
||||
private String guardianName;
|
||||
|
||||
@Column(name = "guardian_cif_number", length = 50)
|
||||
private String guardianCifNumber;
|
||||
|
||||
@Column(name = "guardian_relationship", length = 100)
|
||||
private String guardianRelationship;
|
||||
|
||||
@Column(name = "minor_date_of_birth")
|
||||
private LocalDate minorDateOfBirth;
|
||||
|
||||
@Column(name = "guardian_client_id")
|
||||
private Long guardianClientId;
|
||||
|
||||
@Column(name = "introducer_client_id")
|
||||
private Long introducerClientId;
|
||||
|
||||
@Column(name = "introducer_name", length = 200)
|
||||
private String introducerName;
|
||||
|
||||
@Column(name = "introducer_cif_number", length = 50)
|
||||
private String introducerCifNumber;
|
||||
|
||||
@Column(name = "nominee_data", columnDefinition = "TEXT")
|
||||
private String nomineeData;
|
||||
|
||||
@Column(name = "linked_account_id")
|
||||
private Long linkedAccountId;
|
||||
|
||||
@Column(name = "linked_account_type", length = 20)
|
||||
private String linkedAccountType;
|
||||
|
||||
@Column(name = "linked_account_no", length = 50)
|
||||
private String linkedAccountNo;
|
||||
|
||||
@jakarta.persistence.OneToOne(cascade = jakarta.persistence.CascadeType.ALL, mappedBy = "savingsAccount", orphanRemoval = true, fetch = FetchType.LAZY)
|
||||
private SavingsAccountFacilityConfig facilityConfig;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "savingsAccount", orphanRemoval = true, fetch = FetchType.LAZY)
|
||||
private List<SavingsAccountJointHolder> jointHolders = new ArrayList<>();
|
||||
|
||||
public String getCbsAccountType() { return cbsAccountType; }
|
||||
public void setCbsAccountType(String v) { this.cbsAccountType = v; }
|
||||
|
||||
public String getCustomerSegment() { return customerSegment; }
|
||||
public void setCustomerSegment(String v) { this.customerSegment = v; }
|
||||
|
||||
public String getAccountStatus() { return accountStatus; }
|
||||
public void setAccountStatus(String v) { this.accountStatus = v; }
|
||||
|
||||
public String getModeOfOperation() { return modeOfOperation; }
|
||||
public void setModeOfOperation(String v) { this.modeOfOperation = v; }
|
||||
|
||||
public String getSpecialCategory() { return specialCategory; }
|
||||
public void setSpecialCategory(String v) { this.specialCategory = v; }
|
||||
|
||||
public String getWeakerSection() { return weakerSection; }
|
||||
public void setWeakerSection(String v) { this.weakerSection = v; }
|
||||
|
||||
public String getGuardianName() { return guardianName; }
|
||||
public void setGuardianName(String v) { this.guardianName = v; }
|
||||
|
||||
public String getGuardianCifNumber() { return guardianCifNumber; }
|
||||
public void setGuardianCifNumber(String v) { this.guardianCifNumber = v; }
|
||||
|
||||
public String getGuardianRelationship() { return guardianRelationship; }
|
||||
public void setGuardianRelationship(String v) { this.guardianRelationship = v; }
|
||||
|
||||
public LocalDate getMinorDateOfBirth() { return minorDateOfBirth; }
|
||||
public void setMinorDateOfBirth(LocalDate v) { this.minorDateOfBirth = v; }
|
||||
|
||||
public Long getGuardianClientId() { return guardianClientId; }
|
||||
public void setGuardianClientId(Long v) { this.guardianClientId = v; }
|
||||
|
||||
public Long getIntroducerClientId() { return introducerClientId; }
|
||||
public void setIntroducerClientId(Long v) { this.introducerClientId = v; }
|
||||
|
||||
public String getIntroducerName() { return introducerName; }
|
||||
public void setIntroducerName(String v) { this.introducerName = v; }
|
||||
|
||||
public String getIntroducerCifNumber() { return introducerCifNumber; }
|
||||
public void setIntroducerCifNumber(String v) { this.introducerCifNumber = v; }
|
||||
|
||||
public String getNomineeData() { return nomineeData; }
|
||||
public void setNomineeData(String v) { this.nomineeData = v; }
|
||||
|
||||
public Long getLinkedAccountId() { return linkedAccountId; }
|
||||
public void setLinkedAccountId(Long v) { this.linkedAccountId = v; }
|
||||
|
||||
public String getLinkedAccountType() { return linkedAccountType; }
|
||||
public void setLinkedAccountType(String v) { this.linkedAccountType = v; }
|
||||
|
||||
public String getLinkedAccountNo() { return linkedAccountNo; }
|
||||
public void setLinkedAccountNo(String v) { this.linkedAccountNo = v; }
|
||||
|
||||
public SavingsAccountFacilityConfig getFacilityConfig() { return facilityConfig; }
|
||||
public void setFacilityConfig(SavingsAccountFacilityConfig v) { this.facilityConfig = v; }
|
||||
|
||||
public List<SavingsAccountJointHolder> getJointHolders() { return jointHolders; }
|
||||
public void setJointHolders(List<SavingsAccountJointHolder> v) { this.jointHolders = v; }
|
||||
}
|
||||
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.domain;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.time.LocalDateTime;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_savings_account_facility_config")
|
||||
public class SavingsAccountFacilityConfig extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "savings_account_id", nullable = false)
|
||||
private SavingsAccount savingsAccount;
|
||||
|
||||
@Column(name = "atm_facility")
|
||||
private Boolean atmFacility = false;
|
||||
|
||||
@Column(name = "atm_withdrawal_facility")
|
||||
private Boolean atmWithdrawalFacility = false;
|
||||
|
||||
@Column(name = "upi_facility")
|
||||
private Boolean upiFacility = false;
|
||||
|
||||
@Column(name = "pos_transactions_facility")
|
||||
private Boolean posTransactionsFacility = false;
|
||||
|
||||
@Column(name = "cheque_book")
|
||||
private Boolean chequeBook = false;
|
||||
|
||||
@Column(name = "imps_facility")
|
||||
private Boolean impsFacility = false;
|
||||
|
||||
@Column(name = "sms_alerts")
|
||||
private Boolean smsAlerts = false;
|
||||
|
||||
@Column(name = "bbps_facility")
|
||||
private Boolean bbpsFacility = false;
|
||||
|
||||
@Column(name = "insurance_cover")
|
||||
private Boolean insuranceCover = false;
|
||||
|
||||
@Column(name = "bepg_facility")
|
||||
private Boolean bepgFacility = false;
|
||||
|
||||
@Column(name = "neft_facility")
|
||||
private Boolean neftFacility = false;
|
||||
|
||||
@Column(name = "rtgs_facility")
|
||||
private Boolean rtgsFacility = false;
|
||||
|
||||
@Column(name = "inter_bank_total_cap_facility")
|
||||
private Boolean interBankTotalCapFacility = false;
|
||||
|
||||
@Column(name = "withdrawal_facility")
|
||||
private Boolean withdrawalFacility = false;
|
||||
|
||||
@Column(name = "deposit_facility_kyc")
|
||||
private Boolean depositFacilityKyc = false;
|
||||
|
||||
@Column(name = "virtual_debit_card")
|
||||
private Boolean virtualDebitCard = false;
|
||||
|
||||
@Column(name = "created_date", nullable = false)
|
||||
private LocalDateTime createdDate;
|
||||
|
||||
protected SavingsAccountFacilityConfig() {
|
||||
this.createdDate = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public SavingsAccountFacilityConfig(SavingsAccount savingsAccount) {
|
||||
this();
|
||||
this.savingsAccount = savingsAccount;
|
||||
}
|
||||
|
||||
public SavingsAccount getSavingsAccount() { return savingsAccount; }
|
||||
public void setSavingsAccount(SavingsAccount savingsAccount) { this.savingsAccount = savingsAccount; }
|
||||
|
||||
public Boolean getAtmFacility() { return atmFacility; }
|
||||
public void setAtmFacility(Boolean v) { this.atmFacility = v != null ? v : false; }
|
||||
|
||||
public Boolean getAtmWithdrawalFacility() { return atmWithdrawalFacility; }
|
||||
public void setAtmWithdrawalFacility(Boolean v) { this.atmWithdrawalFacility = v != null ? v : false; }
|
||||
|
||||
public Boolean getUpiFacility() { return upiFacility; }
|
||||
public void setUpiFacility(Boolean v) { this.upiFacility = v != null ? v : false; }
|
||||
|
||||
public Boolean getPosTransactionsFacility() { return posTransactionsFacility; }
|
||||
public void setPosTransactionsFacility(Boolean v) { this.posTransactionsFacility = v != null ? v : false; }
|
||||
|
||||
public Boolean getChequeBook() { return chequeBook; }
|
||||
public void setChequeBook(Boolean v) { this.chequeBook = v != null ? v : false; }
|
||||
|
||||
public Boolean getImpsFacility() { return impsFacility; }
|
||||
public void setImpsFacility(Boolean v) { this.impsFacility = v != null ? v : false; }
|
||||
|
||||
public Boolean getSmsAlerts() { return smsAlerts; }
|
||||
public void setSmsAlerts(Boolean v) { this.smsAlerts = v != null ? v : false; }
|
||||
|
||||
public Boolean getBbpsFacility() { return bbpsFacility; }
|
||||
public void setBbpsFacility(Boolean v) { this.bbpsFacility = v != null ? v : false; }
|
||||
|
||||
public Boolean getInsuranceCover() { return insuranceCover; }
|
||||
public void setInsuranceCover(Boolean v) { this.insuranceCover = v != null ? v : false; }
|
||||
|
||||
public Boolean getBepgFacility() { return bepgFacility; }
|
||||
public void setBepgFacility(Boolean v) { this.bepgFacility = v != null ? v : false; }
|
||||
|
||||
public Boolean getNeftFacility() { return neftFacility; }
|
||||
public void setNeftFacility(Boolean v) { this.neftFacility = v != null ? v : false; }
|
||||
|
||||
public Boolean getRtgsFacility() { return rtgsFacility; }
|
||||
public void setRtgsFacility(Boolean v) { this.rtgsFacility = v != null ? v : false; }
|
||||
|
||||
public Boolean getInterBankTotalCapFacility() { return interBankTotalCapFacility; }
|
||||
public void setInterBankTotalCapFacility(Boolean v) { this.interBankTotalCapFacility = v != null ? v : false; }
|
||||
|
||||
public Boolean getWithdrawalFacility() { return withdrawalFacility; }
|
||||
public void setWithdrawalFacility(Boolean v) { this.withdrawalFacility = v != null ? v : false; }
|
||||
|
||||
public Boolean getDepositFacilityKyc() { return depositFacilityKyc; }
|
||||
public void setDepositFacilityKyc(Boolean v) { this.depositFacilityKyc = v != null ? v : false; }
|
||||
|
||||
public Boolean getVirtualDebitCard() { return virtualDebitCard; }
|
||||
public void setVirtualDebitCard(Boolean v) { this.virtualDebitCard = v != null ? v : false; }
|
||||
|
||||
public void updateFrom(com.google.gson.JsonObject config) {
|
||||
if (config == null) return;
|
||||
if (config.has("atmFacility")) setAtmFacility(config.get("atmFacility").getAsBoolean());
|
||||
if (config.has("atmWithdrawalFacility")) setAtmWithdrawalFacility(config.get("atmWithdrawalFacility").getAsBoolean());
|
||||
if (config.has("upiFacility")) setUpiFacility(config.get("upiFacility").getAsBoolean());
|
||||
if (config.has("posTransactionsFacility")) setPosTransactionsFacility(config.get("posTransactionsFacility").getAsBoolean());
|
||||
if (config.has("chequeBook")) setChequeBook(config.get("chequeBook").getAsBoolean());
|
||||
if (config.has("impsFacility")) setImpsFacility(config.get("impsFacility").getAsBoolean());
|
||||
if (config.has("smsAlerts")) setSmsAlerts(config.get("smsAlerts").getAsBoolean());
|
||||
if (config.has("bbpsFacility")) setBbpsFacility(config.get("bbpsFacility").getAsBoolean());
|
||||
if (config.has("insuranceCover")) setInsuranceCover(config.get("insuranceCover").getAsBoolean());
|
||||
if (config.has("bepgFacility")) setBepgFacility(config.get("bepgFacility").getAsBoolean());
|
||||
if (config.has("neftFacility")) setNeftFacility(config.get("neftFacility").getAsBoolean());
|
||||
if (config.has("rtgsFacility")) setRtgsFacility(config.get("rtgsFacility").getAsBoolean());
|
||||
if (config.has("interBankTotalCapFacility")) setInterBankTotalCapFacility(config.get("interBankTotalCapFacility").getAsBoolean());
|
||||
if (config.has("withdrawalFacility")) setWithdrawalFacility(config.get("withdrawalFacility").getAsBoolean());
|
||||
if (config.has("depositFacilityKyc")) setDepositFacilityKyc(config.get("depositFacilityKyc").getAsBoolean());
|
||||
if (config.has("virtualDebitCard")) setVirtualDebitCard(config.get("virtualDebitCard").getAsBoolean());
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.domain;
|
||||
|
||||
import java.util.Optional;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface SavingsAccountFacilityConfigRepository extends JpaRepository<SavingsAccountFacilityConfig, Long> {
|
||||
|
||||
@Query("SELECT fc FROM SavingsAccountFacilityConfig fc WHERE fc.savingsAccount.id = :accountId")
|
||||
Optional<SavingsAccountFacilityConfig> findBySavingsAccountId(@Param("accountId") Long accountId);
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.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 java.math.BigDecimal;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_savings_account_joint_holders")
|
||||
public class SavingsAccountJointHolder extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "savings_account_id", nullable = false)
|
||||
private SavingsAccount savingsAccount;
|
||||
|
||||
@Column(name = "client_id")
|
||||
private Long clientId;
|
||||
|
||||
@Column(name = "cif_number", length = 50)
|
||||
private String cifNumber;
|
||||
|
||||
@Column(name = "display_name", length = 200)
|
||||
private String displayName;
|
||||
|
||||
@Column(name = "share_percentage", precision = 5, scale = 2)
|
||||
private BigDecimal sharePercentage;
|
||||
|
||||
@Column(name = "signing_authority", length = 100)
|
||||
private String signingAuthority;
|
||||
|
||||
@Column(name = "role", length = 100)
|
||||
private String role;
|
||||
|
||||
@Column(name = "is_primary")
|
||||
private boolean primary = false;
|
||||
|
||||
protected SavingsAccountJointHolder() {}
|
||||
|
||||
public SavingsAccountJointHolder(SavingsAccount account, Long clientId, String cifNumber,
|
||||
String displayName, BigDecimal sharePercentage, String signingAuthority, String role, boolean primary) {
|
||||
this.savingsAccount = account;
|
||||
this.clientId = clientId;
|
||||
this.cifNumber = cifNumber;
|
||||
this.displayName = displayName;
|
||||
this.sharePercentage = sharePercentage;
|
||||
this.signingAuthority = signingAuthority;
|
||||
this.role = role;
|
||||
this.primary = primary;
|
||||
}
|
||||
|
||||
public SavingsAccount getSavingsAccount() { return savingsAccount; }
|
||||
public Long getClientId() { return clientId; }
|
||||
public String getCifNumber() { return cifNumber; }
|
||||
public String getDisplayName() { return displayName; }
|
||||
public BigDecimal getSharePercentage() { return sharePercentage; }
|
||||
public String getSigningAuthority() { return signingAuthority; }
|
||||
public String getRole() { return role; }
|
||||
public boolean isPrimary() { return primary; }
|
||||
}
|
||||
+1
@@ -32,4 +32,5 @@
|
||||
<include file="parts/2007_add_interest_calculation_type_option.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2008_add_other_gl_mappings_to_savings_product.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2009_add_gl_account_id_to_savings_product.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/2010_add_savings_account_cbs_fields.xml" relativeToChangelogFile="true" />
|
||||
</databaseChangeLog>
|
||||
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. This file is licensed under the Apache License, Version 2.0.
|
||||
|
||||
-->
|
||||
<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.3.xsd">
|
||||
|
||||
<!-- CBS extended fields on m_savings_account -->
|
||||
<changeSet author="fineract" id="2010-add-savings-account-cbs-fields">
|
||||
<addColumn tableName="m_savings_account">
|
||||
<column name="cbs_account_type" type="VARCHAR(100)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="customer_segment" type="VARCHAR(100)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="account_status" type="VARCHAR(50)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="mode_of_operation" type="VARCHAR(50)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="special_category" type="VARCHAR(100)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="weaker_section" type="VARCHAR(100)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="guardian_name" type="VARCHAR(200)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="guardian_cif_number" type="VARCHAR(50)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="guardian_relationship" type="VARCHAR(100)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="minor_date_of_birth" type="DATE">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="guardian_client_id" type="BIGINT">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="introducer_client_id" type="BIGINT">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="introducer_name" type="VARCHAR(200)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="introducer_cif_number" type="VARCHAR(50)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="nominee_data" type="TEXT">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="linked_account_id" type="BIGINT">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="linked_account_type" type="VARCHAR(20)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="linked_account_no" type="VARCHAR(50)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<!-- Facility config table for savings accounts -->
|
||||
<changeSet author="fineract" id="2010-create-savings-account-facility-config">
|
||||
<createTable tableName="m_savings_account_facility_config">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="savings_account_id" type="BIGINT">
|
||||
<constraints nullable="false" unique="true"
|
||||
foreignKeyName="fk_sa_facility_config_account"
|
||||
references="m_savings_account(id)"/>
|
||||
</column>
|
||||
<column name="atm_facility" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="atm_withdrawal_facility" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="upi_facility" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="pos_transactions_facility" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="cheque_book" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="imps_facility" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="sms_alerts" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="bbps_facility" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="insurance_cover" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="bepg_facility" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="neft_facility" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="rtgs_facility" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="inter_bank_total_cap_facility" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="withdrawal_facility" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="deposit_facility_kyc" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="virtual_debit_card" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="created_date" type="DATETIME">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<!-- Joint holders table for savings accounts -->
|
||||
<changeSet author="fineract" id="2010-create-savings-account-joint-holders">
|
||||
<createTable tableName="m_savings_account_joint_holders">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="savings_account_id" type="BIGINT">
|
||||
<constraints nullable="false"
|
||||
foreignKeyName="fk_sa_joint_holder_account"
|
||||
references="m_savings_account(id)"/>
|
||||
</column>
|
||||
<column name="client_id" type="BIGINT">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="cif_number" type="VARCHAR(50)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="display_name" type="VARCHAR(200)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="share_percentage" type="DECIMAL(5,2)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="signing_authority" type="VARCHAR(100)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="role" type="VARCHAR(100)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="is_primary" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+11
@@ -112,6 +112,17 @@
|
||||
<class>org.apache.fineract.portfolio.savings.domain.SavingsProductDepositLimitKyc</class>
|
||||
<class>org.apache.fineract.portfolio.savings.domain.SavingsProductFacilityConfig</class>
|
||||
<class>org.apache.fineract.portfolio.savings.domain.SavingsProductFacilityLimit</class>
|
||||
<class>org.apache.fineract.portfolio.savings.domain.SavingsAccountFacilityConfig</class>
|
||||
<class>org.apache.fineract.portfolio.savings.domain.SavingsAccountJointHolder</class>
|
||||
|
||||
<!-- Current Account Entities -->
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccount</class>
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountTransaction</class>
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountCharge</class>
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountFacilityConfig</class>
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountJointHolder</class>
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountPartner</class>
|
||||
<class>org.apache.fineract.portfolio.currentaccount.domain.CurrentAccountOfficerHistory</class>
|
||||
|
||||
<!-- Charge Module Entities -->
|
||||
<class>org.apache.fineract.portfolio.charge.domain.Charge</class>
|
||||
|
||||
Reference in New Issue
Block a user