public Set<SavingsAccountCharge> fromSavingsProduct(final SavingsProduct savingsProduct) { final Set<SavingsAccountCharge> savingsAccountCharges = new HashSet<SavingsAccountCharge>(); Set<Charge> productCharges = savingsProduct.charges(); for (Charge charge : productCharges) { ChargeTimeType chargeTime = null; if (charge.getChargeTime() != null) { chargeTime = ChargeTimeType.fromInt(charge.getChargeTime()); } if (chargeTime != null && chargeTime.isOnSpecifiedDueDate()) { continue; } ChargeCalculationType chargeCalculation = null; if (charge.getChargeCalculation() != null) { chargeCalculation = ChargeCalculationType.fromInt(charge.getChargeCalculation()); } final boolean status = true; final SavingsAccountCharge savingsAccountCharge = SavingsAccountCharge.createNewWithoutSavingsAccount( charge, charge.getAmount(), chargeTime, chargeCalculation, null, status, charge.getFeeOnMonthDay(), charge.feeInterval()); savingsAccountCharges.add(savingsAccountCharge); } return savingsAccountCharges; }
public void update( final BigDecimal amount, final LocalDate dueDate, final BigDecimal loanPrincipal, Integer numberOfRepayments, BigDecimal loanCharge) { if (dueDate != null) { this.dueDate = dueDate.toDate(); } if (amount != null) { switch (ChargeCalculationType.fromInt(this.chargeCalculation)) { case INVALID: break; case FLAT: if (isInstalmentFee()) { if (numberOfRepayments == null) { numberOfRepayments = this.loan.repaymentScheduleDetail().getNumberOfRepayments(); } this.amount = amount.multiply(BigDecimal.valueOf(numberOfRepayments)); } else { this.amount = amount; } break; case PERCENT_OF_AMOUNT: case PERCENT_OF_AMOUNT_AND_INTEREST: case PERCENT_OF_INTEREST: this.percentage = amount; this.amountPercentageAppliedTo = loanPrincipal; if (loanCharge.compareTo(BigDecimal.ZERO) == 0) { loanCharge = percentageOf(this.amountPercentageAppliedTo); } this.amount = minimumAndMaximumCap(loanCharge); break; } this.amountOrPercentage = amount; this.amountOutstanding = calculateOutstanding(); if (this.loan != null && isInstalmentFee()) { final Set<LoanInstallmentCharge> chargePerInstallments = this.loan.generateInstallmentLoanCharges(this); if (this.loanInstallmentCharge.isEmpty()) { this.loanInstallmentCharge.addAll(chargePerInstallments); } else { int index = 0; final LoanInstallmentCharge[] loanChargePerInstallments = new LoanInstallmentCharge[chargePerInstallments.size()]; final LoanInstallmentCharge[] loanChargePerInstallmentArray = chargePerInstallments.toArray(loanChargePerInstallments); for (final LoanInstallmentCharge chargePerInstallment : this.loanInstallmentCharge) { chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]); } } } } }
public void update( final BigDecimal amount, final LocalDate dueDate, final Integer numberOfRepayments) { BigDecimal amountPercentageAppliedTo = BigDecimal.ZERO; if (this.loan != null) { switch (ChargeCalculationType.fromInt(this.chargeCalculation)) { case PERCENT_OF_AMOUNT: amountPercentageAppliedTo = this.loan.getPrincpal().getAmount(); break; case PERCENT_OF_AMOUNT_AND_INTEREST: amountPercentageAppliedTo = this.loan.getPrincpal().getAmount().add(this.loan.getTotalInterest()); break; case PERCENT_OF_INTEREST: amountPercentageAppliedTo = this.loan.getTotalInterest(); break; default: break; } } update(amount, dueDate, amountPercentageAppliedTo, numberOfRepayments, BigDecimal.ZERO); }
public Set<SavingsAccountCharge> fromParsedJson( final JsonElement element, final String productCurrencyCode) { final Set<SavingsAccountCharge> savingsAccountCharges = new HashSet<SavingsAccountCharge>(); if (element.isJsonObject()) { final JsonObject topLevelJsonElement = element.getAsJsonObject(); final String dateFormat = this.fromApiJsonHelper.extractDateFormatParameter(topLevelJsonElement); final String monthDayFormat = this.fromApiJsonHelper.extractMonthDayFormatParameter(topLevelJsonElement); final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement); if (topLevelJsonElement.has(chargesParamName) && topLevelJsonElement.get(chargesParamName).isJsonArray()) { final JsonArray array = topLevelJsonElement.get(chargesParamName).getAsJsonArray(); for (int i = 0; i < array.size(); i++) { final JsonObject savingsChargeElement = array.get(i).getAsJsonObject(); final Long id = this.fromApiJsonHelper.extractLongNamed(idParamName, savingsChargeElement); final Long chargeId = this.fromApiJsonHelper.extractLongNamed(chargeIdParamName, savingsChargeElement); final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalNamed( amountParamName, savingsChargeElement, locale); final Integer chargeTimeType = this.fromApiJsonHelper.extractIntegerNamed( chargeTimeTypeParamName, savingsChargeElement, locale); final Integer chargeCalculationType = this.fromApiJsonHelper.extractIntegerNamed( chargeCalculationTypeParamName, savingsChargeElement, locale); final LocalDate dueDate = this.fromApiJsonHelper.extractLocalDateNamed( dueAsOfDateParamName, savingsChargeElement, dateFormat, locale); final MonthDay feeOnMonthDay = this.fromApiJsonHelper.extractMonthDayNamed( feeOnMonthDayParamName, savingsChargeElement, monthDayFormat, locale); final Integer feeInterval = this.fromApiJsonHelper.extractIntegerNamed( feeIntervalParamName, savingsChargeElement, locale); if (id == null) { final Charge chargeDefinition = this.chargeRepository.findOneWithNotFoundDetection(chargeId); if (!chargeDefinition.isSavingsCharge()) { final String errorMessage = "Charge with identifier " + chargeDefinition.getId() + " cannot be applied to Savings product."; throw new ChargeCannotBeAppliedToException( "savings.product", errorMessage, chargeDefinition.getId()); } ChargeTimeType chargeTime = null; if (chargeTimeType != null) { chargeTime = ChargeTimeType.fromInt(chargeTimeType); } ChargeCalculationType chargeCalculation = null; if (chargeCalculationType != null) { chargeCalculation = ChargeCalculationType.fromInt(chargeCalculationType); } final boolean status = true; final SavingsAccountCharge savingsAccountCharge = SavingsAccountCharge.createNewWithoutSavingsAccount( chargeDefinition, amount, chargeTime, chargeCalculation, dueDate, status, feeOnMonthDay, feeInterval); savingsAccountCharges.add(savingsAccountCharge); } else { final Long savingsAccountChargeId = id; final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOne(savingsAccountChargeId); if (savingsAccountCharge == null) { throw new SavingsAccountChargeNotFoundException(savingsAccountChargeId); } savingsAccountCharge.update(amount, dueDate, feeOnMonthDay, feeInterval); savingsAccountCharges.add(savingsAccountCharge); } } } } this.validateSavingsCharges(savingsAccountCharges, productCurrencyCode); return savingsAccountCharges; }
public ChargeCalculationType getChargeCalculation() { return ChargeCalculationType.fromInt(this.chargeCalculation); }
public Map<String, Object> update(final JsonCommand command, final BigDecimal amount) { final Map<String, Object> actualChanges = new LinkedHashMap<>(7); final String dateFormatAsInput = command.dateFormat(); final String localeAsInput = command.locale(); final String dueDateParamName = "dueDate"; if (command.isChangeInLocalDateParameterNamed(dueDateParamName, getDueLocalDate())) { final String valueAsInput = command.stringValueOfParameterNamed(dueDateParamName); actualChanges.put(dueDateParamName, valueAsInput); actualChanges.put("dateFormat", dateFormatAsInput); actualChanges.put("locale", localeAsInput); final LocalDate newValue = command.localDateValueOfParameterNamed(dueDateParamName); this.dueDate = newValue.toDate(); } final String amountParamName = "amount"; if (command.isChangeInBigDecimalParameterNamed(amountParamName, this.amount)) { final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountParamName); actualChanges.put(amountParamName, newValue); actualChanges.put("locale", localeAsInput); switch (ChargeCalculationType.fromInt(this.chargeCalculation)) { case INVALID: break; case FLAT: if (isInstalmentFee()) { this.amount = newValue.multiply( BigDecimal.valueOf( this.loan.repaymentScheduleDetail().getNumberOfRepayments())); } else { this.amount = newValue; } this.amountOutstanding = calculateOutstanding(); break; case PERCENT_OF_AMOUNT: case PERCENT_OF_AMOUNT_AND_INTEREST: case PERCENT_OF_INTEREST: this.percentage = newValue; this.amountPercentageAppliedTo = amount; BigDecimal loanCharge = BigDecimal.ZERO; if (isInstalmentFee()) { loanCharge = this.loan.calculatePerInstallmentChargeAmount( ChargeCalculationType.fromInt(this.chargeCalculation), this.percentage); } if (loanCharge.compareTo(BigDecimal.ZERO) == 0) { loanCharge = percentageOf(this.amountPercentageAppliedTo); } this.amount = minimumAndMaximumCap(loanCharge); this.amountOutstanding = calculateOutstanding(); break; } this.amountOrPercentage = newValue; if (isInstalmentFee()) { final Set<LoanInstallmentCharge> chargePerInstallments = this.loan.generateInstallmentLoanCharges(this); if (this.loanInstallmentCharge.isEmpty()) { this.loanInstallmentCharge.addAll(chargePerInstallments); } else { int index = 0; final LoanInstallmentCharge[] loanChargePerInstallments = new LoanInstallmentCharge[chargePerInstallments.size()]; final LoanInstallmentCharge[] loanChargePerInstallmentArray = chargePerInstallments.toArray(loanChargePerInstallments); for (final LoanInstallmentCharge chargePerInstallment : this.loanInstallmentCharge) { chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]); } } } } return actualChanges; }
private void populateDerivedFields( final BigDecimal amountPercentageAppliedTo, final BigDecimal chargeAmount, Integer numberOfRepayments, BigDecimal loanCharge) { switch (ChargeCalculationType.fromInt(this.chargeCalculation)) { case INVALID: this.percentage = null; this.amount = null; this.amountPercentageAppliedTo = null; this.amountPaid = null; this.amountOutstanding = BigDecimal.ZERO; this.amountWaived = null; this.amountWrittenOff = null; break; case FLAT: this.percentage = null; this.amountPercentageAppliedTo = null; this.amountPaid = null; if (isInstalmentFee()) { if (numberOfRepayments == null) { numberOfRepayments = this.loan.repaymentScheduleDetail().getNumberOfRepayments(); } this.amount = chargeAmount.multiply(BigDecimal.valueOf(numberOfRepayments)); } else { this.amount = chargeAmount; } this.amountOutstanding = this.amount; this.amountWaived = null; this.amountWrittenOff = null; break; case PERCENT_OF_AMOUNT: case PERCENT_OF_AMOUNT_AND_INTEREST: case PERCENT_OF_INTEREST: this.percentage = chargeAmount; this.amountPercentageAppliedTo = amountPercentageAppliedTo; if (loanCharge.compareTo(BigDecimal.ZERO) == 0) { loanCharge = percentageOf(this.amountPercentageAppliedTo); } this.amount = minimumAndMaximumCap(loanCharge); this.amountPaid = null; this.amountOutstanding = calculateOutstanding(); this.amountWaived = null; this.amountWrittenOff = null; break; } this.amountOrPercentage = chargeAmount; if (this.loan != null && isInstalmentFee()) { final Set<LoanInstallmentCharge> chargePerInstallments = this.loan.generateInstallmentLoanCharges(this); if (this.loanInstallmentCharge.isEmpty()) { this.loanInstallmentCharge.addAll(chargePerInstallments); } else { int index = 0; final LoanInstallmentCharge[] loanChargePerInstallments = new LoanInstallmentCharge[chargePerInstallments.size()]; final LoanInstallmentCharge[] loanChargePerInstallmentArray = chargePerInstallments.toArray(loanChargePerInstallments); for (final LoanInstallmentCharge chargePerInstallment : this.loanInstallmentCharge) { chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]); } } } }
public static LoanCharge createNewFromJson( final Loan loan, final Charge chargeDefinition, final JsonCommand command, final LocalDate dueDate) { final BigDecimal amount = command.bigDecimalValueOfParameterNamed("amount"); final ChargeTimeType chargeTime = null; final ChargeCalculationType chargeCalculation = null; final ChargePaymentMode chargePaymentMode = null; BigDecimal amountPercentageAppliedTo = BigDecimal.ZERO; switch (ChargeCalculationType.fromInt(chargeDefinition.getChargeCalculation())) { case PERCENT_OF_AMOUNT: if (command.hasParameter("principal")) { amountPercentageAppliedTo = command.bigDecimalValueOfParameterNamed("principal"); } else { amountPercentageAppliedTo = loan.getPrincpal().getAmount(); } break; case PERCENT_OF_AMOUNT_AND_INTEREST: if (command.hasParameter("principal") && command.hasParameter("interest")) { amountPercentageAppliedTo = command .bigDecimalValueOfParameterNamed("principal") .add(command.bigDecimalValueOfParameterNamed("interest")); } else { amountPercentageAppliedTo = loan.getPrincpal().getAmount().add(loan.getTotalInterest()); } break; case PERCENT_OF_INTEREST: if (command.hasParameter("interest")) { amountPercentageAppliedTo = command.bigDecimalValueOfParameterNamed("interest"); } else { amountPercentageAppliedTo = loan.getTotalInterest(); } break; default: break; } BigDecimal loanCharge = BigDecimal.ZERO; if (ChargeTimeType.fromInt(chargeDefinition.getChargeTime()) .equals(ChargeTimeType.INSTALMENT_FEE)) { BigDecimal percentage = amount; if (percentage == null) { percentage = chargeDefinition.getAmount(); } loanCharge = loan.calculatePerInstallmentChargeAmount( ChargeCalculationType.fromInt(chargeDefinition.getChargeCalculation()), percentage); } return new LoanCharge( loan, chargeDefinition, amountPercentageAppliedTo, amount, chargeTime, chargeCalculation, dueDate, chargePaymentMode, null, loanCharge); }