FINERACT-1390:WithdrawChargesPerPaymentType
This commit is contained in:
+46
-39
@@ -48,6 +48,8 @@ public final class ChargeData implements Comparable<ChargeData>, Serializable {
|
||||
private final Integer freeWithdrawalChargeFrequency;
|
||||
private final Integer restartFrequency;
|
||||
private final Integer restartFrequencyEnum;
|
||||
private final boolean isPaymentType;
|
||||
private final PaymentTypeData paymentTypeOptions;
|
||||
private final CurrencyData currency;
|
||||
private final BigDecimal amount;
|
||||
private final EnumOptionData chargeTimeType;
|
||||
@@ -99,34 +101,36 @@ public final class ChargeData implements Comparable<ChargeData>, Serializable {
|
||||
final GLAccountData account = null;
|
||||
final TaxGroupData taxGroupData = null;
|
||||
|
||||
return new ChargeData(null, null, null, null, null, null, null, null, false, false, false, null, null, null, taxGroupData,
|
||||
currencyOptions, chargeCalculationTypeOptions, chargeAppliesToOptions, chargeTimeTypeOptions, chargePaymentModeOptions,
|
||||
loansChargeCalculationTypeOptions, loansChargeTimeTypeOptions, savingsChargeCalculationTypeOptions,
|
||||
savingsChargeTimeTypeOptions, clientChargeCalculationTypeOptions, clientChargeTimeTypeOptions, null, null, null, null, null,
|
||||
feeFrequencyOptions, account, incomeOrLiabilityAccountOptions, taxGroupOptions, shareChargeCalculationTypeOptions,
|
||||
shareChargeTimeTypeOptions, accountMappingForChargeConfig, expenseAccountOptions, assetAccountOptions);
|
||||
return new ChargeData(null, null, null, null, null, null, null, null, false, false, false, null, null, null, false, null,
|
||||
taxGroupData, currencyOptions, chargeCalculationTypeOptions, chargeAppliesToOptions, chargeTimeTypeOptions,
|
||||
chargePaymentModeOptions, loansChargeCalculationTypeOptions, loansChargeTimeTypeOptions,
|
||||
savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, clientChargeCalculationTypeOptions,
|
||||
clientChargeTimeTypeOptions, null, null, null, null, null, feeFrequencyOptions, account, incomeOrLiabilityAccountOptions,
|
||||
taxGroupOptions, shareChargeCalculationTypeOptions, shareChargeTimeTypeOptions, accountMappingForChargeConfig,
|
||||
expenseAccountOptions, assetAccountOptions);
|
||||
}
|
||||
|
||||
public static ChargeData withTemplate(final ChargeData charge, final ChargeData template) {
|
||||
return new ChargeData(charge.id, charge.name, charge.amount, charge.currency, charge.chargeTimeType, charge.chargeAppliesTo,
|
||||
charge.chargeCalculationType, charge.chargePaymentMode, charge.penalty, charge.active, charge.freeWithdrawal,
|
||||
charge.freeWithdrawalChargeFrequency, charge.restartFrequency, charge.restartFrequencyEnum, charge.taxGroup,
|
||||
template.currencyOptions, template.chargeCalculationTypeOptions, template.chargeAppliesToOptions,
|
||||
template.chargeTimeTypeOptions, template.chargePaymetModeOptions, template.loanChargeCalculationTypeOptions,
|
||||
template.loanChargeTimeTypeOptions, template.savingsChargeCalculationTypeOptions, template.savingsChargeTimeTypeOptions,
|
||||
template.clientChargeCalculationTypeOptions, template.clientChargeTimeTypeOptions, charge.feeOnMonthDay, charge.feeInterval,
|
||||
charge.minCap, charge.maxCap, charge.feeFrequency, template.feeFrequencyOptions, charge.incomeOrLiabilityAccount,
|
||||
template.incomeOrLiabilityAccountOptions, template.taxGroupOptions, template.shareChargeCalculationTypeOptions,
|
||||
template.shareChargeTimeTypeOptions, template.accountMappingForChargeConfig, template.expenseAccountOptions,
|
||||
template.assetAccountOptions);
|
||||
charge.freeWithdrawalChargeFrequency, charge.restartFrequency, charge.restartFrequencyEnum, charge.isPaymentType,
|
||||
charge.paymentTypeOptions, charge.taxGroup, template.currencyOptions, template.chargeCalculationTypeOptions,
|
||||
template.chargeAppliesToOptions, template.chargeTimeTypeOptions, template.chargePaymetModeOptions,
|
||||
template.loanChargeCalculationTypeOptions, template.loanChargeTimeTypeOptions, template.savingsChargeCalculationTypeOptions,
|
||||
template.savingsChargeTimeTypeOptions, template.clientChargeCalculationTypeOptions, template.clientChargeTimeTypeOptions,
|
||||
charge.feeOnMonthDay, charge.feeInterval, charge.minCap, charge.maxCap, charge.feeFrequency, template.feeFrequencyOptions,
|
||||
charge.incomeOrLiabilityAccount, template.incomeOrLiabilityAccountOptions, template.taxGroupOptions,
|
||||
template.shareChargeCalculationTypeOptions, template.shareChargeTimeTypeOptions, template.accountMappingForChargeConfig,
|
||||
template.expenseAccountOptions, template.assetAccountOptions);
|
||||
}
|
||||
|
||||
public static ChargeData instance(final Long id, final String name, final BigDecimal amount, final CurrencyData currency,
|
||||
final EnumOptionData chargeTimeType, final EnumOptionData chargeAppliesTo, final EnumOptionData chargeCalculationType,
|
||||
final EnumOptionData chargePaymentMode, final MonthDay feeOnMonthDay, final Integer feeInterval, final boolean penalty,
|
||||
final boolean active, final boolean freeWithdrawal, final Integer freeWithdrawalChargeFrequency, final Integer restartFrequency,
|
||||
final Integer restartFrequencyEnum, final BigDecimal minCap, final BigDecimal maxCap, final EnumOptionData feeFrequency,
|
||||
final GLAccountData accountData, TaxGroupData taxGroupData) {
|
||||
final Integer restartFrequencyEnum, final boolean isPaymentType, final PaymentTypeData paymentTypeOptions,
|
||||
final BigDecimal minCap, final BigDecimal maxCap, final EnumOptionData feeFrequency, final GLAccountData accountData,
|
||||
TaxGroupData taxGroupData) {
|
||||
|
||||
final Collection<CurrencyData> currencyOptions = null;
|
||||
final List<EnumOptionData> chargeCalculationTypeOptions = null;
|
||||
@@ -148,13 +152,13 @@ public final class ChargeData implements Comparable<ChargeData>, Serializable {
|
||||
final List<GLAccountData> expenseAccountOptions = null;
|
||||
final List<GLAccountData> assetAccountOptions = null;
|
||||
return new ChargeData(id, name, amount, currency, chargeTimeType, chargeAppliesTo, chargeCalculationType, chargePaymentMode,
|
||||
penalty, active, freeWithdrawal, freeWithdrawalChargeFrequency, restartFrequency, restartFrequencyEnum, taxGroupData,
|
||||
currencyOptions, chargeCalculationTypeOptions, chargeAppliesToOptions, chargeTimeTypeOptions, chargePaymentModeOptions,
|
||||
loansChargeCalculationTypeOptions, loansChargeTimeTypeOptions, savingsChargeCalculationTypeOptions,
|
||||
savingsChargeTimeTypeOptions, clientChargeCalculationTypeOptions, clientChargeTimeTypeOptions, feeOnMonthDay, feeInterval,
|
||||
minCap, maxCap, feeFrequency, feeFrequencyOptions, accountData, incomeOrLiabilityAccountOptions, taxGroupOptions,
|
||||
shareChargeCalculationTypeOptions, shareChargeTimeTypeOptions, accountMappingForChargeConfig, expenseAccountOptions,
|
||||
assetAccountOptions);
|
||||
penalty, active, freeWithdrawal, freeWithdrawalChargeFrequency, restartFrequency, restartFrequencyEnum, isPaymentType,
|
||||
paymentTypeOptions, taxGroupData, currencyOptions, chargeCalculationTypeOptions, chargeAppliesToOptions,
|
||||
chargeTimeTypeOptions, chargePaymentModeOptions, loansChargeCalculationTypeOptions, loansChargeTimeTypeOptions,
|
||||
savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, clientChargeCalculationTypeOptions,
|
||||
clientChargeTimeTypeOptions, feeOnMonthDay, feeInterval, minCap, maxCap, feeFrequency, feeFrequencyOptions, accountData,
|
||||
incomeOrLiabilityAccountOptions, taxGroupOptions, shareChargeCalculationTypeOptions, shareChargeTimeTypeOptions,
|
||||
accountMappingForChargeConfig, expenseAccountOptions, assetAccountOptions);
|
||||
}
|
||||
|
||||
public static ChargeData lookup(final Long id, final String name, final boolean isPenalty) {
|
||||
@@ -200,27 +204,28 @@ public final class ChargeData implements Comparable<ChargeData>, Serializable {
|
||||
final List<GLAccountData> assetAccountOptions = null;
|
||||
|
||||
return new ChargeData(id, name, amount, currency, chargeTimeType, chargeAppliesTo, chargeCalculationType, chargePaymentMode,
|
||||
penalty, active, freeWithdrawal, freeWithdrawalChargeFrequency, restartFrequency, restartFrequencyEnum, taxGroupData,
|
||||
currencyOptions, chargeCalculationTypeOptions, chargeAppliesToOptions, chargeTimeTypeOptions, chargePaymentModeOptions,
|
||||
loansChargeCalculationTypeOptions, loansChargeTimeTypeOptions, savingsChargeCalculationTypeOptions,
|
||||
savingsChargeTimeTypeOptions, clientChargeCalculationTypeOptions, clientChargeTimeTypeOptions, feeOnMonthDay, feeInterval,
|
||||
minCap, maxCap, feeFrequency, feeFrequencyOptions, account, incomeOrLiabilityAccountOptions, taxGroupOptions,
|
||||
shareChargeCalculationTypeOptions, shareChargeTimeTypeOptions, accountMappingForChargeConfig, expenseAccountOptions,
|
||||
assetAccountOptions);
|
||||
penalty, active, freeWithdrawal, freeWithdrawalChargeFrequency, restartFrequency, restartFrequencyEnum, isPaymentType,
|
||||
paymentTypeOptions, taxGroupData, currencyOptions, chargeCalculationTypeOptions, chargeAppliesToOptions,
|
||||
chargeTimeTypeOptions, chargePaymentModeOptions, loansChargeCalculationTypeOptions, loansChargeTimeTypeOptions,
|
||||
savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, clientChargeCalculationTypeOptions,
|
||||
clientChargeTimeTypeOptions, feeOnMonthDay, feeInterval, minCap, maxCap, feeFrequency, feeFrequencyOptions, account,
|
||||
incomeOrLiabilityAccountOptions, taxGroupOptions, shareChargeCalculationTypeOptions, shareChargeTimeTypeOptions,
|
||||
accountMappingForChargeConfig, expenseAccountOptions, assetAccountOptions);
|
||||
}
|
||||
|
||||
private ChargeData(final Long id, final String name, final BigDecimal amount, final CurrencyData currency,
|
||||
final EnumOptionData chargeTimeType, final EnumOptionData chargeAppliesTo, final EnumOptionData chargeCalculationType,
|
||||
final EnumOptionData chargePaymentMode, final boolean penalty, final boolean active, final boolean freeWithdrawal,
|
||||
final Integer freeWithdrawalChargeFrequency, final Integer restartFrequency, final Integer restartFrequencyEnum,
|
||||
final TaxGroupData taxGroupData, final Collection<CurrencyData> currencyOptions,
|
||||
final List<EnumOptionData> chargeCalculationTypeOptions, final List<EnumOptionData> chargeAppliesToOptions,
|
||||
final List<EnumOptionData> chargeTimeTypeOptions, final List<EnumOptionData> chargePaymentModeOptions,
|
||||
final List<EnumOptionData> loansChargeCalculationTypeOptions, final List<EnumOptionData> loansChargeTimeTypeOptions,
|
||||
final List<EnumOptionData> savingsChargeCalculationTypeOptions, final List<EnumOptionData> savingsChargeTimeTypeOptions,
|
||||
final List<EnumOptionData> clientChargeCalculationTypeOptions, final List<EnumOptionData> clientChargeTimeTypeOptions,
|
||||
final MonthDay feeOnMonthDay, final Integer feeInterval, final BigDecimal minCap, final BigDecimal maxCap,
|
||||
final EnumOptionData feeFrequency, final List<EnumOptionData> feeFrequencyOptions, final GLAccountData account,
|
||||
final boolean isPaymentType, final PaymentTypeData paymentTypeOptions, final TaxGroupData taxGroupData,
|
||||
final Collection<CurrencyData> currencyOptions, final List<EnumOptionData> chargeCalculationTypeOptions,
|
||||
final List<EnumOptionData> chargeAppliesToOptions, final List<EnumOptionData> chargeTimeTypeOptions,
|
||||
final List<EnumOptionData> chargePaymentModeOptions, final List<EnumOptionData> loansChargeCalculationTypeOptions,
|
||||
final List<EnumOptionData> loansChargeTimeTypeOptions, final List<EnumOptionData> savingsChargeCalculationTypeOptions,
|
||||
final List<EnumOptionData> savingsChargeTimeTypeOptions, final List<EnumOptionData> clientChargeCalculationTypeOptions,
|
||||
final List<EnumOptionData> clientChargeTimeTypeOptions, final MonthDay feeOnMonthDay, final Integer feeInterval,
|
||||
final BigDecimal minCap, final BigDecimal maxCap, final EnumOptionData feeFrequency,
|
||||
final List<EnumOptionData> feeFrequencyOptions, final GLAccountData account,
|
||||
final Map<String, List<GLAccountData>> incomeOrLiabilityAccountOptions, final Collection<TaxGroupData> taxGroupOptions,
|
||||
final List<EnumOptionData> shareChargeCalculationTypeOptions, final List<EnumOptionData> shareChargeTimeTypeOptions,
|
||||
final String accountMappingForChargeConfig, final List<GLAccountData> expenseAccountOptions,
|
||||
@@ -241,6 +246,8 @@ public final class ChargeData implements Comparable<ChargeData>, Serializable {
|
||||
this.freeWithdrawalChargeFrequency = freeWithdrawalChargeFrequency;
|
||||
this.restartFrequency = restartFrequency;
|
||||
this.restartFrequencyEnum = restartFrequencyEnum;
|
||||
this.isPaymentType = isPaymentType;
|
||||
this.paymentTypeOptions = paymentTypeOptions;
|
||||
this.minCap = minCap;
|
||||
this.maxCap = maxCap;
|
||||
this.currencyOptions = currencyOptions;
|
||||
|
||||
+64
-5
@@ -49,6 +49,8 @@ import org.apache.fineract.portfolio.charge.exception.ChargeMustBePenaltyExcepti
|
||||
import org.apache.fineract.portfolio.charge.exception.ChargeParameterUpdateNotSupportedException;
|
||||
import org.apache.fineract.portfolio.charge.service.ChargeEnumerations;
|
||||
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
||||
import org.apache.fineract.portfolio.paymenttype.domain.PaymentType;
|
||||
import org.apache.fineract.portfolio.tax.data.TaxGroupData;
|
||||
import org.apache.fineract.portfolio.tax.domain.TaxGroup;
|
||||
|
||||
@@ -116,6 +118,13 @@ public class Charge extends AbstractPersistableCustom {
|
||||
@Column(name = "restart_frequency_enum", nullable = true)
|
||||
private Integer restartFrequencyEnum;
|
||||
|
||||
@Column(name = "is_payment_type", nullable = false)
|
||||
private boolean enablePaymentType;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "payment_type_id", nullable = false)
|
||||
private PaymentType paymentType;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "income_or_liability_account_id")
|
||||
private GLAccount account;
|
||||
@@ -124,7 +133,8 @@ public class Charge extends AbstractPersistableCustom {
|
||||
@JoinColumn(name = "tax_group_id")
|
||||
private TaxGroup taxGroup;
|
||||
|
||||
public static Charge fromJson(final JsonCommand command, final GLAccount account, final TaxGroup taxGroup) {
|
||||
public static Charge fromJson(final JsonCommand command, final GLAccount account, final TaxGroup taxGroup,
|
||||
final PaymentType paymentType) {
|
||||
|
||||
final String name = command.stringValueOfParameterNamed("name");
|
||||
final BigDecimal amount = command.bigDecimalValueOfParameterNamed("amount");
|
||||
@@ -149,6 +159,9 @@ public class Charge extends AbstractPersistableCustom {
|
||||
boolean enableFreeWithdrawalCharge = false;
|
||||
enableFreeWithdrawalCharge = command.booleanPrimitiveValueOfParameterNamed("enableFreeWithdrawalCharge");
|
||||
|
||||
boolean enablePaymentType = false;
|
||||
enablePaymentType = command.booleanPrimitiveValueOfParameterNamed("enablePaymentType");
|
||||
|
||||
Integer freeWithdrawalFrequency = null;
|
||||
Integer restartCountFrequency = null;
|
||||
PeriodFrequencyType countFrequencyType = null;
|
||||
@@ -162,7 +175,7 @@ public class Charge extends AbstractPersistableCustom {
|
||||
|
||||
return new Charge(name, amount, currencyCode, chargeAppliesTo, chargeTimeType, chargeCalculationType, penalty, active, paymentMode,
|
||||
feeOnMonthDay, feeInterval, minCap, maxCap, feeFrequency, enableFreeWithdrawalCharge, freeWithdrawalFrequency,
|
||||
restartCountFrequency, countFrequencyType, account, taxGroup);
|
||||
restartCountFrequency, countFrequencyType, account, taxGroup, enablePaymentType, paymentType);
|
||||
}
|
||||
|
||||
protected Charge() {}
|
||||
@@ -172,7 +185,7 @@ public class Charge extends AbstractPersistableCustom {
|
||||
final ChargePaymentMode paymentMode, final MonthDay feeOnMonthDay, final Integer feeInterval, final BigDecimal minCap,
|
||||
final BigDecimal maxCap, final Integer feeFrequency, final boolean enableFreeWithdrawalCharge,
|
||||
final Integer freeWithdrawalFrequency, final Integer restartFrequency, final PeriodFrequencyType restartFrequencyEnum,
|
||||
final GLAccount account, final TaxGroup taxGroup) {
|
||||
final GLAccount account, final TaxGroup taxGroup, final boolean enablePaymentType, final PaymentType paymentType) {
|
||||
this.name = name;
|
||||
this.amount = amount;
|
||||
this.currencyCode = currencyCode;
|
||||
@@ -224,6 +237,14 @@ public class Charge extends AbstractPersistableCustom {
|
||||
this.restartFrequencyEnum = restartFrequencyEnum.getValue();
|
||||
}
|
||||
|
||||
if (enablePaymentType) {
|
||||
if (paymentType != null) {
|
||||
|
||||
this.enablePaymentType = enablePaymentType;
|
||||
this.paymentType = paymentType;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (isLoanCharge()) {
|
||||
|
||||
if (penalty && (chargeTime.isTimeOfDisbursement() || chargeTime.isTrancheDisbursement())) {
|
||||
@@ -334,6 +355,10 @@ public class Charge extends AbstractPersistableCustom {
|
||||
return this.enableFreeWithdrawal;
|
||||
}
|
||||
|
||||
public boolean isEnablePaymentType() {
|
||||
return this.enablePaymentType;
|
||||
}
|
||||
|
||||
public Integer getFrequencyFreeWithdrawalCharge() {
|
||||
return this.freeWithdrawalFrequency;
|
||||
}
|
||||
@@ -346,6 +371,22 @@ public class Charge extends AbstractPersistableCustom {
|
||||
return this.restartFrequencyEnum;
|
||||
}
|
||||
|
||||
public PaymentType getPaymentType() {
|
||||
return this.paymentType;
|
||||
}
|
||||
|
||||
public void setPaymentType(PaymentType paymentType) {
|
||||
this.paymentType = paymentType;
|
||||
}
|
||||
|
||||
private Long getPaymentTypeId() {
|
||||
Long paymentTypeId = null;
|
||||
if (this.paymentType != null) {
|
||||
paymentTypeId = this.paymentType.getId();
|
||||
}
|
||||
return paymentTypeId;
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(7);
|
||||
|
||||
@@ -439,6 +480,19 @@ public class Charge extends AbstractPersistableCustom {
|
||||
|
||||
}
|
||||
|
||||
final String enablePaymentTypeParamName = "enablePaymentType";
|
||||
if (command.isChangeInBooleanParameterNamed(enablePaymentTypeParamName, this.enablePaymentType)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(enablePaymentTypeParamName);
|
||||
actualChanges.put(enablePaymentTypeParamName, newValue);
|
||||
this.enablePaymentType = newValue;
|
||||
}
|
||||
|
||||
final String paymentTypeParamName = "paymentTypeId";
|
||||
if (command.isChangeInLongParameterNamed(paymentTypeParamName, getPaymentTypeId())) {
|
||||
final Long newValue = command.longValueOfParameterNamed(paymentTypeParamName);
|
||||
actualChanges.put(paymentTypeParamName, newValue);
|
||||
}
|
||||
|
||||
final String chargeAppliesToParamName = "chargeAppliesTo";
|
||||
if (command.isChangeInIntegerParameterNamed(chargeAppliesToParamName, this.chargeAppliesTo)) {
|
||||
/*
|
||||
@@ -613,11 +667,16 @@ public class Charge extends AbstractPersistableCustom {
|
||||
taxGroupData = TaxGroupData.lookup(taxGroup.getId(), taxGroup.getName());
|
||||
}
|
||||
|
||||
PaymentTypeData paymentTypeData = null;
|
||||
if (this.paymentType != null) {
|
||||
paymentTypeData = PaymentTypeData.instance(paymentType.getId(), paymentType.getPaymentName());
|
||||
}
|
||||
|
||||
final CurrencyData currency = new CurrencyData(this.currencyCode, null, 0, 0, null, null);
|
||||
return ChargeData.instance(getId(), this.name, this.amount, currency, chargeTimeType, chargeAppliesTo, chargeCalculationType,
|
||||
chargePaymentmode, getFeeOnMonthDay(), this.feeInterval, this.penalty, this.active, this.enableFreeWithdrawal,
|
||||
this.freeWithdrawalFrequency, this.restartFrequency, this.restartFrequencyEnum, this.minCap, this.maxCap, feeFrequencyType,
|
||||
accountData, taxGroupData);
|
||||
this.freeWithdrawalFrequency, this.restartFrequency, this.restartFrequencyEnum, this.enablePaymentType, paymentTypeData,
|
||||
this.minCap, this.maxCap, feeFrequencyType, accountData, taxGroupData);
|
||||
}
|
||||
|
||||
public Integer getChargePaymentMode() {
|
||||
|
||||
+24
-2
@@ -54,8 +54,8 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
|
||||
private final Set<String> supportedParameters = new HashSet<>(Arrays.asList("name", "amount", "locale", "currencyCode",
|
||||
"currencyOptions", "chargeAppliesTo", "chargeTimeType", "chargeCalculationType", "chargeCalculationTypeOptions", "penalty",
|
||||
"active", "chargePaymentMode", "feeOnMonthDay", "feeInterval", "monthDayFormat", "minCap", "maxCap", "feeFrequency",
|
||||
"enableFreeWithdrawalCharge", "freeWithdrawalFrequency", "restartCountFrequency", "countFrequencyType",
|
||||
ChargesApiConstants.glAccountIdParamName, ChargesApiConstants.taxGroupIdParamName));
|
||||
"enableFreeWithdrawalCharge", "freeWithdrawalFrequency", "restartCountFrequency", "countFrequencyType", "paymentTypeId",
|
||||
"enablePaymentType", ChargesApiConstants.glAccountIdParamName, ChargesApiConstants.taxGroupIdParamName));
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@@ -114,6 +114,17 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists("enablePaymentType", element)) {
|
||||
|
||||
final boolean enablePaymentType = this.fromApiJsonHelper.extractBooleanNamed("enablePaymentType", element);
|
||||
baseDataValidator.reset().parameter("enablePaymentType").value(enablePaymentType).notNull();
|
||||
|
||||
if (enablePaymentType) {
|
||||
final Integer paymentTypeId = this.fromApiJsonHelper.extractIntegerNamed("paymentTypeId", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("paymentTypeId").value(paymentTypeId).integerGreaterThanZero();
|
||||
}
|
||||
}
|
||||
|
||||
if (feeFrequency != null) {
|
||||
baseDataValidator.reset().parameter("feeInterval").value(feeInterval).notNull();
|
||||
}
|
||||
@@ -320,6 +331,17 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
|
||||
Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("countFrequencyType").value(countFrequencyType);
|
||||
}
|
||||
|
||||
Boolean enablePaymentType = false;
|
||||
if (this.fromApiJsonHelper.parameterExists("enablePaymentType", element)) {
|
||||
enablePaymentType = this.fromApiJsonHelper.extractBooleanNamed("enablePaymentType", element);
|
||||
baseDataValidator.reset().parameter("enablePaymentType").value(enablePaymentType).notNull();
|
||||
|
||||
if (enablePaymentType) {
|
||||
final Integer paymentTypeId = this.fromApiJsonHelper.extractIntegerNamed("paymentTypeId", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("paymentTypeId").value(paymentTypeId).integerGreaterThanZero();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists("chargeAppliesTo", element)) {
|
||||
|
||||
+15
-4
@@ -43,6 +43,7 @@ import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
|
||||
import org.apache.fineract.portfolio.charge.exception.ChargeNotFoundException;
|
||||
import org.apache.fineract.portfolio.common.service.CommonEnumerations;
|
||||
import org.apache.fineract.portfolio.common.service.DropdownReadPlatformService;
|
||||
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
||||
import org.apache.fineract.portfolio.tax.data.TaxGroupData;
|
||||
import org.apache.fineract.portfolio.tax.service.TaxReadPlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -293,10 +294,10 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
|
||||
+ "oc.internationalized_name_code as currencyNameCode, c.fee_on_day as feeOnDay, c.fee_on_month as feeOnMonth, "
|
||||
+ "c.fee_interval as feeInterval, c.fee_frequency as feeFrequency,c.min_cap as minCap,c.max_cap as maxCap, "
|
||||
+ "c.income_or_liability_account_id as glAccountId , acc.name as glAccountName, acc.gl_code as glCode, "
|
||||
+ "tg.id as taxGroupId, tg.name as taxGroupName " + "from m_charge c "
|
||||
+ "join m_organisation_currency oc on c.currency_code = oc.code "
|
||||
+ "tg.id as taxGroupId, c.is_payment_type as isPaymentType, pt.id as paymentTypeId, pt.value as paymentTypeName, tg.name as taxGroupName "
|
||||
+ "from m_charge c " + "join m_organisation_currency oc on c.currency_code = oc.code "
|
||||
+ " LEFT JOIN acc_gl_account acc on acc.id = c.income_or_liability_account_id "
|
||||
+ " LEFT JOIN m_tax_group tg on tg.id = c.tax_group_id ";
|
||||
+ " LEFT JOIN m_tax_group tg on tg.id = c.tax_group_id " + " LEFT JOIN m_payment_type pt on pt.id = c.payment_type_id ";
|
||||
}
|
||||
|
||||
public String loanProductChargeSchema() {
|
||||
@@ -378,9 +379,19 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
|
||||
final int restartFrequency = rs.getInt("restartFrequency");
|
||||
final int restartFrequencyEnum = rs.getInt("restartFrequencyEnum");
|
||||
|
||||
final boolean isPaymentType = rs.getBoolean("isPaymentType");
|
||||
final Long paymentTypeId = JdbcSupport.getLong(rs, "paymentTypeId");
|
||||
|
||||
final String paymentTypeName = rs.getString("paymentTypeName");
|
||||
PaymentTypeData paymentTypeData = null;
|
||||
if (paymentTypeId != null) {
|
||||
paymentTypeData = PaymentTypeData.instance(paymentTypeId, paymentTypeName);
|
||||
}
|
||||
|
||||
return ChargeData.instance(id, name, amount, currency, chargeTimeType, chargeAppliesToType, chargeCalculationType,
|
||||
chargePaymentMode, feeOnMonthDay, feeInterval, penalty, active, isFreeWithdrawal, freeWithdrawalChargeFrequency,
|
||||
restartFrequency, restartFrequencyEnum, minCap, maxCap, feeFrequencyType, glAccountData, taxGroupData);
|
||||
restartFrequency, restartFrequencyEnum, isPaymentType, paymentTypeData, minCap, maxCap, feeFrequencyType, glAccountData,
|
||||
taxGroupData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+27
-1
@@ -42,6 +42,8 @@ import org.apache.fineract.portfolio.charge.exception.ChargeNotFoundException;
|
||||
import org.apache.fineract.portfolio.charge.serialization.ChargeDefinitionCommandFromApiJsonDeserializer;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
|
||||
import org.apache.fineract.portfolio.paymentdetail.PaymentDetailConstants;
|
||||
import org.apache.fineract.portfolio.paymenttype.domain.PaymentType;
|
||||
import org.apache.fineract.portfolio.paymenttype.domain.PaymentTypeRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.tax.domain.TaxGroup;
|
||||
import org.apache.fineract.portfolio.tax.domain.TaxGroupRepositoryWrapper;
|
||||
@@ -110,7 +112,16 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP
|
||||
taxGroup = this.taxGroupRepository.findOneWithNotFoundDetection(taxGroupId);
|
||||
}
|
||||
|
||||
final Charge charge = Charge.fromJson(command, glAccount, taxGroup);
|
||||
final boolean enablePaymentType = command.booleanPrimitiveValueOfParameterNamed("enablePaymentType");
|
||||
PaymentType paymentType = null;
|
||||
if (enablePaymentType) {
|
||||
final Long paymentTypeId = command.longValueOfParameterNamed(PaymentDetailConstants.paymentTypeParamName);
|
||||
if (paymentTypeId != null) {
|
||||
paymentType = this.paymentTyperepositoryWrapper.findOneWithNotFoundDetection(paymentTypeId);
|
||||
}
|
||||
}
|
||||
|
||||
final Charge charge = Charge.fromJson(command, glAccount, taxGroup, paymentType);
|
||||
this.chargeRepository.save(charge);
|
||||
|
||||
// check if the office specific products are enabled. If yes, then
|
||||
@@ -179,6 +190,21 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP
|
||||
chargeForUpdate.setAccount(newIncomeAccount);
|
||||
}
|
||||
|
||||
final String paymentTypeIdParamName = "paymentTypeId";
|
||||
if (changes.containsKey(paymentTypeIdParamName)) {
|
||||
|
||||
final Integer paymentTypeIdNewValue = command.integerValueOfParameterNamed(paymentTypeIdParamName);
|
||||
|
||||
PaymentType paymentType = null;
|
||||
if (paymentTypeIdNewValue != null) {
|
||||
final Long paymentTypeId = paymentTypeIdNewValue.longValue();
|
||||
|
||||
paymentType = this.paymentTyperepositoryWrapper.findOneWithNotFoundDetection(paymentTypeId);
|
||||
chargeForUpdate.setPaymentType(paymentType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (changes.containsKey(ChargesApiConstants.taxGroupIdParamName)) {
|
||||
final Long newValue = command.longValueOfParameterNamed(ChargesApiConstants.taxGroupIdParamName);
|
||||
TaxGroup taxGroup = null;
|
||||
|
||||
+4
@@ -97,4 +97,8 @@ public class PaymentType extends AbstractPersistableCustom {
|
||||
return isCashPayment;
|
||||
}
|
||||
|
||||
public String getPaymentName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+15
-2
@@ -1076,14 +1076,27 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
||||
for (SavingsAccountCharge charge : this.charges()) {
|
||||
|
||||
if (charge.isWithdrawalFee() && charge.isActive()) {
|
||||
|
||||
if (charge.getFreeWithdrawalCount() == null) {
|
||||
charge.setFreeWithdrawalCount(0);
|
||||
}
|
||||
|
||||
if (charge.isEnableFreeWithdrawal()) {
|
||||
if (charge.isEnablePaymentType() && charge.isEnableFreeWithdrawal()) { // discount transaction to
|
||||
// specific paymentType
|
||||
if (paymentDetail.getPaymentType().getPaymentName().equals(charge.getCharge().getPaymentType().getPaymentName())) {
|
||||
resetFreeChargeDaysCount(charge, transactionAmount, transactionDate, user);
|
||||
}
|
||||
} else if (charge.isEnablePaymentType()) { // normal charge-transaction to specific paymentType
|
||||
if (paymentDetail.getPaymentType().getPaymentName().equals(charge.getCharge().getPaymentType().getPaymentName())) {
|
||||
charge.updateWithdralFeeAmount(transactionAmount);
|
||||
this.payCharge(charge, charge.getAmountOutstanding(this.getCurrency()), transactionDate, user);
|
||||
}
|
||||
} else if (!charge.isEnablePaymentType() && charge.isEnableFreeWithdrawal()) { // discount transaction
|
||||
// irrespective of
|
||||
// PaymentTypes.
|
||||
resetFreeChargeDaysCount(charge, transactionAmount, transactionDate, user);
|
||||
|
||||
} else {
|
||||
} else { // normal-withdraw
|
||||
charge.updateWithdralFeeAmount(transactionAmount);
|
||||
this.payCharge(charge, charge.getAmountOutstanding(this.getCurrency()), transactionDate, user);
|
||||
}
|
||||
|
||||
+4
@@ -677,6 +677,10 @@ public class SavingsAccountCharge extends AbstractPersistableCustom {
|
||||
return charge.isEnableFreeWithdrawal();
|
||||
}
|
||||
|
||||
public boolean isEnablePaymentType() {
|
||||
return charge.isEnablePaymentType();
|
||||
}
|
||||
|
||||
public Integer getFrequencyFreeWithdrawalCharge() { // number of times free withdrawal allowed
|
||||
return charge.getFrequencyFreeWithdrawalCharge();
|
||||
}
|
||||
|
||||
+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.
|
||||
--
|
||||
|
||||
ALTER TABLE `m_charge`
|
||||
ADD COLUMN `is_payment_type` INT NULL DEFAULT '0' AFTER `restart_frequency_enum`;
|
||||
|
||||
ALTER TABLE `m_charge`
|
||||
ADD COLUMN `payment_type_id` INT(11) NULL DEFAULT NULL AFTER `is_payment_type`;
|
||||
|
||||
ALTER TABLE `m_charge`
|
||||
ADD CONSTRAINT `FK_m_payment_detail_m_payment_types` FOREIGN KEY (`payment_type_id`) REFERENCES `m_payment_type` (`id`);
|
||||
+83
@@ -42,6 +42,7 @@ import java.util.Locale;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.apache.fineract.integrationtests.common.CommonConstants;
|
||||
import org.apache.fineract.integrationtests.common.PaymentTypeHelper;
|
||||
import org.apache.fineract.integrationtests.common.SchedulerJobHelper;
|
||||
import org.apache.fineract.integrationtests.common.TaxComponentHelper;
|
||||
import org.apache.fineract.integrationtests.common.TaxGroupHelper;
|
||||
@@ -2127,4 +2128,86 @@ public class ClientSavingsIntegrationTest {
|
||||
assertEquals(balance, summary.get("accountBalance"), "Verifying opening Balance is -300");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSavingsAccountWithdrawalChargesOnPaymentTypes() {
|
||||
|
||||
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
|
||||
|
||||
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
|
||||
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
|
||||
|
||||
final String minBalanceForInterestCalculation = null;
|
||||
final String minRequiredBalance = null;
|
||||
final String enforceMinRequiredBalance = "false";
|
||||
final boolean allowOverdraft = false;
|
||||
final String MINIMUM_OPENING_BALANCE = "10000";
|
||||
final String withdrawalAmountOne = "1000";
|
||||
final String withdrawalAmountTwo = "2000";
|
||||
final Integer withdrawalChargeOne = 10;
|
||||
final Integer withdrawalChargeTwo = 20;
|
||||
|
||||
final Integer savingsProductID = createSavingsProduct(this.requestSpec, this.responseSpec, MINIMUM_OPENING_BALANCE,
|
||||
minBalanceForInterestCalculation, minRequiredBalance, enforceMinRequiredBalance, allowOverdraft);
|
||||
Assertions.assertNotNull(savingsProductID);
|
||||
|
||||
final Integer savingsId = this.savingsAccountHelper.applyForSavingsApplication(clientID, savingsProductID, ACCOUNT_TYPE_INDIVIDUAL);
|
||||
Assertions.assertNotNull(savingsProductID);
|
||||
|
||||
HashMap savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(this.requestSpec, this.responseSpec, savingsId);
|
||||
SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap);
|
||||
|
||||
savingsStatusHashMap = this.savingsAccountHelper.approveSavings(savingsId);
|
||||
SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
|
||||
|
||||
savingsStatusHashMap = this.savingsAccountHelper.activateSavings(savingsId);
|
||||
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
|
||||
|
||||
String name = PaymentTypeHelper.randomNameGenerator("P_T", 5);
|
||||
String description = PaymentTypeHelper.randomNameGenerator("PT_Desc", 15);
|
||||
Boolean isCashPayment = false;
|
||||
Integer position = 1;
|
||||
|
||||
Integer paymentTypeIdOne = PaymentTypeHelper.createPaymentType(requestSpec, responseSpec, name, description, isCashPayment,
|
||||
position);
|
||||
Assertions.assertNotNull(paymentTypeIdOne);
|
||||
|
||||
final Integer chargeIdOne = ChargesHelper.createCharges(this.requestSpec, this.responseSpec,
|
||||
ChargesHelper.paymentTypeCharge(withdrawalChargeOne, true, paymentTypeIdOne));
|
||||
Assertions.assertNotNull(chargeIdOne);
|
||||
|
||||
this.savingsAccountHelper.addChargesForSavings(savingsId, chargeIdOne, false, BigDecimal.valueOf(withdrawalChargeOne));
|
||||
|
||||
Integer withdrawTransactionIdOne = (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccountWithPaymentType(savingsId,
|
||||
withdrawalAmountOne, SavingsAccountHelper.TRANSACTION_DATE, paymentTypeIdOne.toString(),
|
||||
CommonConstants.RESPONSE_RESOURCE_ID);
|
||||
|
||||
Float balance = Float.parseFloat("8990");
|
||||
// Withdraw charge from paymentType 1 is 10 So balance should be 10,000(deposit)-1000(wd)-"10(charge)" = 8990
|
||||
|
||||
HashMap summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
|
||||
assertEquals(balance, summary.get("accountBalance"), "Verifying Balance after withdrawal charge ");
|
||||
|
||||
String paymentTypeNameTwo = PaymentTypeHelper.randomNameGenerator("P_T", 5);
|
||||
|
||||
Integer paymentTypeIdTwo = PaymentTypeHelper.createPaymentType(requestSpec, responseSpec, paymentTypeNameTwo, description,
|
||||
isCashPayment, position);
|
||||
Assertions.assertNotNull(paymentTypeIdTwo);
|
||||
|
||||
final Integer chargeIdTwo = ChargesHelper.createCharges(this.requestSpec, this.responseSpec,
|
||||
ChargesHelper.paymentTypeCharge(withdrawalChargeTwo, true, paymentTypeIdTwo));
|
||||
Assertions.assertNotNull(chargeIdTwo);
|
||||
|
||||
this.savingsAccountHelper.addChargesForSavings(savingsId, chargeIdTwo, false, BigDecimal.valueOf(withdrawalChargeTwo));
|
||||
|
||||
Integer withdrawTransactionIdTwo = (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccountWithPaymentType(savingsId,
|
||||
withdrawalAmountTwo, SavingsAccountHelper.TRANSACTION_DATE, paymentTypeIdTwo.toString(),
|
||||
CommonConstants.RESPONSE_RESOURCE_ID);
|
||||
|
||||
Float balanceAfterChargeTwo = Float.parseFloat("6970");
|
||||
// Withdraw charge from paymentType 2 is 20 So balance should be 8990(balance)-2000(wd)-"20(charge)" = 6970
|
||||
|
||||
HashMap summaryTwo = this.savingsAccountHelper.getSavingsSummary(savingsId);
|
||||
assertEquals(balanceAfterChargeTwo, summaryTwo.get("accountBalance"), "Verifying Balance after withdrawal charge two ");
|
||||
}
|
||||
}
|
||||
|
||||
+21
@@ -188,6 +188,27 @@ public final class ChargesHelper {
|
||||
return chargesCreateJson;
|
||||
}
|
||||
|
||||
public static String paymentTypeCharge(Integer amount, final boolean enablePaymentType, final Integer paymentTypeId) {
|
||||
return paymentTypeChargeJSON(amount, enablePaymentType, paymentTypeId);
|
||||
}
|
||||
|
||||
public static String paymentTypeChargeJSON(Integer amount, final boolean enablePaymentType, final Integer paymentTypeId) {
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("active", ChargesHelper.ACTIVE);
|
||||
map.put("amount", amount);
|
||||
map.put("chargeAppliesTo", ChargesHelper.CHARGE_APPLIES_TO_SAVINGS);
|
||||
map.put("chargeCalculationType", ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT);
|
||||
map.put("currencyCode", ChargesHelper.CURRENCY_CODE);
|
||||
map.put("locale", CommonConstants.LOCALE);
|
||||
map.put("monthDayFormat", ChargesHelper.MONTH_DAY_FORMAT);
|
||||
map.put("name", Utils.randomNameGenerator("Charge_Savings_", 6));
|
||||
map.put("chargeTimeType", CHARGE_WITHDRAWAL_FEE);
|
||||
map.put("enablePaymentType", enablePaymentType);
|
||||
map.put("paymentTypeId", paymentTypeId);
|
||||
String paymentTypeJson = new Gson().toJson(map);
|
||||
return paymentTypeJson;
|
||||
}
|
||||
|
||||
public static String getLoanSpecifiedDueDateJSON() {
|
||||
return getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, ChargesHelper.AMOUNT, ChargesHelper.PENALTY);
|
||||
}
|
||||
|
||||
+19
@@ -253,6 +253,13 @@ public class SavingsAccountHelper {
|
||||
getSavingsTransactionJSON(amount, date), jsonAttributeToGetback);
|
||||
}
|
||||
|
||||
public Object withdrawalFromSavingsAccountWithPaymentType(final Integer savingsId, final String amount, String date, String paymentType,
|
||||
String jsonAttributeToGetback) {
|
||||
LOG.info("\n--------------------------------- SAVINGS TRANSACTION WITHDRAWAL WITH PAYMENT TYPE--------------------------------");
|
||||
return performSavingActions(createSavingsTransactionURL(WITHDRAW_SAVINGS_COMMAND, savingsId),
|
||||
getSavingsTransactionPaymentTypeJSON(amount, date, paymentType), jsonAttributeToGetback);
|
||||
}
|
||||
|
||||
public Integer updateSavingsAccountTransaction(final Integer savingsId, final Integer transactionId, final String amount) {
|
||||
LOG.info("\n--------------------------------- MODIFY SAVINGS TRANSACTION --------------------------------");
|
||||
return (Integer) performSavingActions(createAdjustTransactionURL(MODIFY_TRASACTION_COMMAND, savingsId, transactionId),
|
||||
@@ -432,6 +439,18 @@ public class SavingsAccountHelper {
|
||||
return savingsAccountWithdrawalJson;
|
||||
}
|
||||
|
||||
private String getSavingsTransactionPaymentTypeJSON(final String amount, final String transactionDate, final String paymentTypeId) {
|
||||
final HashMap<String, String> map = new HashMap<>();
|
||||
map.put("locale", CommonConstants.LOCALE);
|
||||
map.put("dateFormat", CommonConstants.DATE_FORMAT);
|
||||
map.put("transactionDate", transactionDate);
|
||||
map.put("transactionAmount", amount);
|
||||
map.put("paymentTypeId", paymentTypeId);
|
||||
String savingsAccountWithdrawalJson = new Gson().toJson(map);
|
||||
LOG.info(savingsAccountWithdrawalJson);
|
||||
return savingsAccountWithdrawalJson;
|
||||
}
|
||||
|
||||
private String getCalculatedInterestForSavingsApplicationAsJSON() {
|
||||
final HashMap<String, String> map = new HashMap<>();
|
||||
String savingsAccountCalculatedInterestJson = new Gson().toJson(map);
|
||||
|
||||
Reference in New Issue
Block a user