This is an automated email from the ASF dual-hosted git repository.

ptuomola pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 2513ee4  FINERACT-1390:WithdrawChargesPerPaymentType
2513ee4 is described below

commit 2513ee48379fec73c4ef4497efc8729fe15217a7
Author: rrpawar96 <[email protected]>
AuthorDate: Sat Jan 1 02:10:21 2022 +0530

    FINERACT-1390:WithdrawChargesPerPaymentType
---
 .../fineract/portfolio/charge/data/ChargeData.java | 85 ++++++++++++----------
 .../fineract/portfolio/charge/domain/Charge.java   | 69 ++++++++++++++++--
 ...geDefinitionCommandFromApiJsonDeserializer.java | 26 ++++++-
 .../service/ChargeReadPlatformServiceImpl.java     | 19 ++++-
 ...hargeWritePlatformServiceJpaRepositoryImpl.java | 28 ++++++-
 .../portfolio/paymenttype/domain/PaymentType.java  |  4 +
 .../portfolio/savings/domain/SavingsAccount.java   | 17 ++++-
 .../savings/domain/SavingsAccountCharge.java       |  4 +
 .../V271_2__withdrawal_charges_paymenttype.sql     | 27 +++++++
 .../ClientSavingsIntegrationTest.java              | 83 +++++++++++++++++++++
 .../common/charges/ChargesHelper.java              | 21 ++++++
 .../common/savings/SavingsAccountHelper.java       | 19 +++++
 12 files changed, 349 insertions(+), 53 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/data/ChargeData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/data/ChargeData.java
index d070c3a..1b4c47a 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/data/ChargeData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/data/ChargeData.java
@@ -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;
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/Charge.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/Charge.java
index 670db81..ea1eda4 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/Charge.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/Charge.java
@@ -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() {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/serialization/ChargeDefinitionCommandFromApiJsonDeserializer.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/serialization/ChargeDefinitionCommandFromApiJsonDeserializer.java
index e5d35e8..eee9ff9 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/serialization/ChargeDefinitionCommandFromApiJsonDeserializer.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/serialization/ChargeDefinitionCommandFromApiJsonDeserializer.java
@@ -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)) {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeReadPlatformServiceImpl.java
index 26f46ea..cf9ab4e 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeReadPlatformServiceImpl.java
@@ -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);
         }
     }
 
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java
index 22959c0..e11d44a 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java
@@ -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;
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentType.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentType.java
index aaac576..1207eba 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentType.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentType.java
@@ -97,4 +97,8 @@ public class PaymentType extends AbstractPersistableCustom {
         return isCashPayment;
     }
 
+    public String getPaymentName() {
+        return name;
+    }
+
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java
index b882955..a33c8e3 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java
@@ -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);
                 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountCharge.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountCharge.java
index f0e8401..4e35d0b 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountCharge.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountCharge.java
@@ -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();
     }
diff --git 
a/fineract-provider/src/main/resources/sql/migrations/core_db/V271_2__withdrawal_charges_paymenttype.sql
 
b/fineract-provider/src/main/resources/sql/migrations/core_db/V271_2__withdrawal_charges_paymenttype.sql
new file mode 100644
index 0000000..8a77ba4
--- /dev/null
+++ 
b/fineract-provider/src/main/resources/sql/migrations/core_db/V271_2__withdrawal_charges_paymenttype.sql
@@ -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`);
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
index e3acbaa..cb843e4 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
@@ -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 ");
+    }
 }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/charges/ChargesHelper.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/charges/ChargesHelper.java
index 32ce65b..b2401d2 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/charges/ChargesHelper.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/charges/ChargesHelper.java
@@ -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);
     }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
index 0507f3e..f076950 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
@@ -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);

Reply via email to