client fees : adding client transaction api's

This commit is contained in:
Vishwas Babu A J
2015-08-20 01:45:20 +05:30
parent b6626b0b83
commit 340aa20120
22 changed files with 357 additions and 146 deletions
@@ -49,6 +49,8 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
private final List<EnumOptionData> loanChargeTimeTypeOptions;
private final List<EnumOptionData> savingsChargeCalculationTypeOptions;
private final List<EnumOptionData> savingsChargeTimeTypeOptions;
private final List<EnumOptionData> clientChargeCalculationTypeOptions;
private final List<EnumOptionData> clientChargeTimeTypeOptions;
private final List<EnumOptionData> feeFrequencyOptions;
public static ChargeData template(final Collection<CurrencyData> currencyOptions,
@@ -56,12 +58,13 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
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 List<EnumOptionData> feeFrequencyOptions) {
return new ChargeData(null, null, null, null, null, null, null, null, false, false, currencyOptions, chargeCalculationTypeOptions,
chargeAppliesToOptions, chargeTimeTypeOptions, chargePaymentModeOptions, loansChargeCalculationTypeOptions,
loansChargeTimeTypeOptions, savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, null, null, null, null,
null, feeFrequencyOptions);
loansChargeTimeTypeOptions, savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions,
clientChargeCalculationTypeOptions, clientChargeTimeTypeOptions, null, null, null, null, null, feeFrequencyOptions);
}
public static ChargeData withTemplate(final ChargeData charge, final ChargeData template) {
@@ -69,8 +72,9 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
charge.chargeCalculationType, charge.chargePaymentMode, charge.penalty, charge.active, template.currencyOptions,
template.chargeCalculationTypeOptions, template.chargeAppliesToOptions, template.chargeTimeTypeOptions,
template.chargePaymetModeOptions, template.loanChargeCalculationTypeOptions, template.loanChargeTimeTypeOptions,
template.savingsChargeCalculationTypeOptions, template.savingsChargeTimeTypeOptions, charge.feeOnMonthDay,
charge.feeInterval, charge.minCap, charge.maxCap, charge.feeFrequency, template.feeFrequencyOptions);
template.savingsChargeCalculationTypeOptions, template.savingsChargeTimeTypeOptions,
template.clientChargeCalculationTypeOptions, template.clientChargeTimeTypeOptions, charge.feeOnMonthDay, charge.feeInterval,
charge.minCap, charge.maxCap, charge.feeFrequency, template.feeFrequencyOptions);
}
public static ChargeData instance(final Long id, final String name, final BigDecimal amount, final CurrencyData currency,
@@ -88,12 +92,14 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
final List<EnumOptionData> savingsChargeCalculationTypeOptions = null;
final List<EnumOptionData> savingsChargeTimeTypeOptions = null;
final List<EnumOptionData> feeFrequencyOptions = null;
final List<EnumOptionData> clientChargeCalculationTypeOptions = null;
final List<EnumOptionData> clientChargeTimeTypeOptions = null;
return new ChargeData(id, name, amount, currency, chargeTimeType, chargeAppliesTo, chargeCalculationType, chargePaymentMode,
penalty, active, currencyOptions, chargeCalculationTypeOptions, chargeAppliesToOptions, chargeTimeTypeOptions,
chargePaymentModeOptions, loansChargeCalculationTypeOptions, loansChargeTimeTypeOptions,
savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, feeOnMonthDay, feeInterval, minCap, maxCap,
feeFrequency, feeFrequencyOptions);
savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, clientChargeCalculationTypeOptions,
clientChargeTimeTypeOptions, feeOnMonthDay, feeInterval, minCap, maxCap, feeFrequency, feeFrequencyOptions);
}
public static ChargeData lookup(final Long id, final String name, final boolean isPenalty) {
@@ -118,14 +124,16 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
final List<EnumOptionData> loansChargeTimeTypeOptions = null;
final List<EnumOptionData> savingsChargeCalculationTypeOptions = null;
final List<EnumOptionData> savingsChargeTimeTypeOptions = null;
final List<EnumOptionData> clientChargeCalculationTypeOptions = null;
final List<EnumOptionData> clientChargeTimeTypeOptions = null;
final EnumOptionData feeFrequency = null;
final List<EnumOptionData> feeFrequencyOptions = null;
return new ChargeData(id, name, amount, currency, chargeTimeType, chargeAppliesTo, chargeCalculationType, chargePaymentMode,
penalty, active, currencyOptions, chargeCalculationTypeOptions, chargeAppliesToOptions, chargeTimeTypeOptions,
chargePaymentModeOptions, loansChargeCalculationTypeOptions, loansChargeTimeTypeOptions,
savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, feeOnMonthDay, feeInterval, minCap, maxCap,
feeFrequency, feeFrequencyOptions);
savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, clientChargeCalculationTypeOptions,
clientChargeTimeTypeOptions, feeOnMonthDay, feeInterval, minCap, maxCap, feeFrequency, feeFrequencyOptions);
}
private ChargeData(final Long id, final String name, final BigDecimal amount, final CurrencyData currency,
@@ -135,7 +143,8 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
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 MonthDay feeOnMonthDay, final Integer feeInterval,
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) {
this.id = id;
@@ -159,6 +168,8 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
this.chargePaymetModeOptions = chargePaymentModeOptions;
this.savingsChargeCalculationTypeOptions = savingsChargeCalculationTypeOptions;
this.savingsChargeTimeTypeOptions = savingsChargeTimeTypeOptions;
this.clientChargeCalculationTypeOptions = clientChargeCalculationTypeOptions;
this.clientChargeTimeTypeOptions = clientChargeTimeTypeOptions;
this.loanChargeCalculationTypeOptions = loansChargeCalculationTypeOptions;
this.loanChargeTimeTypeOptions = loansChargeTimeTypeOptions;
this.feeFrequency = feeFrequency;
@@ -210,18 +221,18 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
final LocalDate inactivationDate = null;
return SavingsAccountChargeData.instance(savingsChargeId, this.id, savingsAccountId, this.name, this.currency, this.amount,
amountPaid, amountWaived, amountWrittenOff, amountOutstanding, this.chargeTimeType, dueAsOfDate,
this.chargeCalculationType, percentage, amountPercentageAppliedTo, chargeOptions, this.penalty, this.feeOnMonthDay,
this.feeInterval, isActive, inactivationDate);
amountPaid, amountWaived, amountWrittenOff, amountOutstanding, this.chargeTimeType, dueAsOfDate, this.chargeCalculationType,
percentage, amountPercentageAppliedTo, chargeOptions, this.penalty, this.feeOnMonthDay, this.feeInterval, isActive,
inactivationDate);
}
public boolean isPenalty() {
return this.penalty;
}
public boolean isOverdueInstallmentCharge(){
public boolean isOverdueInstallmentCharge() {
boolean isOverdueInstallmentCharge = false;
if(this.chargeTimeType != null){
if (this.chargeTimeType != null) {
isOverdueInstallmentCharge = ChargeTimeType.fromInt(this.chargeTimeType.getId().intValue()).isOverdueInstallment();
}
return isOverdueInstallmentCharge;
@@ -93,8 +93,8 @@ public class Charge extends AbstractPersistable<Long> {
final ChargeAppliesTo chargeAppliesTo = ChargeAppliesTo.fromInt(command.integerValueOfParameterNamed("chargeAppliesTo"));
final ChargeTimeType chargeTimeType = ChargeTimeType.fromInt(command.integerValueOfParameterNamed("chargeTimeType"));
final ChargeCalculationType chargeCalculationType = ChargeCalculationType.fromInt(command
.integerValueOfParameterNamed("chargeCalculationType"));
final ChargeCalculationType chargeCalculationType = ChargeCalculationType
.fromInt(command.integerValueOfParameterNamed("chargeCalculationType"));
final Integer chargePaymentMode = command.integerValueOfParameterNamed("chargePaymentMode");
final ChargePaymentMode paymentMode = chargePaymentMode == null ? null : ChargePaymentMode.fromInt(chargePaymentMode);
@@ -116,9 +116,9 @@ public class Charge extends AbstractPersistable<Long> {
}
private Charge(final String name, final BigDecimal amount, final String currencyCode, final ChargeAppliesTo chargeAppliesTo,
final ChargeTimeType chargeTime, final ChargeCalculationType chargeCalculationType, final boolean penalty,
final boolean active, final ChargePaymentMode paymentMode, final MonthDay feeOnMonthDay, final Integer feeInterval,
final BigDecimal minCap, final BigDecimal maxCap, final Integer feeFrequency) {
final ChargeTimeType chargeTime, final ChargeCalculationType chargeCalculationType, final boolean penalty, final boolean active,
final ChargePaymentMode paymentMode, final MonthDay feeOnMonthDay, final Integer feeInterval, final BigDecimal minCap,
final BigDecimal maxCap, final Integer feeFrequency) {
this.name = name;
this.amount = amount;
this.currencyCode = currencyCode;
@@ -140,12 +140,14 @@ public class Charge extends AbstractPersistable<Long> {
this.feeFrequency = feeFrequency;
if (isSavingsCharge()) {
// TODO vishwas, this validation seems unnecessary as identical
// validation is performed in the write service
if (!isAllowedSavingsChargeTime()) {
baseDataValidator.reset().parameter("chargeTimeType").value(this.chargeTime)
.failWithCodeNoParameterAddedToErrorCode("not.allowed.charge.time.for.savings");
}
// TODO vishwas, this validation seems unnecessary as identical
// validation is performed in the writeservice
if (!isAllowedSavingsChargeCalculationType()) {
baseDataValidator.reset().parameter("chargeCalculationType").value(this.chargeCalculation)
.failWithCodeNoParameterAddedToErrorCode("not.allowed.charge.calculation.type.for.savings");
@@ -161,6 +163,8 @@ public class Charge extends AbstractPersistable<Long> {
if (penalty && chargeTime.isTimeOfDisbursement()) { throw new ChargeDueAtDisbursementCannotBePenaltyException(name); }
if (!penalty && chargeTime.isOverdueInstallment()) { throw new ChargeMustBePenaltyException(name); }
// TODO vishwas, this validation seems unnecessary as identical
// validation is performed in the write service
if (!isAllowedLoanChargeTime()) {
baseDataValidator.reset().parameter("chargeTimeType").value(this.chargeTime)
.failWithCodeNoParameterAddedToErrorCode("not.allowed.charge.time.for.loan");
@@ -232,10 +236,18 @@ public class Charge extends AbstractPersistable<Long> {
return ChargeTimeType.fromInt(this.chargeTime).isAllowedLoanChargeTime();
}
public boolean isAllowedClientChargeTime() {
return ChargeTimeType.fromInt(this.chargeTime).isAllowedClientChargeTime();
}
public boolean isSavingsCharge() {
return ChargeAppliesTo.fromInt(this.chargeAppliesTo).isSavingsCharge();
}
public boolean isClientCharge() {
return ChargeAppliesTo.fromInt(this.chargeAppliesTo).isClientCharge();
}
public boolean isAllowedSavingsChargeTime() {
return ChargeTimeType.fromInt(this.chargeTime).isAllowedSavingsChargeTime();
}
@@ -244,6 +256,10 @@ public class Charge extends AbstractPersistable<Long> {
return ChargeCalculationType.fromInt(this.chargeCalculation).isAllowedSavingsChargeCalculationType();
}
public boolean isAllowedClientChargeCalculationType() {
return ChargeCalculationType.fromInt(this.chargeCalculation).isAllowedClientChargeCalculationType();
}
public boolean isPercentageOfAmount() {
return ChargeCalculationType.fromInt(this.chargeCalculation).isPercentageOfAmount();
}
@@ -313,6 +329,11 @@ public class Charge extends AbstractPersistable<Long> {
baseDataValidator.reset().parameter("chargeTimeType").value(this.chargeTime)
.failWithCodeNoParameterAddedToErrorCode("not.allowed.charge.time.for.loan");
}
} else if (isClientCharge()) {
if (!isAllowedLoanChargeTime()) {
baseDataValidator.reset().parameter("chargeTimeType").value(this.chargeTime)
.failWithCodeNoParameterAddedToErrorCode("not.allowed.charge.time.for.client");
}
}
}
@@ -349,6 +370,11 @@ public class Charge extends AbstractPersistable<Long> {
baseDataValidator.reset().parameter("chargeCalculationType").value(this.chargeCalculation)
.failWithCodeNoParameterAddedToErrorCode("charge.calculation.type.percentage.allowed.only.for.withdrawal");
}
} else if (isClientCharge()) {
if (!isAllowedClientChargeCalculationType()) {
baseDataValidator.reset().parameter("chargeCalculationType").value(this.chargeCalculation)
.failWithCodeNoParameterAddedToErrorCode("not.allowed.charge.calculation.type.for.client");
}
}
}
@@ -387,7 +413,7 @@ public class Charge extends AbstractPersistable<Long> {
actualChanges.put("locale", localeAsInput);
this.feeInterval = newValue;
}
final String feeFrequency = "feeFrequency";
if (command.isChangeInIntegerParameterNamed(feeFrequency, this.feeFrequency)) {
final Integer newValue = command.integerValueOfParameterNamed(feeFrequency);
@@ -395,8 +421,8 @@ public class Charge extends AbstractPersistable<Long> {
actualChanges.put("locale", localeAsInput);
this.feeFrequency = newValue;
}
if(this.feeFrequency != null){
if (this.feeFrequency != null) {
baseDataValidator.reset().parameter("feeInterval").value(this.feeInterval).notNull();
}
@@ -431,8 +457,8 @@ public class Charge extends AbstractPersistable<Long> {
}
}
if (this.penalty && ChargeTimeType.fromInt(this.chargeTime).isTimeOfDisbursement()) { throw new ChargeDueAtDisbursementCannotBePenaltyException(
this.name); }
if (this.penalty && ChargeTimeType.fromInt(this.chargeTime)
.isTimeOfDisbursement()) { throw new ChargeDueAtDisbursementCannotBePenaltyException(this.name); }
if (!penalty && ChargeTimeType.fromInt(this.chargeTime).isOverdueInstallment()) { throw new ChargeMustBePenaltyException(name); }
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
@@ -467,9 +493,9 @@ public class Charge extends AbstractPersistable<Long> {
public Integer getChargePaymentMode() {
return this.chargePaymentMode;
}
public Integer getFeeInterval(){
return this.feeInterval;
public Integer getFeeInterval() {
return this.feeInterval;
}
public boolean isMonthlyFee() {
@@ -9,7 +9,8 @@ public enum ChargeAppliesTo {
INVALID(0, "chargeAppliesTo.invalid"), //
LOAN(1, "chargeAppliesTo.loan"), //
SAVINGS(2, "chargeAppliesTo.savings");
SAVINGS(2, "chargeAppliesTo.savings"), //
CLIENT(3, "chargeAppliesTo.client");
private final Integer value;
private final String code;
@@ -38,6 +39,9 @@ public enum ChargeAppliesTo {
case 2:
chargeAppliesToType = SAVINGS;
break;
case 3:
chargeAppliesToType = CLIENT;
break;
default:
chargeAppliesToType = INVALID;
break;
@@ -55,7 +59,11 @@ public enum ChargeAppliesTo {
return this.value.equals(ChargeAppliesTo.SAVINGS.getValue());
}
public boolean isClientCharge() {
return this.value.equals(ChargeAppliesTo.CLIENT.getValue());
}
public static Object[] validValues() {
return new Object[] { ChargeAppliesTo.LOAN.getValue(), ChargeAppliesTo.SAVINGS.getValue() };
return new Object[] { ChargeAppliesTo.LOAN.getValue(), ChargeAppliesTo.SAVINGS.getValue(), ChargeAppliesTo.CLIENT.getValue() };
}
}
@@ -38,6 +38,10 @@ public enum ChargeCalculationType {
return new Integer[] { ChargeCalculationType.FLAT.getValue(), ChargeCalculationType.PERCENT_OF_AMOUNT.getValue() };
}
public static Object[] validValuesForClients() {
return new Integer[] { ChargeCalculationType.FLAT.getValue() };
}
public static ChargeCalculationType fromInt(final Integer chargeCalculation) {
ChargeCalculationType chargeCalculationType = ChargeCalculationType.INVALID;
switch (chargeCalculation) {
@@ -77,6 +81,10 @@ public enum ChargeCalculationType {
return isFlat() || isPercentageOfAmount();
}
public boolean isAllowedClientChargeCalculationType() {
return isFlat();
}
public boolean isPercentageBased() {
return isPercentageOfAmount() || isPercentageOfAmountAndInterest() || isPercentageOfInterest();
}
@@ -20,7 +20,7 @@ public enum ChargeTimeType {
INSTALMENT_FEE(8, "chargeTimeType.instalmentFee"), // only for loan charges
OVERDUE_INSTALLMENT(9, "chargeTimeType.overdueInstallment"), // only for
// loan charges
OVERDRAFT_FEE(10, "chargeTimeType.overdraftFee"),// only for savings
OVERDRAFT_FEE(10, "chargeTimeType.overdraftFee"), // only for savings
WEEKLY_FEE(11, "chargeTimeType.weeklyFee"); // only for savings
private final Integer value;
@@ -43,10 +43,10 @@ public enum ChargeTimeType {
return new Integer[] { ChargeTimeType.DISBURSEMENT.getValue(), ChargeTimeType.SPECIFIED_DUE_DATE.getValue(),
ChargeTimeType.INSTALMENT_FEE.getValue(), ChargeTimeType.OVERDUE_INSTALLMENT.getValue() };
}
public static Object[] validLoanChargeValues() {
return new Integer[] { ChargeTimeType.DISBURSEMENT.getValue(), ChargeTimeType.SPECIFIED_DUE_DATE.getValue(),
ChargeTimeType.INSTALMENT_FEE.getValue()};
ChargeTimeType.INSTALMENT_FEE.getValue() };
}
public static Object[] validSavingsValues() {
@@ -55,6 +55,10 @@ public enum ChargeTimeType {
ChargeTimeType.MONTHLY_FEE.getValue(), ChargeTimeType.OVERDRAFT_FEE.getValue(), ChargeTimeType.WEEKLY_FEE.getValue() };
}
public static Object[] validClientValues() {
return new Integer[] { ChargeTimeType.SPECIFIED_DUE_DATE.getValue() };
}
public static ChargeTimeType fromInt(final Integer chargeTime) {
ChargeTimeType chargeTimeType = ChargeTimeType.INVALID;
if (chargeTime != null) {
@@ -127,11 +131,11 @@ public enum ChargeTimeType {
public boolean isMonthlyFee() {
return this.value.equals(ChargeTimeType.MONTHLY_FEE.getValue());
}
public boolean isWeeklyFee() {
return this.value.equals(ChargeTimeType.WEEKLY_FEE.getValue());
return this.value.equals(ChargeTimeType.WEEKLY_FEE.getValue());
}
public boolean isInstalmentFee() {
return this.value.equals(ChargeTimeType.INSTALMENT_FEE.getValue());
}
@@ -144,9 +148,13 @@ public enum ChargeTimeType {
return isTimeOfDisbursement() || isOnSpecifiedDueDate() || isInstalmentFee() || isOverdueInstallment();
}
public boolean isAllowedClientChargeTime() {
return isOnSpecifiedDueDate();
}
public boolean isAllowedSavingsChargeTime() {
return isOnSpecifiedDueDate() || isSavingsActivation() || isSavingsClosure() || isWithdrawalFee() || isAnnualFee()
|| isMonthlyFee() || isWeeklyFee() || isOverdraftFee();
return isOnSpecifiedDueDate() || isSavingsActivation() || isSavingsClosure() || isWithdrawalFee() || isAnnualFee() || isMonthlyFee()
|| isWeeklyFee() || isOverdraftFee();
}
public boolean isOverdraftFee() {
@@ -116,8 +116,8 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
if (ctt.isWeeklyFee()) {
final String monthDay = this.fromApiJsonHelper.extractStringNamed("feeOnMonthDay", element);
baseDataValidator.reset().parameter("feeOnMonthDay").value(monthDay)
.mustBeBlankWhenParameterProvidedIs("chargeTimeType", chargeTimeType);
baseDataValidator.reset().parameter("feeOnMonthDay").value(monthDay).mustBeBlankWhenParameterProvidedIs("chargeTimeType",
chargeTimeType);
}
if (ctt.isMonthlyFee()) {
@@ -132,6 +132,22 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
baseDataValidator.reset().parameter("feeOnMonthDay").value(monthDay).notNull();
}
if (chargeCalculationType != null) {
baseDataValidator.reset().parameter("chargeCalculationType").value(chargeCalculationType)
.isOneOfTheseValues(ChargeCalculationType.validValuesForSavings());
}
} else if (appliesTo.isClientCharge()) {
// client applicable validation
final Integer chargeTimeType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed("chargeTimeType", element);
baseDataValidator.reset().parameter("chargeTimeType").value(chargeTimeType).notNull();
if (chargeTimeType != null) {
baseDataValidator.reset().parameter("chargeTimeType").value(chargeTimeType)
.isOneOfTheseValues(ChargeTimeType.validClientValues());
}
// final ChargeTimeType ctt =
// ChargeTimeType.fromInt(chargeTimeType);
if (chargeCalculationType != null) {
baseDataValidator.reset().parameter("chargeCalculationType").value(chargeCalculationType)
.isOneOfTheseValues(ChargeCalculationType.validValuesForSavings());
@@ -217,9 +233,11 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
final Collection<Object> validLoanValues = Arrays.asList(ChargeTimeType.validLoanValues());
final Collection<Object> validSavingsValues = Arrays.asList(ChargeTimeType.validSavingsValues());
final Collection<Object> validClientValues = Arrays.asList(ChargeTimeType.validClientValues());
final Collection<Object> allValidValues = new ArrayList<>(validLoanValues);
allValidValues.addAll(validSavingsValues);
allValidValues.addAll(validClientValues);
baseDataValidator.reset().parameter("chargeTimeType").value(chargeTimeType).notNull()
.isOneOfTheseValues(allValidValues.toArray(new Object[allValidValues.size()]));
@@ -27,4 +27,8 @@ public interface ChargeDropdownReadPlatformService {
List<EnumOptionData> retrieveSavingsCollectionTimeTypes();
List<EnumOptionData> retrieveClientCalculationTypes();
List<EnumOptionData> retrieveClientCollectionTimeTypes();
}
@@ -87,4 +87,14 @@ public class ChargeDropdownReadPlatformServiceImpl implements ChargeDropdownRead
chargeTimeType(ChargeTimeType.MONTHLY_FEE), chargeTimeType(ChargeTimeType.WEEKLY_FEE),
chargeTimeType(ChargeTimeType.OVERDRAFT_FEE));
}
@Override
public List<EnumOptionData> retrieveClientCalculationTypes() {
return Arrays.asList(chargeCalculationType(ChargeCalculationType.FLAT));
}
@Override
public List<EnumOptionData> retrieveClientCollectionTimeTypes() {
return Arrays.asList(chargeTimeType(ChargeTimeType.SPECIFIED_DUE_DATE));
}
}
@@ -49,9 +49,9 @@ public class ChargeEnumerations {
"Monthly Fee");
break;
case WEEKLY_FEE:
optionData = new EnumOptionData(ChargeTimeType.WEEKLY_FEE.getValue().longValue(), ChargeTimeType.WEEKLY_FEE.getCode(),
"Weekly Fee");
break;
optionData = new EnumOptionData(ChargeTimeType.WEEKLY_FEE.getValue().longValue(), ChargeTimeType.WEEKLY_FEE.getCode(),
"Weekly Fee");
break;
case INSTALMENT_FEE:
optionData = new EnumOptionData(ChargeTimeType.INSTALMENT_FEE.getValue().longValue(),
ChargeTimeType.INSTALMENT_FEE.getCode(), "Installment Fee");
@@ -61,8 +61,8 @@ public class ChargeEnumerations {
ChargeTimeType.OVERDUE_INSTALLMENT.getCode(), "Overdue Fees");
break;
case OVERDRAFT_FEE:
optionData = new EnumOptionData(ChargeTimeType.OVERDRAFT_FEE.getValue().longValue(),
ChargeTimeType.OVERDRAFT_FEE.getCode(), "Overdraft Fee");
optionData = new EnumOptionData(ChargeTimeType.OVERDRAFT_FEE.getValue().longValue(), ChargeTimeType.OVERDRAFT_FEE.getCode(),
"Overdraft Fee");
break;
default:
optionData = new EnumOptionData(ChargeTimeType.INVALID.getValue().longValue(), ChargeTimeType.INVALID.getCode(), "Invalid");
@@ -85,6 +85,9 @@ public class ChargeEnumerations {
optionData = new EnumOptionData(ChargeAppliesTo.SAVINGS.getValue().longValue(), ChargeAppliesTo.SAVINGS.getCode(),
"Savings");
break;
case CLIENT:
optionData = new EnumOptionData(ChargeAppliesTo.CLIENT.getValue().longValue(), ChargeAppliesTo.CLIENT.getCode(), "Client");
break;
default:
optionData = new EnumOptionData(ChargeAppliesTo.INVALID.getValue().longValue(), ChargeAppliesTo.INVALID.getCode(),
"Invalid");
@@ -20,6 +20,13 @@ public interface ChargeReadPlatformService {
ChargeData retrieveNewChargeDetails();
/**
* Returns all charges that can be applied to Cients
*
* @return
*/
Collection<ChargeData> retrieveAllChargesApplicableToClients();
/**
* Returns all Fees (excluding penalties) applicable for loans
*
@@ -93,7 +100,7 @@ public interface ChargeReadPlatformService {
* @return
*/
Collection<ChargeData> retrieveSavingsProductCharges(Long savingsProductId);
/** Retrieve savings account charges **/
Collection<ChargeData> retrieveSavingsAccountApplicableCharges(Long savingsId);
@@ -45,12 +45,11 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
private final ChargeDropdownReadPlatformService chargeDropdownReadPlatformService;
private final DropdownReadPlatformService dropdownReadPlatformService;
private final MifosEntityAccessUtil mifosEntityAccessUtil;
@Autowired
public ChargeReadPlatformServiceImpl(final CurrencyReadPlatformService currencyReadPlatformService,
final ChargeDropdownReadPlatformService chargeDropdownReadPlatformService, final RoutingDataSource dataSource,
final DropdownReadPlatformService dropdownReadPlatformService,
final MifosEntityAccessUtil mifosEntityAccessUtil) {
final DropdownReadPlatformService dropdownReadPlatformService, final MifosEntityAccessUtil mifosEntityAccessUtil) {
this.chargeDropdownReadPlatformService = chargeDropdownReadPlatformService;
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.currencyReadPlatformService = currencyReadPlatformService;
@@ -64,10 +63,10 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
final ChargeMapper rm = new ChargeMapper();
String sql = "select " + rm.chargeSchema() + " where c.is_deleted=0 ";
sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled();
sql += " order by c.name ";
sql += " order by c.name ";
return this.jdbcTemplate.query(sql, rm, new Object[] {});
}
@@ -76,12 +75,11 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
public Collection<ChargeData> retrieveAllChargesForCurrency(String currencyCode) {
final ChargeMapper rm = new ChargeMapper();
String sql = "select " + rm.chargeSchema() + " where c.is_deleted=0 and c.currency_code='" + currencyCode
+ "' ";
String sql = "select " + rm.chargeSchema() + " where c.is_deleted=0 and c.currency_code='" + currencyCode + "' ";
sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled();
sql += " order by c.name ";
sql += " order by c.name ";
return this.jdbcTemplate.query(sql, rm, new Object[] {});
}
@@ -92,9 +90,9 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
final ChargeMapper rm = new ChargeMapper();
String sql = "select " + rm.chargeSchema() + " where c.id = ? and c.is_deleted=0 ";
sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled();
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { chargeId });
} catch (final EmptyResultDataAccessException e) {
throw new ChargeNotFoundException(chargeId);
@@ -116,11 +114,15 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
.retrieveSavingsCalculationTypes();
final List<EnumOptionData> savingsChargeTimeTypeOptions = this.chargeDropdownReadPlatformService
.retrieveSavingsCollectionTimeTypes();
final List<EnumOptionData> clientChargeCalculationTypeOptions = this.chargeDropdownReadPlatformService
.retrieveClientCalculationTypes();
final List<EnumOptionData> clientChargeTimeTypeOptions = this.chargeDropdownReadPlatformService.retrieveClientCollectionTimeTypes();
final List<EnumOptionData> feeFrequencyOptions = this.dropdownReadPlatformService.retrievePeriodFrequencyTypeOptions();
return ChargeData.template(currencyOptions, allowedChargeCalculationTypeOptions, allowedChargeAppliesToOptions,
allowedChargeTimeOptions, chargePaymentOptions, loansChargeCalculationTypeOptions, loansChargeTimeTypeOptions,
savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, feeFrequencyOptions);
savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, clientChargeCalculationTypeOptions,
clientChargeTimeTypeOptions, feeFrequencyOptions);
}
@Override
@@ -128,7 +130,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
final ChargeMapper rm = new ChargeMapper();
String sql = "select " + rm.loanProductChargeSchema() + " where c.is_deleted=0 and c.is_active=1 and plc.product_loan_id=? ";
sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled();
return this.jdbcTemplate.query(sql, rm, new Object[] { loanProductId });
@@ -168,7 +170,6 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
+ " and c.is_deleted=0 and c.is_active=1 and c.charge_applies_to_enum=?" + excludeClause + " ";
sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled();
sql += " order by c.name ";
return this.jdbcTemplate.query(sql, rm, params);
}
@@ -219,20 +220,19 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
sql += " order by c.name ";
return this.jdbcTemplate.query(sql, rm, new Object[] { ChargeAppliesTo.LOAN.getValue() });
}
private String addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled () {
String sql = "";
// Check if branch specific products are enabled. If yes, fetch only charges mapped to current user's office
String inClause = mifosEntityAccessUtil.
getSQLWhereClauseForProductIDsForUserOffice_ifGlobalConfigEnabled(
MifosEntityType.CHARGE);
if ( (inClause != null) && (!(inClause.trim().isEmpty())) ) {
sql += " and c.id in ( " + inClause + " ) ";
}
return sql;
private String addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled() {
String sql = "";
// Check if branch specific products are enabled. If yes, fetch only
// charges mapped to current user's office
String inClause = mifosEntityAccessUtil.getSQLWhereClauseForProductIDsForUserOffice_ifGlobalConfigEnabled(MifosEntityType.CHARGE);
if ((inClause != null) && (!(inClause.trim().isEmpty()))) {
sql += " and c.id in ( " + inClause + " ) ";
}
return sql;
}
private static final class ChargeMapper implements RowMapper<ChargeData> {
@@ -312,8 +312,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
public Collection<ChargeData> retrieveSavingsProductApplicableCharges(final boolean feeChargesOnly) {
final ChargeMapper rm = new ChargeMapper();
String sql = "select " + rm.chargeSchema()
+ " where c.is_deleted=0 and c.is_active=1 and c.charge_applies_to_enum=? ";
String sql = "select " + rm.chargeSchema() + " where c.is_deleted=0 and c.is_active=1 and c.charge_applies_to_enum=? ";
if (feeChargesOnly) {
sql = "select " + rm.chargeSchema()
+ " where c.is_deleted=0 and c.is_active=1 and c.is_penalty=0 and c.charge_applies_to_enum=? ";
@@ -339,13 +338,12 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
public Collection<ChargeData> retrieveSavingsProductCharges(final Long savingsProductId) {
final ChargeMapper rm = new ChargeMapper();
String sql = "select " + rm.savingsProductChargeSchema()
+ " where c.is_deleted=0 and c.is_active=1 and spc.savings_product_id=? ";
String sql = "select " + rm.savingsProductChargeSchema() + " where c.is_deleted=0 and c.is_active=1 and spc.savings_product_id=? ";
sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled();
return this.jdbcTemplate.query(sql, rm, new Object[] { savingsProductId });
}
@Override
public Collection<ChargeData> retrieveSavingsAccountApplicableCharges(Long savingsAccountId) {
@@ -354,9 +352,19 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
String sql = "select " + rm.chargeSchema() + " join m_savings_account sa on sa.currency_code = c.currency_code"
+ " where c.is_deleted=0 and c.is_active=1 and c.charge_applies_to_enum=? " + " and sa.account_no = ?";
sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled();
return this.jdbcTemplate.query(sql, rm, new Object[] { ChargeAppliesTo.SAVINGS.getValue(), savingsAccountId });
}
}
@Override
public Collection<ChargeData> retrieveAllChargesApplicableToClients() {
final ChargeMapper rm = new ChargeMapper();
String sql = "select " + rm.chargeSchema() + " where c.is_deleted=0 and c.is_active=1 and c.charge_applies_to_enum=? ";
sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled();
sql += " order by c.name ";
return this.jdbcTemplate.query(sql, rm, new Object[] { ChargeAppliesTo.CLIENT.getValue() });
}
}
@@ -25,6 +25,7 @@ import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamExc
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
import org.mifosplatform.portfolio.client.data.ClientChargeData;
import org.mifosplatform.portfolio.client.service.ClientChargeReadPlatformService;
@@ -82,11 +83,15 @@ public class ClientChargesApiResource {
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveTemplate(@PathParam("savingsAccountId") final Long savingsAccountId, @Context final UriInfo uriInfo) {
public String retrieveTemplate(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_CHARGES_RESOURCE_NAME);
return null;
final Collection<ChargeData> chargeOptions = this.chargeReadPlatformService.retrieveAllChargesApplicableToClients();
final ClientChargeData clientChargeData = ClientChargeData.template(chargeOptions);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, clientChargeData, ClientApiConstants.CLIENT_CHARGES_RESPONSE_DATA_PARAMETERS);
}
@@ -54,6 +54,28 @@ public class ClientChargeData {
amountPaid, amountWaived, amountWrittenOff, amountOutstanding, penalty, isActive, inactivationDate, chargeOptions);
}
public static ClientChargeData template(final Collection<ChargeData> chargeOptions) {
final Long id = null;
final Long clientId = null;
final Long chargeId = null;
final String name = null;
final EnumOptionData chargeTimeType = null;
final LocalDate dueDate = null;
final EnumOptionData chargeCalculationType = null;
final CurrencyData currency = null;
final BigDecimal amount = null;
final BigDecimal amountPaid = null;
final BigDecimal amountWaived = null;
final BigDecimal amountWrittenOff = null;
final BigDecimal amountOutstanding = null;
final Boolean penalty = false;
final Boolean isActive = null;
final LocalDate inactivationDate = null;
return new ClientChargeData(id, clientId, chargeId, name, chargeTimeType, dueDate, chargeCalculationType, currency, amount,
amountPaid, amountWaived, amountWrittenOff, amountOutstanding, penalty, isActive, inactivationDate, chargeOptions);
}
private ClientChargeData(Long id, Long clientId, Long chargeId, String name, EnumOptionData chargeTimeType, LocalDate dueDate,
EnumOptionData chargeCalculationType, CurrencyData currency, BigDecimal amount, BigDecimal amountPaid, BigDecimal amountWaived,
BigDecimal amountWrittenOff, BigDecimal amountOutstanding, boolean penalty, Boolean isActive, LocalDate inactivationDate,
@@ -42,8 +42,6 @@ public class ClientChargeDataValidator {
.resource(ClientApiConstants.CLIENT_CHARGES_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final Long chargeId = this.fromApiJsonHelper.extractLongNamed(ClientApiConstants.chargeIdParamName, element);
baseDataValidator.reset().parameter(ClientApiConstants.chargeIdParamName).value(chargeId).notNull().integerGreaterThanZero();
final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(ClientApiConstants.amountParamName, element);
baseDataValidator.reset().parameter(ClientApiConstants.amountParamName).value(amount).notNull().positiveAmount();
@@ -1,12 +1,7 @@
package org.mifosplatform.portfolio.client.domain;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -15,14 +10,10 @@ import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormatter;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.service.DateUtils;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.organisation.office.domain.OrganisationCurrency;
@@ -30,8 +21,6 @@ import org.mifosplatform.portfolio.charge.domain.Charge;
import org.mifosplatform.portfolio.charge.domain.ChargeCalculationType;
import org.mifosplatform.portfolio.charge.domain.ChargeTimeType;
import org.mifosplatform.portfolio.client.api.ClientApiConstants;
import org.mifosplatform.portfolio.savings.domain.SavingsAccountCharge;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@@ -87,7 +76,12 @@ public class ClientCharge extends AbstractPersistable<Long> {
@Column(name = "inactivated_on_date")
private Date inactivationDate;
@Transient
private OrganisationCurrency currency;
protected ClientCharge() {
//
}
public static ClientCharge createNew(final Client client, final Charge charge, final JsonCommand command) {
BigDecimal amount = command.bigDecimalValueOfParameterNamed(ClientApiConstants.amountParamName);
@@ -3,7 +3,9 @@ package org.mifosplatform.portfolio.client.domain;
import org.mifosplatform.organisation.office.domain.OrganisationCurrencyRepositoryWrapper;
import org.mifosplatform.portfolio.charge.exception.ChargeNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class ClientChargeRepositoryWrapper {
private final ClientChargeRepository repository;
@@ -118,7 +118,7 @@ public class ClientChargeReadPlatformServiceImpl implements ClientChargeReadPlat
final ClientChargeMapper rm = new ClientChargeMapper();
final String sql = "select " + rm.schema() + " where sc.client_id=? and sc.id=? ";
final String sql = "select " + rm.schema() + " where cc.client_id=? and cc.id=? ";
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { clientId, clientChargeId });
} catch (final EmptyResultDataAccessException e) {
@@ -24,6 +24,7 @@ import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
import org.mifosplatform.portfolio.charge.domain.Charge;
import org.mifosplatform.portfolio.charge.domain.ChargeRepositoryWrapper;
import org.mifosplatform.portfolio.charge.exception.ChargeCannotBeAppliedToException;
import org.mifosplatform.portfolio.client.api.ClientApiConstants;
import org.mifosplatform.portfolio.client.data.ClientChargeDataValidator;
import org.mifosplatform.portfolio.client.domain.Client;
@@ -82,6 +83,12 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
final Long chargeDefinitionId = command.longValueOfParameterNamed(ClientApiConstants.chargeIdParamName);
final Charge charge = this.chargeRepository.findOneWithNotFoundDetection(chargeDefinitionId);
// validate for client charge
if (!charge.isClientCharge()) {
final String errorMessage = "Charge with identifier " + charge.getId() + " cannot be applied to a Client";
throw new ChargeCannotBeAppliedToException("client", errorMessage, charge.getId());
}
final ClientCharge clientCharge = ClientCharge.createNew(client, charge, command);
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat());
@@ -98,7 +105,7 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
@Override
public CommandProcessingResult payCharge(Long clientId, Long clientChargeId, JsonCommand command) {
this.clientChargeDataValidator.validateAdd(command.json());
this.clientChargeDataValidator.validatePayCharge(command.json());
final Client client = this.clientRepository.getActiveClient(clientId);
@@ -18,7 +18,9 @@ import org.mifosplatform.portfolio.paymenttype.data.PaymentTypeData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@Service
public class ClientTransactionReadPlatformServiceImpl implements ClientTransactionReadPlatformService {
private final JdbcTemplate jdbcTemplate;
@@ -54,22 +54,14 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
private static final class LoanChargeMapper implements RowMapper<LoanChargeData> {
public String schema() {
return "lc.id as id, c.id as chargeId, c.name as name, "
+ "lc.amount as amountDue, "
+ "lc.amount_paid_derived as amountPaid, "
+ "lc.amount_waived_derived as amountWaived, "
+ "lc.amount_writtenoff_derived as amountWrittenOff, "
return "lc.id as id, c.id as chargeId, c.name as name, " + "lc.amount as amountDue, " + "lc.amount_paid_derived as amountPaid, "
+ "lc.amount_waived_derived as amountWaived, " + "lc.amount_writtenoff_derived as amountWrittenOff, "
+ "lc.amount_outstanding_derived as amountOutstanding, "
+ "lc.calculation_percentage as percentageOf, lc.calculation_on_amount as amountPercentageAppliedTo, "
+ "lc.charge_time_enum as chargeTime, "
+ "lc.is_penalty as penalty, "
+ "lc.due_for_collection_as_of_date as dueAsOfDate, "
+ "lc.charge_calculation_enum as chargeCalculation, "
+ "lc.charge_payment_mode_enum as chargePaymentMode, "
+ "lc.is_paid_derived as paid, "
+ "lc.waived as waied, "
+ "lc.min_cap as minCap, lc.max_cap as maxCap, "
+ "lc.charge_amount_or_percentage as amountOrPercentage, "
+ "lc.charge_time_enum as chargeTime, " + "lc.is_penalty as penalty, "
+ "lc.due_for_collection_as_of_date as dueAsOfDate, " + "lc.charge_calculation_enum as chargeCalculation, "
+ "lc.charge_payment_mode_enum as chargePaymentMode, " + "lc.is_paid_derived as paid, " + "lc.waived as waied, "
+ "lc.min_cap as minCap, lc.max_cap as maxCap, " + "lc.charge_amount_or_percentage as amountOrPercentage, "
+ "c.currency_code as currencyCode, oc.name as currencyName, "
+ "oc.decimal_places as currencyDecimalPlaces, oc.currency_multiplesof as inMultiplesOf, oc.display_symbol as currencyDisplaySymbol, "
+ "oc.internationalized_name_code as currencyNameCode from m_charge c "
@@ -119,8 +111,8 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
final BigDecimal amountOrPercentage = rs.getBigDecimal("amountOrPercentage");
return new LoanChargeData(id, chargeId, name, currency, amount, amountPaid, amountWaived, amountWrittenOff, amountOutstanding,
chargeTimeType, dueAsOfDate, chargeCalculationType, percentageOf, amountPercentageAppliedTo, penalty, paymentMode,
paid, waived, null, minCap, maxCap, amountOrPercentage, null);
chargeTimeType, dueAsOfDate, chargeCalculationType, percentageOf, amountPercentageAppliedTo, penalty, paymentMode, paid,
waived, null, minCap, maxCap, amountOrPercentage, null);
}
}
@@ -137,11 +129,14 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
.retrieveSavingsCalculationTypes();
final List<EnumOptionData> savingsChargeTimeTypeOptions = this.chargeDropdownReadPlatformService
.retrieveSavingsCollectionTimeTypes();
final List<EnumOptionData> clientChargeCalculationTypeOptions = null;
final List<EnumOptionData> clientChargeTimeTypeOptions = null;
final List<EnumOptionData> feeFrequencyOptions = this.dropdownReadPlatformService.retrievePeriodFrequencyTypeOptions();
return ChargeData.template(null, allowedChargeCalculationTypeOptions, null, allowedChargeTimeOptions, null,
loansChargeCalculationTypeOptions, loansChargeTimeTypeOptions, savingsChargeCalculationTypeOptions,
savingsChargeTimeTypeOptions, feeFrequencyOptions);
savingsChargeTimeTypeOptions, clientChargeCalculationTypeOptions, clientChargeTimeTypeOptions, feeFrequencyOptions);
}
@Override
@@ -170,8 +165,7 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
@Override
public Collection<LoanChargeData> retrieveLoanChargesForFeePayment(final Integer paymentMode, final Integer loanStatus) {
final LoanChargeMapperWithLoanId rm = new LoanChargeMapperWithLoanId();
final String sql = "select "
+ rm.schema()
final String sql = "select " + rm.schema()
+ "where loan.loan_status_id= ? and lc.charge_payment_mode_enum=? and lc.waived =0 and lc.is_paid_derived=0 and lc.is_active = 1";
return this.jdbcTemplate.query(sql, rm, new Object[] { loanStatus, paymentMode });
}
@@ -179,9 +173,9 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
private static final class LoanChargeMapperWithLoanId implements RowMapper<LoanChargeData> {
public String schema() {
return "lc.id as id, lc.due_for_collection_as_of_date as dueAsOfDate, "
+ "lc.amount_outstanding_derived as amountOutstanding, " + "lc.charge_time_enum as chargeTime, " + "loan.id as loanId "
+ "from m_loan_charge lc " + "join m_loan loan on loan.id = lc.loan_id ";
return "lc.id as id, lc.due_for_collection_as_of_date as dueAsOfDate, " + "lc.amount_outstanding_derived as amountOutstanding, "
+ "lc.charge_time_enum as chargeTime, " + "loan.id as loanId " + "from m_loan_charge lc "
+ "join m_loan loan on loan.id = lc.loan_id ";
}
@Override
@@ -265,8 +259,8 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
charges.removeAll(removeCharges);
for (LoanChargeData loanChargeData : removeCharges) {
if (loanChargeData.isInstallmentFee()) {
Collection<LoanInstallmentChargeData> installmentChargeDatas = retrieveInstallmentLoanChargesForAccrual(loanChargeData
.getId());
Collection<LoanInstallmentChargeData> installmentChargeDatas = retrieveInstallmentLoanChargesForAccrual(
loanChargeData.getId());
LoanChargeData modifiedChargeData = new LoanChargeData(loanChargeData, installmentChargeDatas);
charges.add(modifiedChargeData);
}
@@ -292,7 +286,8 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
sb.append("left join (");
sb.append("select lcp.loan_charge_id, lcp.amount");
sb.append(" from m_loan_charge_paid_by lcp ");
sb.append("inner join m_loan_transaction lt on lt.id = lcp.loan_transaction_id and lt.is_reversed = 0 and lt.transaction_type_enum = ?");
sb.append(
"inner join m_loan_transaction lt on lt.id = lcp.loan_transaction_id and lt.is_reversed = 0 and lt.transaction_type_enum = ?");
sb.append(") cp on cp.loan_charge_id= lc.id ");
schemaSql = sb.toString();
@@ -321,7 +316,8 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
}
}
private Collection<LoanChargeData> updateLoanChargesWithUnrecognizedIncome(final Long loanId, Collection<LoanChargeData> loanChargeDatas) {
private Collection<LoanChargeData> updateLoanChargesWithUnrecognizedIncome(final Long loanId,
Collection<LoanChargeData> loanChargeDatas) {
final LoanChargeUnRecognizedIncomeMapper rm = new LoanChargeUnRecognizedIncomeMapper(loanChargeDatas);
@@ -350,7 +346,8 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
sb.append("left join (");
sb.append("select cpb.loan_charge_id, lt.unrecognized_income_portion");
sb.append(" from m_loan_charge_paid_by cpb ");
sb.append("inner join m_loan_transaction lt on lt.id = cpb.loan_transaction_id and lt.is_reversed = 0 and lt.transaction_type_enum = ?");
sb.append(
"inner join m_loan_transaction lt on lt.id = cpb.loan_transaction_id and lt.is_reversed = 0 and lt.transaction_type_enum = ?");
sb.append(") wt on wt.loan_charge_id= lc.id ");
schemaSql = sb.toString();
@@ -406,7 +403,8 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
sb.append("left join (");
sb.append("select lcp.loan_charge_id, lcp.amount as amount, lcp.installment_number ");
sb.append(" from m_loan_charge_paid_by lcp ");
sb.append("inner join m_loan_transaction lt on lt.id = lcp.loan_transaction_id and lt.is_reversed = 0 and lt.transaction_type_enum = ?");
sb.append(
"inner join m_loan_transaction lt on lt.id = lcp.loan_transaction_id and lt.is_reversed = 0 and lt.transaction_type_enum = ?");
sb.append(") cp on cp.loan_charge_id= lic.loan_charge_id and cp.installment_number = lsi.installment ");
schemaSql = sb.toString();
}
@@ -449,7 +447,8 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
sb.append(" cpb.installment_number as installmentNumber, ");
sb.append(" sum(lt.unrecognized_income_portion) as amountUnrecognized ");
sb.append(" from m_loan_charge_paid_by cpb ");
sb.append("inner join m_loan_transaction lt on lt.id = cpb.loan_transaction_id and lt.is_reversed = 0 and lt.transaction_type_enum = ?");
sb.append(
"inner join m_loan_transaction lt on lt.id = cpb.loan_transaction_id and lt.is_reversed = 0 and lt.transaction_type_enum = ?");
schemaSql = sb.toString();
}
@@ -58,18 +58,12 @@ public class SavingsAccountChargeReadPlatformServiceImpl implements SavingsAccou
private static final class SavingsAccountChargeMapper implements RowMapper<SavingsAccountChargeData> {
public String schema() {
return "sc.id as id, c.id as chargeId, sc.savings_account_id as accountId, c.name as name, "
+ "sc.amount as amountDue, "
+ "sc.amount_paid_derived as amountPaid, "
+ "sc.amount_waived_derived as amountWaived, "
+ "sc.amount_writtenoff_derived as amountWrittenOff, "
+ "sc.amount_outstanding_derived as amountOutstanding, "
return "sc.id as id, c.id as chargeId, sc.savings_account_id as accountId, c.name as name, " + "sc.amount as amountDue, "
+ "sc.amount_paid_derived as amountPaid, " + "sc.amount_waived_derived as amountWaived, "
+ "sc.amount_writtenoff_derived as amountWrittenOff, " + "sc.amount_outstanding_derived as amountOutstanding, "
+ "sc.calculation_percentage as percentageOf, sc.calculation_on_amount as amountPercentageAppliedTo, "
+ "sc.charge_time_enum as chargeTime, "
+ "sc.is_penalty as penalty, "
+ "sc.charge_due_date as dueAsOfDate, "
+ "sc.fee_on_month as feeOnMonth, "
+ "sc.fee_on_day as feeOnDay, sc.fee_interval as feeInterval, "
+ "sc.charge_time_enum as chargeTime, " + "sc.is_penalty as penalty, " + "sc.charge_due_date as dueAsOfDate, "
+ "sc.fee_on_month as feeOnMonth, " + "sc.fee_on_day as feeOnDay, sc.fee_interval as feeInterval, "
+ "sc.charge_calculation_enum as chargeCalculation, "
+ "sc.is_active as isActive, sc.inactivated_on_date as inactivationDate, "
+ "c.currency_code as currencyCode, oc.name as currencyName, "
@@ -144,13 +138,15 @@ public class SavingsAccountChargeReadPlatformServiceImpl implements SavingsAccou
.retrieveSavingsCalculationTypes();
final List<EnumOptionData> savingsChargeTimeTypeOptions = this.chargeDropdownReadPlatformService
.retrieveSavingsCollectionTimeTypes();
final List<EnumOptionData> clientChargeCalculationTypeOptions = null;
final List<EnumOptionData> clientChargeTimeTypeOptions = null;
final List<EnumOptionData> feeFrequencyOptions = this.dropdownReadPlatformService.retrievePeriodFrequencyTypeOptions();
// TODO AA : revisit for merge conflict - Not sure method signature
return ChargeData.template(null, allowedChargeCalculationTypeOptions, null, allowedChargeTimeOptions, null,
loansChargeCalculationTypeOptions, loansChargeTimeTypeOptions, savingsChargeCalculationTypeOptions,
savingsChargeTimeTypeOptions, feeFrequencyOptions);
savingsChargeTimeTypeOptions, clientChargeCalculationTypeOptions, clientChargeTimeTypeOptions, feeFrequencyOptions);
}
@Override
@@ -227,8 +223,7 @@ public class SavingsAccountChargeReadPlatformServiceImpl implements SavingsAccou
@Override
public Collection<SavingsAccountAnnualFeeData> retrieveChargesWithDue() {
final String sql = "select "
+ this.chargeDueMapper.schema()
final String sql = "select " + this.chargeDueMapper.schema()
+ " where sac.charge_due_date is not null and sac.charge_due_date <= NOW() and sac.waived = 0 and sac.is_paid_derived=0 and sac.is_active=1 and sa.status_enum = "
+ SavingsAccountStatusType.ACTIVE.getValue() + " order by sac.charge_due_date ";
@@ -1,5 +1,6 @@
-- add permissions for Client Fees
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'READ_CLIENTCHARGE', 'CLIENTCHARGE', 'READ', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'CREATE_CLIENTCHARGE', 'CLIENTCHARGE', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'DELETE_CLIENTCHARGE', 'CLIENTCHARGE', 'DELETE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'WAIVE_CLIENTCHARGE', 'CLIENTCHARGE', 'WAIVE', 0);
@@ -7,3 +8,78 @@ INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `c
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'INACTIVATE_CLIENTCHARGE', 'CLIENTCHARGE', 'INACTIVATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'UPDATE_CLIENTCHARGE', 'CLIENTCHARGE', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'CREATE_CLIENTCHARGE_CHECKER', 'CLIENTCHARGE', 'CREATE_CHECKER', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'DELETE_CLIENTCHARGE_CHECKER', 'CLIENTCHARGE', 'DELETE_CHECKER', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'WAIVE_CLIENTCHARGE_CHECKER', 'CLIENTCHARGE', 'WAIVE_CHECKER', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'PAY_CLIENTCHARGE_CHECKER', 'CLIENTCHARGE', 'PAY_CHECKER', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'INACTIVATE_CLIENTCHARGE_CHECKER', 'CLIENTCHARGE', 'INACTIVATE_CHECKER', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'UPDATE_CLIENTCHARGE_CHECKER', 'CLIENTCHARGE', 'UPDATE_CHECKER', 0);
-- new tables
CREATE TABLE `m_client_transaction` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`client_id` BIGINT(20) NOT NULL,
`office_id` BIGINT(20) NOT NULL,
`currency_code` VARCHAR(3) NOT NULL,
`payment_detail_id` BIGINT(20) NULL DEFAULT NULL,
`is_reversed` TINYINT(1) NOT NULL,
`external_id` VARCHAR(50) NULL DEFAULT NULL,
`transaction_date` DATE NOT NULL,
`transaction_type_enum` SMALLINT(5) NOT NULL,
`amount` DECIMAL(19,6) NOT NULL,
`created_date` DATETIME NOT NULL,
`appuser_id` BIGINT(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `external_id` (`external_id`),
INDEX `FK_m_client_transaction_m_client` (`client_id`),
INDEX `FK_m_client_transaction_m_appuser` (`appuser_id`),
CONSTRAINT `FK_m_client_transaction_m_appuser` FOREIGN KEY (`appuser_id`) REFERENCES `m_appuser` (`id`),
CONSTRAINT `FK_m_client_transaction_m_client` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
CREATE TABLE `m_client_charge` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`client_id` BIGINT(20) NOT NULL,
`charge_id` BIGINT(20) NOT NULL,
`is_penalty` TINYINT(1) NOT NULL,
`charge_time_enum` SMALLINT(5) NOT NULL,
`charge_due_date` DATE NULL DEFAULT NULL,
`charge_calculation_enum` SMALLINT(5) NOT NULL,
`amount` DECIMAL(19,6) NOT NULL,
`amount_paid_derived` DECIMAL(19,6) NULL DEFAULT NULL,
`amount_waived_derived` DECIMAL(19,6) NULL DEFAULT NULL,
`amount_writtenoff_derived` DECIMAL(19,6) NULL DEFAULT NULL,
`amount_outstanding_derived` DECIMAL(19,6) NOT NULL,
`is_paid_derived` TINYINT(1) NULL DEFAULT NULL,
`waived` TINYINT(1) NULL DEFAULT NULL,
`is_active` TINYINT(1) NULL DEFAULT NULL,
`inactivated_on_date` DATE NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `FK_m_client_charge_m_client` (`client_id`),
INDEX `FK_m_client_charge_m_charge` (`charge_id`),
CONSTRAINT `FK_m_client_charge_m_charge` FOREIGN KEY (`charge_id`) REFERENCES `m_charge` (`id`),
CONSTRAINT `FK_m_client_charge_m_client` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
CREATE TABLE `m_client_charge_paid_by` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`client_transaction_id` BIGINT(20) NOT NULL,
`client_charge_id` BIGINT(20) NOT NULL,
`amount` DECIMAL(19,6) NOT NULL,
PRIMARY KEY (`id`),
INDEX `FK_m_client_charge_paid_by_m_client_transaction` (`client_transaction_id`),
INDEX `FK_m_client_charge_paid_by_m_client_charge` (`client_charge_id`),
CONSTRAINT `FK_m_client_charge_paid_by_m_client_charge` FOREIGN KEY (`client_charge_id`) REFERENCES `m_client_charge` (`id`),
CONSTRAINT `FK_m_client_charge_paid_by_m_client_transaction` FOREIGN KEY (`client_transaction_id`) REFERENCES `m_client_transaction` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;