fix for Mifosx-437

This commit is contained in:
andrew-dzak
2013-10-17 16:44:04 +02:00
parent f898c5fcff
commit e1c2d36d10
9 changed files with 220 additions and 30 deletions
+46 -2
View File
@@ -11283,7 +11283,9 @@ Request Body:
"chargeCalculationType": "2",
"chargePaymentMode": "1",
"active": "true",
"penalty": "true"
"penalty": "true",
"minCap": 50.00,
"maxCap": 100.00
}
</code>
<code class="method-response">
@@ -11389,7 +11391,49 @@ GET https://DomainName/api/v1/charges
"code":"chargepaymentmode.accounttransfer",
"value":"Account transfer"
}
}
},
{
"id": 54,
"chargeId": 12,
"name": "Loan service fee 2",
"chargeTimeType": {
"id": 1,
"code": "chargeTimeType.disbursement",
"value": "Disbursement"
},
"chargeCalculationType": {
"id": 2,
"code": "chargeCalculationType.percent.of.amount",
"value": "% Amount"
},
"percentage": 2.000000,
"amountPercentageAppliedTo": 14000.000000,
"currency": {
"code": "KES",
"name": "Kenyan Shilling",
"decimalPlaces": 2,
"displaySymbol": "KSh",
"nameCode": "currency.KES",
"displayLabel": "Kenyan Shilling (KSh)"
},
"amount": 500.000000,
"amountPaid": 0,
"amountWaived": 0,
"amountWrittenOff": 0,
"amountOutstanding": 500.000000,
"amountOrPercentage": 2.000000,
"penalty": false,
"chargePaymentMode": {
"id": 1,
"code": "chargepaymentmode.accounttransfer",
"value": "Account transfer"
},
"paid": false,
"waived": false,
"chargePayable": true,
"minCap": 500.000000,
"maxCap": 1000.000000
},
]
</code>
</div>
@@ -0,0 +1,8 @@
ALTER TABLE `m_charge`
ADD COLUMN `min_cap` DECIMAL(19,6) NULL AFTER `is_deleted`,
ADD COLUMN `max_cap` DECIMAL(19,6) NULL AFTER `min_cap`;
ALTER TABLE `m_loan_charge`
ADD COLUMN `min_cap` DECIMAL(19,6) NULL AFTER `waived`,
ADD COLUMN `max_cap` DECIMAL(19,6) NULL AFTER `min_cap`;
@@ -34,6 +34,8 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
private final EnumOptionData chargePaymentMode;
private final MonthDay feeOnMonthDay;
private final Integer feeInterval;
private final BigDecimal minCap;
private final BigDecimal maxCap;
private final Collection<CurrencyData> currencyOptions;
private final List<EnumOptionData> chargeCalculationTypeOptions;//
@@ -54,20 +56,21 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
return new ChargeData(null, null, null, null, null, null, null, null, false, false, currencyOptions, chargeCalculationTypeOptions,
chargeAppliesToOptions, chargeTimeTypeOptions, chargePaymentModeOptions, loansChargeCalculationTypeOptions,
loansChargeTimeTypeOptions, savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, null, null);
loansChargeTimeTypeOptions, savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, null, null,null,null);
}
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, template.currencyOptions,
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);
template.savingsChargeCalculationTypeOptions, template.savingsChargeTimeTypeOptions, charge.feeOnMonthDay, charge.feeInterval,charge.minCap,charge.maxCap);
}
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 EnumOptionData chargePaymentMode, final MonthDay feeOnMonthDay, final Integer feeInterval, final boolean penalty, final boolean active,
final BigDecimal minCap, final BigDecimal maxCap) {
final Collection<CurrencyData> currencyOptions = null;
final List<EnumOptionData> chargeCalculationTypeOptions = null;
@@ -82,7 +85,7 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
return new ChargeData(id, name, amount, currency, chargeTimeType, chargeAppliesTo, chargeCalculationType, chargePaymentMode,
penalty, active, currencyOptions, chargeCalculationTypeOptions, chargeAppliesToOptions, chargeTimeTypeOptions,
chargePaymentModeOptions, loansChargeCalculationTypeOptions, loansChargeTimeTypeOptions,
savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, feeOnMonthDay, feeInterval);
savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, feeOnMonthDay, feeInterval,minCap,maxCap);
}
public static ChargeData lookup(final Long id, final String name, final boolean isPenalty) {
@@ -96,6 +99,8 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
final Integer feeInterval = null;
final Boolean penalty = isPenalty;
final Boolean active = false;
final BigDecimal minCap = null;
final BigDecimal maxCap = null;
final Collection<CurrencyData> currencyOptions = null;
final List<EnumOptionData> chargeCalculationTypeOptions = null;
final List<EnumOptionData> chargeAppliesToOptions = null;
@@ -109,7 +114,7 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
return new ChargeData(id, name, amount, currency, chargeTimeType, chargeAppliesTo, chargeCalculationType, chargePaymentMode,
penalty, active, currencyOptions, chargeCalculationTypeOptions, chargeAppliesToOptions, chargeTimeTypeOptions,
chargePaymentModeOptions, loansChargeCalculationTypeOptions, loansChargeTimeTypeOptions,
savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, feeOnMonthDay, feeInterval);
savingsChargeCalculationTypeOptions, savingsChargeTimeTypeOptions, feeOnMonthDay, feeInterval,minCap,maxCap);
}
private ChargeData(final Long id, final String name, final BigDecimal amount, final CurrencyData currency,
@@ -119,7 +124,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 MonthDay feeOnMonthDay, final Integer feeInterval,
final BigDecimal minCap,final BigDecimal maxCap) {
this.id = id;
this.name = name;
this.amount = amount;
@@ -132,6 +138,8 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
this.feeOnMonthDay = feeOnMonthDay;
this.penalty = penalty;
this.active = active;
this.minCap = minCap;
this.maxCap = maxCap;
this.currencyOptions = currencyOptions;
this.chargeCalculationTypeOptions = chargeCalculationTypeOptions;
this.chargeAppliesToOptions = chargeAppliesToOptions;
@@ -169,7 +177,7 @@ public class ChargeData implements Comparable<ChargeData>, Serializable {
}
return LoanChargeData.newLoanChargeDetails(this.id, this.name, this.currency, this.amount, percentage, this.chargeTimeType,
this.chargeCalculationType, this.penalty, this.chargePaymentMode);
this.chargeCalculationType, this.penalty, this.chargePaymentMode,this.minCap,this.maxCap);
}
public SavingsAccountChargeData toSavingsAccountChargeData() {
@@ -75,6 +75,13 @@ public class Charge extends AbstractPersistable<Long> {
@Column(name = "is_deleted", nullable = false)
private boolean deleted = false;
@Column(name = "min_cap", scale = 6, precision = 19, nullable = true)
private BigDecimal minCap;
@Column(name = "max_cap", scale = 6, precision = 19, nullable = true)
private BigDecimal maxCap;
public static Charge fromJson(final JsonCommand command) {
final String name = command.stringValueOfParameterNamed("name");
@@ -93,9 +100,11 @@ public class Charge extends AbstractPersistable<Long> {
final boolean active = command.booleanPrimitiveValueOfParameterNamed("active");
final MonthDay feeOnMonthDay = command.extractMonthDayNamed("feeOnMonthDay");
final Integer feeInterval = command.integerValueOfParameterNamed("feeInterval");
final BigDecimal minCap = command.bigDecimalValueOfParameterNamed("minCap");
final BigDecimal maxCap = command.bigDecimalValueOfParameterNamed("maxCap");
return new Charge(name, amount, currencyCode, chargeAppliesTo, chargeTimeType, chargeCalculationType, penalty, active, paymentMode,
feeOnMonthDay, feeInterval);
feeOnMonthDay, feeInterval,minCap,maxCap);
}
protected Charge() {
@@ -104,7 +113,8 @@ 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 boolean active, final ChargePaymentMode paymentMode, final MonthDay feeOnMonthDay, final Integer feeInterval,
final BigDecimal minCap, final BigDecimal maxCap) {
this.name = name;
this.amount = amount;
this.currencyCode = currencyCode;
@@ -114,6 +124,8 @@ public class Charge extends AbstractPersistable<Long> {
this.penalty = penalty;
this.active = active;
this.chargePaymentMode = (paymentMode == null) ? null : paymentMode.getValue();
this.minCap = minCap;
this.maxCap = maxCap;
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("charges");
@@ -224,6 +236,19 @@ public class Charge extends AbstractPersistable<Long> {
return ChargeCalculationType.fromInt(this.chargeCalculation).isAllowedSavingsChargeCalculationType();
}
public boolean isPercentageOfAmount(){
return ChargeCalculationType.fromInt(this.chargeCalculation).isPercentageOfAmount();
}
public BigDecimal getMinCap() {
return this.minCap;
}
public BigDecimal getMaxCap() {
return this.maxCap;
}
public Map<String, Object> update(final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(7);
@@ -367,6 +392,25 @@ public class Charge extends AbstractPersistable<Long> {
actualChanges.put(activeParamName, newValue);
this.active = newValue;
}
//allow min and max cap to be only added to PERCENT_OF_AMOUNT for now
if(isPercentageOfAmount()){
final String minCapParamName = "minCap";
if (command.isChangeInBigDecimalParameterNamed(minCapParamName, this.minCap)) {
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minCapParamName);
actualChanges.put(minCapParamName, newValue);
actualChanges.put("locale", localeAsInput);
this.minCap = newValue;
}
final String maxCapParamName = "maxCap";
if (command.isChangeInBigDecimalParameterNamed(maxCapParamName, this.maxCap)) {
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maxCapParamName);
actualChanges.put(maxCapParamName, newValue);
actualChanges.put("locale", localeAsInput);
this.maxCap = newValue;
}
}
if (this.penalty && ChargeTimeType.fromInt(this.chargeTime).isTimeOfDisbursement()) { throw new ChargeDueAtDisbursementCannotBePenaltyException(
this.name); }
@@ -395,7 +439,7 @@ public class Charge extends AbstractPersistable<Long> {
final EnumOptionData chargePaymentmode = ChargeEnumerations.chargePaymentMode(this.chargePaymentMode);
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, this.getFeeOnMonthDay(), this.feeInterval, this.penalty, this.active);
chargePaymentmode, this.getFeeOnMonthDay(), this.feeInterval, this.penalty, this.active,this.minCap,this.maxCap);
}
public Integer getChargePaymentMode() {
@@ -38,7 +38,7 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
*/
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("name", "amount", "locale", "currencyCode",
"currencyOptions", "chargeAppliesTo", "chargeTimeType", "chargeCalculationType", "chargeCalculationTypeOptions", "penalty",
"active", "chargePaymentMode", "feeOnMonthDay", "feeInterval", "monthDayFormat"));
"active", "chargePaymentMode", "feeOnMonthDay", "feeInterval", "monthDayFormat","minCap","maxCap"));
private final FromJsonHelper fromApiJsonHelper;
@@ -84,7 +84,7 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
final Integer chargePaymentMode = this.fromApiJsonHelper.extractIntegerNamed("chargePaymentMode", element, Locale.getDefault());
baseDataValidator.reset().parameter("chargePaymentMode").value(chargePaymentMode).notNull().inMinMaxRange(0, 1);
}
if (this.fromApiJsonHelper.parameterExists("penalty", element)) {
final Boolean penalty = this.fromApiJsonHelper.extractBooleanNamed("penalty", element);
baseDataValidator.reset().parameter("penalty").value(penalty).notNull();
@@ -109,6 +109,15 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
baseDataValidator.reset().parameter("feeOnMonthDay").value(monthDay).notNull();
}
if(this.fromApiJsonHelper.parameterExists("minCap",element)){
final BigDecimal minCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minCap", element.getAsJsonObject());
baseDataValidator.reset().parameter("minCap").value(minCap).notNull().positiveAmount();
}
if(this.fromApiJsonHelper.parameterExists("maxCap",element)){
final BigDecimal maxCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maxCap", element.getAsJsonObject());
baseDataValidator.reset().parameter("maxCap").value(maxCap).notNull().positiveAmount();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
@@ -137,6 +146,16 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
baseDataValidator.reset().parameter("amount").value(amount).notNull().positiveAmount();
}
if(this.fromApiJsonHelper.parameterExists("minCap",element)){
final BigDecimal minCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minCap", element.getAsJsonObject());
baseDataValidator.reset().parameter("minCap").value(minCap).notNull().positiveAmount();
}
if(this.fromApiJsonHelper.parameterExists("maxCap",element)){
final BigDecimal maxCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maxCap", element.getAsJsonObject());
baseDataValidator.reset().parameter("maxCap").value(maxCap).notNull().positiveAmount();
}
if (this.fromApiJsonHelper.parameterExists("chargeAppliesTo", element)) {
final Integer chargeAppliesTo = this.fromApiJsonHelper.extractIntegerNamed("chargeAppliesTo", element, Locale.getDefault());
baseDataValidator.reset().parameter("chargeAppliesTo").value(chargeAppliesTo).notNull()
@@ -179,6 +198,14 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
final Boolean active = this.fromApiJsonHelper.extractBooleanNamed("active", element);
baseDataValidator.reset().parameter("active").value(active).notNull();
}
if(this.fromApiJsonHelper.parameterExists("minCap",element)){
final BigDecimal minCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minCap", element.getAsJsonObject());
baseDataValidator.reset().parameter("minCap").value(minCap).notNull().positiveAmount();
}
if(this.fromApiJsonHelper.parameterExists("maxCap",element)){
final BigDecimal maxCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maxCap", element.getAsJsonObject());
baseDataValidator.reset().parameter("maxCap").value(maxCap).notNull().positiveAmount();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
@@ -145,7 +145,8 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
+ "c.is_active as active, 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, c.fee_on_day as feeOnDay, c.fee_on_month as feeOnMonth, "
+ "c.fee_interval as feeInterval from m_charge c "
+ "c.fee_interval as feeInterval,c.min_cap as minCap,c.max_cap as maxCap "
+ "from m_charge c "
+ "join m_organisation_currency oc on c.currency_code = oc.code";
}
@@ -195,9 +196,11 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
if (feeOnDay != null) {
feeOnMonthDay = new MonthDay(feeOnMonth, feeOnDay);
}
final BigDecimal minCap = rs.getBigDecimal("minCap");
final BigDecimal maxCap = rs.getBigDecimal("maxCap");
return ChargeData.instance(id, name, amount, currency, chargeTimeType, chargeAppliesToType, chargeCalculationType,
chargePaymentMode, feeOnMonthDay, feeInterval, penalty, active);
chargePaymentMode, feeOnMonthDay, feeInterval, penalty, active,minCap,maxCap);
}
}
@@ -72,8 +72,12 @@ public class LoanChargeData {
private final Long loanId;
private final BigDecimal minCap;
private final BigDecimal maxCap;
public static LoanChargeData template(final Collection<ChargeData> chargeOptions) {
return new LoanChargeData(null, null, null, null, null, null, null, null, chargeOptions, false, null, false, false, null);
return new LoanChargeData(null, null, null, null, null, null, null, null, chargeOptions, false, null, false, false, null,null,null);
}
/**
@@ -82,16 +86,17 @@ public class LoanChargeData {
*/
public static LoanChargeData newLoanChargeDetails(final Long chargeId, final String name, final CurrencyData currency,
final BigDecimal amount, final BigDecimal percentage, final EnumOptionData chargeTimeType,
final EnumOptionData chargeCalculationType, final boolean penalty, final EnumOptionData chargePaymentMode) {
final EnumOptionData chargeCalculationType, final boolean penalty, final EnumOptionData chargePaymentMode,final BigDecimal minCap,final BigDecimal maxCap) {
return new LoanChargeData(null, chargeId, name, currency, amount, percentage, chargeTimeType, chargeCalculationType, null, penalty,
chargePaymentMode, false, false, null);
chargePaymentMode, false, false, null,minCap,maxCap);
}
public LoanChargeData(final Long id, final Long chargeId, final String name, final CurrencyData currency, final BigDecimal amount,
final BigDecimal amountPaid, final BigDecimal amountWaived, final BigDecimal amountWrittenOff,
final BigDecimal amountOutstanding, final EnumOptionData chargeTimeType, final LocalDate dueDate,
final EnumOptionData chargeCalculationType, final BigDecimal percentage, final BigDecimal amountPercentageAppliedTo,
final boolean penalty, final EnumOptionData chargePaymentMode, final boolean paid, final boolean waived, final Long loanId) {
final boolean penalty, final EnumOptionData chargePaymentMode, final boolean paid, final boolean waived, final Long loanId,
final BigDecimal minCap, final BigDecimal maxCap) {
this.id = id;
this.chargeId = chargeId;
this.name = name;
@@ -110,6 +115,8 @@ public class LoanChargeData {
this.chargePaymentMode = chargePaymentMode;
this.paid = paid;
this.waived = waived;
this.minCap = minCap;
this.maxCap = maxCap;
if (chargeCalculationType != null && chargeCalculationType.getId().intValue() > 1) {
this.amountOrPercentage = this.percentage;
@@ -123,9 +130,9 @@ public class LoanChargeData {
}
private LoanChargeData(final Long id, final Long chargeId, final String name, final CurrencyData currency, final BigDecimal amount,
final BigDecimal pecentage, final EnumOptionData chargeTimeType, final EnumOptionData chargeCalculationType,
final BigDecimal percentage, final EnumOptionData chargeTimeType, final EnumOptionData chargeCalculationType,
final Collection<ChargeData> chargeOptions, final boolean penalty, final EnumOptionData chargePaymentMode, final boolean paid,
final boolean waived, final Long loanId) {
final boolean waived, final Long loanId,final BigDecimal minCap, final BigDecimal maxCap) {
this.id = id;
this.chargeId = chargeId;
this.name = name;
@@ -138,13 +145,15 @@ public class LoanChargeData {
this.chargeTimeType = chargeTimeType;
this.dueDate = null;
this.chargeCalculationType = chargeCalculationType;
this.percentage = pecentage;
this.percentage = percentage;
this.amountPercentageAppliedTo = null;
this.penalty = penalty;
this.chargePaymentMode = chargePaymentMode;
this.paid = paid;
this.waived = waived;
if (chargeCalculationType != null && chargeCalculationType.getId().intValue() > 1) {
this.amountOrPercentage = this.percentage;
} else {
@@ -154,6 +163,8 @@ public class LoanChargeData {
this.chargeOptions = chargeOptions;
this.chargePayable = isChargePayable();
this.loanId = loanId;
this.minCap = minCap;
this.maxCap = maxCap;
}
public LoanChargeData(final Long id, final LocalDate dueAsOfDate, final BigDecimal amountOutstanding, final Long loanId) {
@@ -179,6 +190,8 @@ public class LoanChargeData {
this.chargeOptions = null;
this.chargePayable = false;
this.loanId = loanId;
this.minCap = null;
this.maxCap = null;
}
public boolean isChargePayable() {
@@ -89,6 +89,12 @@ public class LoanCharge extends AbstractPersistable<Long> {
@Column(name = "waived", nullable = false)
private boolean waived = false;
@Column(name = "min_cap", scale = 6, precision = 19, nullable = true)
private BigDecimal minCap;
@Column(name = "max_cap", scale = 6, precision = 19, nullable = true)
private BigDecimal maxCap;
public static LoanCharge createNewFromJson(final Loan loan, final Charge chargeDefinition, final JsonCommand command) {
final BigDecimal amount = command.bigDecimalValueOfParameterNamed("amount");
@@ -121,6 +127,8 @@ public class LoanCharge extends AbstractPersistable<Long> {
this.loan = loan;
this.charge = chargeDefinition;
this.penaltyCharge = chargeDefinition.isPenalty();
this.minCap = chargeDefinition.getMinCap();
this.maxCap = chargeDefinition.getMaxCap();
this.chargeTime = chargeDefinition.getChargeTime();
if (chargeTime != null) {
@@ -155,7 +163,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
this.chargePaymentMode = chargePaymentMode.getValue();
}
populateDerivedFields(loanPrincipal, chargeAmount);
populateDerivedFields(loanPrincipal,chargeAmount);
this.paid = determineIfFullyPaid();
}
@@ -183,7 +191,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
case PERCENT_OF_AMOUNT:
this.percentage = chargeAmount;
this.amountPercentageAppliedTo = loanPrincipal;
this.amount = percentageOf(this.amountPercentageAppliedTo, this.percentage);
this.amount = minimumAndMaximumCap(percentageOf(this.amountPercentageAppliedTo, this.percentage));
this.amountPaid = null;
this.amountOutstanding = calculateOutstanding();
this.amountWaived = null;
@@ -262,7 +270,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
case PERCENT_OF_AMOUNT:
this.percentage = amount;
this.amountPercentageAppliedTo = loanPrincipal;
this.amount = percentageOf(this.amountPercentageAppliedTo, this.percentage);
this.amount = minimumAndMaximumCap(percentageOf(this.amountPercentageAppliedTo, this.percentage));
this.amountOutstanding = calculateOutstanding();
break;
case PERCENT_OF_AMOUNT_AND_INTEREST:
@@ -313,7 +321,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
case PERCENT_OF_AMOUNT:
this.percentage = newValue;
this.amountPercentageAppliedTo = loanPrincipal;
this.amount = percentageOf(this.amountPercentageAppliedTo, this.percentage);
this.amount = minimumAndMaximumCap(percentageOf(this.amountPercentageAppliedTo, this.percentage));
this.amountOutstanding = calculateOutstanding();
break;
case PERCENT_OF_AMOUNT_AND_INTEREST:
@@ -393,10 +401,34 @@ public class LoanCharge extends AbstractPersistable<Long> {
final BigDecimal multiplicand = percentage.divide(BigDecimal.valueOf(100l), mc);
percentageOf = value.multiply(multiplicand, mc);
}
return percentageOf;
}
/**
* @param percentageOf
* @returns a minimum cap or maximum cap set on charges if the criteria fits
* else it returns the percentageOf if the amount is within min and max cap
*/
private BigDecimal minimumAndMaximumCap(BigDecimal percentageOf){
BigDecimal minMaxCap = BigDecimal.ZERO;
if(this.minCap !=null){
int minimumCap = percentageOf.compareTo(minCap);
if(minimumCap == -1){
minMaxCap = this.minCap;
return minMaxCap;
}
}
if(this.maxCap !=null){
int maximumCap = percentageOf.compareTo(maxCap);
if(maximumCap == 1) {
minMaxCap = this.maxCap;
return minMaxCap;
}
}
minMaxCap = percentageOf;
return minMaxCap;
}
public BigDecimal amount() {
return this.amount;
}
@@ -443,6 +475,14 @@ public class LoanCharge extends AbstractPersistable<Long> {
return this.waived;
}
public BigDecimal getMinCap() {
return this.minCap;
}
public BigDecimal getMaxCap() {
return this.maxCap;
}
public boolean isPaidOrPartiallyPaid(final MonetaryCurrency currency) {
final Money amountWaivedOrWrittenOff = getAmountWaived(currency).plus(getAmountWrittenOff(currency));
@@ -58,6 +58,7 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
+ "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, "
+ "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 "
@@ -102,10 +103,12 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
final EnumOptionData paymentMode = ChargeEnumerations.chargePaymentMode(chargePaymentMode);
final boolean paid = rs.getBoolean("paid");
final boolean waived = rs.getBoolean("waied");
final BigDecimal minCap = rs.getBigDecimal("minCap");
final BigDecimal maxCap = rs.getBigDecimal("maxCap");
return new LoanChargeData(id, chargeId, name, currency, amount, amountPaid, amountWaived, amountWrittenOff, amountOutstanding,
chargeTimeType, dueAsOfDate, chargeCalculationType, percentageOf, amountPercentageAppliedTo, penalty, paymentMode,
paid, waived, null);
paid, waived, null,minCap,maxCap);
}
}