fixed mifosx-304 deleting loan product charges not working

This commit is contained in:
John Woodlock
2013-04-26 17:29:40 +01:00
parent 44cef96643
commit a3a40f5a45
@@ -45,254 +45,335 @@ import com.google.gson.JsonArray;
@Table(name = "m_product_loan", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "unq_name") }) @Table(name = "m_product_loan", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "unq_name") })
public class LoanProduct extends AbstractPersistable<Long> { public class LoanProduct extends AbstractPersistable<Long> {
@ManyToOne @ManyToOne
@JoinColumn(name = "fund_id", nullable = true) @JoinColumn(name = "fund_id", nullable = true)
private Fund fund; private Fund fund;
@ManyToOne @ManyToOne
@JoinColumn(name = "loan_transaction_strategy_id", nullable = true) @JoinColumn(name = "loan_transaction_strategy_id", nullable = true)
private LoanTransactionProcessingStrategy transactionProcessingStrategy; private LoanTransactionProcessingStrategy transactionProcessingStrategy;
@Column(name = "name", nullable = false, unique = true) @Column(name = "name", nullable = false, unique = true)
private String name; private String name;
@Column(name = "description") @Column(name = "description")
private String description; private String description;
@ManyToMany @ManyToMany
@JoinTable(name = "m_product_loan_charge", joinColumns = @JoinColumn(name = "product_loan_id"), inverseJoinColumns = @JoinColumn(name = "charge_id")) @JoinTable(name = "m_product_loan_charge", joinColumns = @JoinColumn(name = "product_loan_id"), inverseJoinColumns = @JoinColumn(name = "charge_id"))
private List<Charge> charges; private List<Charge> charges;
@Embedded @Embedded
private final LoanProductRelatedDetail loanProductRelatedDetail; private final LoanProductRelatedDetail loanProductRelatedDetail;
@Embedded @Embedded
private LoanProductMinMaxConstraints loanProductMinMaxConstraints; private LoanProductMinMaxConstraints loanProductMinMaxConstraints;
@Column(name = "accounting_type", nullable = false) @Column(name = "accounting_type", nullable = false)
private Integer accountingRule; private Integer accountingRule;
public static LoanProduct assembleFromJson(final Fund fund, final LoanTransactionProcessingStrategy loanTransactionProcessingStrategy, public static LoanProduct assembleFromJson(
final List<Charge> productCharges, final JsonCommand command, final AprCalculator aprCalculator) { final Fund fund,
final LoanTransactionProcessingStrategy loanTransactionProcessingStrategy,
final List<Charge> productCharges, final JsonCommand command,
final AprCalculator aprCalculator) {
final String name = command.stringValueOfParameterNamed("name"); final String name = command.stringValueOfParameterNamed("name");
final String description = command.stringValueOfParameterNamed("description"); final String description = command
final String currencyCode = command.stringValueOfParameterNamed("currencyCode"); .stringValueOfParameterNamed("description");
final Integer digitsAfterDecimal = command.integerValueOfParameterNamed("digitsAfterDecimal"); final String currencyCode = command
.stringValueOfParameterNamed("currencyCode");
final Integer digitsAfterDecimal = command
.integerValueOfParameterNamed("digitsAfterDecimal");
final MonetaryCurrency currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal); final MonetaryCurrency currency = new MonetaryCurrency(currencyCode,
final BigDecimal principal = command.bigDecimalValueOfParameterNamed("principal"); digitsAfterDecimal);
final BigDecimal minPrincipal = command.bigDecimalValueOfParameterNamed("minPrincipal"); final BigDecimal principal = command
final BigDecimal maxPrincipal = command.bigDecimalValueOfParameterNamed("maxPrincipal"); .bigDecimalValueOfParameterNamed("principal");
final BigDecimal minPrincipal = command
.bigDecimalValueOfParameterNamed("minPrincipal");
final BigDecimal maxPrincipal = command
.bigDecimalValueOfParameterNamed("maxPrincipal");
final InterestMethod interestMethod = InterestMethod.fromInt(command.integerValueOfParameterNamed("interestType")); final InterestMethod interestMethod = InterestMethod.fromInt(command
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command .integerValueOfParameterNamed("interestType"));
.integerValueOfParameterNamed("interestCalculationPeriodType")); final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.integerValueOfParameterNamed("amortizationType")); .fromInt(command
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command .integerValueOfParameterNamed("interestCalculationPeriodType"));
.integerValueOfParameterNamed("repaymentFrequencyType")); final AmortizationMethod amortizationMethod = AmortizationMethod
final PeriodFrequencyType interestFrequencyType = PeriodFrequencyType.fromInt(command .fromInt(command
.integerValueOfParameterNamed("interestRateFrequencyType")); .integerValueOfParameterNamed("amortizationType"));
final BigDecimal interestRatePerPeriod = command.bigDecimalValueOfParameterNamed("interestRatePerPeriod"); final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType
final BigDecimal minInterestRatePerPeriod = command.bigDecimalValueOfParameterNamed("minInterestRatePerPeriod"); .fromInt(command
final BigDecimal maxInterestRatePerPeriod = command.bigDecimalValueOfParameterNamed("maxInterestRatePerPeriod"); .integerValueOfParameterNamed("repaymentFrequencyType"));
final BigDecimal annualInterestRate = aprCalculator.calculateFrom(interestFrequencyType, interestRatePerPeriod); final PeriodFrequencyType interestFrequencyType = PeriodFrequencyType
.fromInt(command
.integerValueOfParameterNamed("interestRateFrequencyType"));
final BigDecimal interestRatePerPeriod = command
.bigDecimalValueOfParameterNamed("interestRatePerPeriod");
final BigDecimal minInterestRatePerPeriod = command
.bigDecimalValueOfParameterNamed("minInterestRatePerPeriod");
final BigDecimal maxInterestRatePerPeriod = command
.bigDecimalValueOfParameterNamed("maxInterestRatePerPeriod");
final BigDecimal annualInterestRate = aprCalculator.calculateFrom(
interestFrequencyType, interestRatePerPeriod);
final Integer repaymentEvery = command.integerValueOfParameterNamed("repaymentEvery"); final Integer repaymentEvery = command
final Integer numberOfRepayments = command.integerValueOfParameterNamed("numberOfRepayments"); .integerValueOfParameterNamed("repaymentEvery");
final Integer minNumberOfRepayments = command.integerValueOfParameterNamed("minNumberOfRepayments"); final Integer numberOfRepayments = command
final Integer maxNumberOfRepayments = command.integerValueOfParameterNamed("maxNumberOfRepayments"); .integerValueOfParameterNamed("numberOfRepayments");
final BigDecimal inArrearsTolerance = command.bigDecimalValueOfParameterNamed("inArrearsTolerance"); final Integer minNumberOfRepayments = command
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(command.integerValueOfParameterNamed("accountingRule")); .integerValueOfParameterNamed("minNumberOfRepayments");
final Integer maxNumberOfRepayments = command
.integerValueOfParameterNamed("maxNumberOfRepayments");
final BigDecimal inArrearsTolerance = command
.bigDecimalValueOfParameterNamed("inArrearsTolerance");
final AccountingRuleType accountingRuleType = AccountingRuleType
.fromInt(command.integerValueOfParameterNamed("accountingRule"));
return new LoanProduct(fund, loanTransactionProcessingStrategy, name, description, currency, principal, minPrincipal, maxPrincipal, return new LoanProduct(fund, loanTransactionProcessingStrategy, name,
interestRatePerPeriod, minInterestRatePerPeriod, maxInterestRatePerPeriod, interestFrequencyType, annualInterestRate, interestMethod, interestCalculationPeriodMethod, description, currency, principal, minPrincipal, maxPrincipal,
repaymentEvery, repaymentFrequencyType, numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, amortizationMethod, inArrearsTolerance, productCharges, interestRatePerPeriod, minInterestRatePerPeriod,
accountingRuleType); maxInterestRatePerPeriod, interestFrequencyType,
} annualInterestRate, interestMethod,
interestCalculationPeriodMethod, repaymentEvery,
repaymentFrequencyType, numberOfRepayments,
minNumberOfRepayments, maxNumberOfRepayments,
amortizationMethod, inArrearsTolerance, productCharges,
accountingRuleType);
}
protected LoanProduct() { protected LoanProduct() {
this.loanProductRelatedDetail = null; this.loanProductRelatedDetail = null;
this.loanProductMinMaxConstraints = null; this.loanProductMinMaxConstraints = null;
} }
public LoanProduct(final Fund fund, final LoanTransactionProcessingStrategy transactionProcessingStrategy, final String name, public LoanProduct(
final String description, final MonetaryCurrency currency, final BigDecimal defaultPrincipal, final Fund fund,
final BigDecimal defaultMinPrincipal, final BigDecimal defaultMaxPrincipal, final LoanTransactionProcessingStrategy transactionProcessingStrategy,
final BigDecimal defaultNominalInterestRatePerPeriod, final BigDecimal defaultMinNominalInterestRatePerPeriod, final String name,
final BigDecimal defaultMaxNominalInterestRatePerPeriod, final PeriodFrequencyType interestPeriodFrequencyType, final String description,
final BigDecimal defaultAnnualNominalInterestRate, final InterestMethod interestMethod, final MonetaryCurrency currency,
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery, final BigDecimal defaultPrincipal,
final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfInstallments, final BigDecimal defaultMinPrincipal,
final Integer defaultMinNumberOfInstallments, final Integer defaultMaxNumberOfInstallments, final BigDecimal defaultMaxPrincipal,
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance, final List<Charge> charges, final BigDecimal defaultNominalInterestRatePerPeriod,
final AccountingRuleType accountingRuleType) { final BigDecimal defaultMinNominalInterestRatePerPeriod,
this.fund = fund; final BigDecimal defaultMaxNominalInterestRatePerPeriod,
this.transactionProcessingStrategy = transactionProcessingStrategy; final PeriodFrequencyType interestPeriodFrequencyType,
this.name = name.trim(); final BigDecimal defaultAnnualNominalInterestRate,
if (StringUtils.isNotBlank(description)) { final InterestMethod interestMethod,
this.description = description.trim(); final InterestCalculationPeriodMethod interestCalculationPeriodMethod,
} else { final Integer repayEvery,
this.description = null; final PeriodFrequencyType repaymentFrequencyType,
} final Integer defaultNumberOfInstallments,
final Integer defaultMinNumberOfInstallments,
final Integer defaultMaxNumberOfInstallments,
final AmortizationMethod amortizationMethod,
final BigDecimal inArrearsTolerance, final List<Charge> charges,
final AccountingRuleType accountingRuleType) {
this.fund = fund;
this.transactionProcessingStrategy = transactionProcessingStrategy;
this.name = name.trim();
if (StringUtils.isNotBlank(description)) {
this.description = description.trim();
} else {
this.description = null;
}
if (charges != null) { if (charges != null) {
this.charges = charges; this.charges = charges;
} }
this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency,
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, defaultPrincipal, defaultNominalInterestRatePerPeriod,
repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod, inArrearsTolerance); interestPeriodFrequencyType, defaultAnnualNominalInterestRate,
interestMethod, interestCalculationPeriodMethod, repayEvery,
repaymentFrequencyType, defaultNumberOfInstallments,
amortizationMethod, inArrearsTolerance);
this.loanProductMinMaxConstraints = new LoanProductMinMaxConstraints(defaultMinPrincipal, defaultMaxPrincipal, this.loanProductMinMaxConstraints = new LoanProductMinMaxConstraints(
defaultMinNominalInterestRatePerPeriod, defaultMaxNominalInterestRatePerPeriod, defaultMinNumberOfInstallments, defaultMinPrincipal, defaultMaxPrincipal,
defaultMaxNumberOfInstallments); defaultMinNominalInterestRatePerPeriod,
defaultMaxNominalInterestRatePerPeriod,
defaultMinNumberOfInstallments, defaultMaxNumberOfInstallments);
if (accountingRuleType != null) { if (accountingRuleType != null) {
this.accountingRule = accountingRuleType.getValue(); this.accountingRule = accountingRuleType.getValue();
} }
} }
public MonetaryCurrency getCurrency() { public MonetaryCurrency getCurrency() {
return this.loanProductRelatedDetail.getCurrency(); return this.loanProductRelatedDetail.getCurrency();
} }
public void update(final Fund fund) { public void update(final Fund fund) {
this.fund = fund; this.fund = fund;
} }
public void update(final LoanTransactionProcessingStrategy strategy) { public void update(final LoanTransactionProcessingStrategy strategy) {
this.transactionProcessingStrategy = strategy; this.transactionProcessingStrategy = strategy;
} }
public boolean update(final List<Charge> newProductCharges) { public boolean update(final List<Charge> newProductCharges) {
boolean updated = false; if (newProductCharges == null)
if (this.charges != null) { return false;
final Set<Charge> setOfCharges = new HashSet<Charge>(this.charges);
updated = setOfCharges.addAll(newProductCharges); boolean updated = false;
if (updated) { if (this.charges != null) {
this.charges = newProductCharges; final Set<Charge> currentSetOfCharges = new HashSet<Charge>(
} this.charges);
} final Set<Charge> newSetOfCharges = new HashSet<Charge>(
return updated; newProductCharges);
}
public Integer getAccountingType() { if (!(currentSetOfCharges.equals(newSetOfCharges))) {
return this.accountingRule; updated = true;
} this.charges = newProductCharges;
}
} else {
updated = true;
this.charges = newProductCharges;
}
return updated;
}
public Map<String, Object> update(final JsonCommand command, final AprCalculator aprCalculator) { public Integer getAccountingType() {
return this.accountingRule;
}
final Map<String, Object> actualChanges = this.loanProductRelatedDetail.update(command, aprCalculator); public Map<String, Object> update(final JsonCommand command,
actualChanges.putAll(this.loanProductMinMaxConstraints().update(command)); final AprCalculator aprCalculator) {
final String accountingTypeParamName = "accountingRule"; final Map<String, Object> actualChanges = this.loanProductRelatedDetail
if (command.isChangeInIntegerParameterNamed(accountingTypeParamName, this.accountingRule)) { .update(command, aprCalculator);
final Integer newValue = command.integerValueOfParameterNamed(accountingTypeParamName); actualChanges.putAll(this.loanProductMinMaxConstraints()
actualChanges.put(accountingTypeParamName, newValue); .update(command));
this.accountingRule = newValue;
}
final String nameParamName = "name"; final String accountingTypeParamName = "accountingRule";
if (command.isChangeInStringParameterNamed(nameParamName, this.name)) { if (command.isChangeInIntegerParameterNamed(accountingTypeParamName,
final String newValue = command.stringValueOfParameterNamed(nameParamName); this.accountingRule)) {
actualChanges.put(nameParamName, newValue); final Integer newValue = command
this.name = newValue; .integerValueOfParameterNamed(accountingTypeParamName);
} actualChanges.put(accountingTypeParamName, newValue);
this.accountingRule = newValue;
}
final String descriptionParamName = "description"; final String nameParamName = "name";
if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) { if (command.isChangeInStringParameterNamed(nameParamName, this.name)) {
final String newValue = command.stringValueOfParameterNamed(descriptionParamName); final String newValue = command
actualChanges.put(descriptionParamName, newValue); .stringValueOfParameterNamed(nameParamName);
this.description = newValue; actualChanges.put(nameParamName, newValue);
} this.name = newValue;
}
Long existingFundId = null; final String descriptionParamName = "description";
if (this.fund != null) { if (command.isChangeInStringParameterNamed(descriptionParamName,
existingFundId = this.fund.getId(); this.description)) {
} final String newValue = command
final String fundIdParamName = "fundId"; .stringValueOfParameterNamed(descriptionParamName);
if (command.isChangeInLongParameterNamed(fundIdParamName, existingFundId)) { actualChanges.put(descriptionParamName, newValue);
final Long newValue = command.longValueOfParameterNamed(fundIdParamName); this.description = newValue;
actualChanges.put(fundIdParamName, newValue); }
}
Long existingStrategyId = null; Long existingFundId = null;
if (this.transactionProcessingStrategy != null) { if (this.fund != null) {
existingStrategyId = this.transactionProcessingStrategy.getId(); existingFundId = this.fund.getId();
} }
final String transactionProcessingStrategyParamName = "transactionProcessingStrategyId"; final String fundIdParamName = "fundId";
if (command.isChangeInLongParameterNamed(transactionProcessingStrategyParamName, existingStrategyId)) { if (command.isChangeInLongParameterNamed(fundIdParamName,
final Long newValue = command.longValueOfParameterNamed(transactionProcessingStrategyParamName); existingFundId)) {
actualChanges.put(transactionProcessingStrategyParamName, newValue); final Long newValue = command
} .longValueOfParameterNamed(fundIdParamName);
actualChanges.put(fundIdParamName, newValue);
}
final String chargesParamName = "charges"; Long existingStrategyId = null;
if (command.hasParameter(chargesParamName)) { if (this.transactionProcessingStrategy != null) {
JsonArray jsonArray = command.arrayOfParameterNamed(chargesParamName); existingStrategyId = this.transactionProcessingStrategy.getId();
if (jsonArray != null) { }
final String transactionProcessingStrategyParamName = "transactionProcessingStrategyId";
if (command.isChangeInLongParameterNamed(
transactionProcessingStrategyParamName, existingStrategyId)) {
final Long newValue = command
.longValueOfParameterNamed(transactionProcessingStrategyParamName);
actualChanges.put(transactionProcessingStrategyParamName, newValue);
}
} final String chargesParamName = "charges";
actualChanges.put(chargesParamName, command.jsonFragment(chargesParamName)); if (command.hasParameter(chargesParamName)) {
} JsonArray jsonArray = command
.arrayOfParameterNamed(chargesParamName);
if (jsonArray != null) {
return actualChanges; }
} actualChanges.put(chargesParamName,
command.jsonFragment(chargesParamName));
}
public boolean isCashBasedAccountingEnabled() { return actualChanges;
return AccountingRuleType.CASH_BASED.getValue().equals(this.accountingRule); }
}
public boolean isAccrualBasedAccountingEnabled() { public boolean isCashBasedAccountingEnabled() {
return AccountingRuleType.ACCRUAL_BASED.getValue().equals(this.accountingRule); return AccountingRuleType.CASH_BASED.getValue().equals(
} this.accountingRule);
}
public Money getPrincipalAmount(){ public boolean isAccrualBasedAccountingEnabled() {
return this.loanProductRelatedDetail.getPrincipal(); return AccountingRuleType.ACCRUAL_BASED.getValue().equals(
} this.accountingRule);
}
public Money getMinPrincipalAmount(){ public Money getPrincipalAmount() {
return Money.of(this.loanProductRelatedDetail.getCurrency(), this.loanProductMinMaxConstraints().getMinPrincipal()); return this.loanProductRelatedDetail.getPrincipal();
} }
public Money getMaxPrincipalAmount(){ public Money getMinPrincipalAmount() {
return Money.of(this.loanProductRelatedDetail.getCurrency(), this.loanProductMinMaxConstraints().getMaxPrincipal()); return Money.of(this.loanProductRelatedDetail.getCurrency(), this
} .loanProductMinMaxConstraints().getMinPrincipal());
}
public BigDecimal getNominalInterestRatePerPeriod() { public Money getMaxPrincipalAmount() {
return this.loanProductRelatedDetail.getNominalInterestRatePerPeriod(); return Money.of(this.loanProductRelatedDetail.getCurrency(), this
} .loanProductMinMaxConstraints().getMaxPrincipal());
}
public BigDecimal getMinNominalInterestRatePerPeriod() { public BigDecimal getNominalInterestRatePerPeriod() {
return this.loanProductMinMaxConstraints().getMinNominalInterestRatePerPeriod(); return this.loanProductRelatedDetail.getNominalInterestRatePerPeriod();
} }
public BigDecimal getMaxNominalInterestRatePerPeriod(){ public BigDecimal getMinNominalInterestRatePerPeriod() {
return this.loanProductMinMaxConstraints().getMaxNominalInterestRatePerPeriod(); return this.loanProductMinMaxConstraints()
} .getMinNominalInterestRatePerPeriod();
}
public Integer getNumberOfRepayments(){ public BigDecimal getMaxNominalInterestRatePerPeriod() {
return this.loanProductRelatedDetail().getNumberOfRepayments(); return this.loanProductMinMaxConstraints()
} .getMaxNominalInterestRatePerPeriod();
}
public Integer getMinNumberOfRepayments() { public Integer getNumberOfRepayments() {
return this.loanProductMinMaxConstraints().getMinNumberOfRepayments(); return this.loanProductRelatedDetail().getNumberOfRepayments();
} }
public Integer getMaxNumberOfRepayments() { public Integer getMinNumberOfRepayments() {
return this.loanProductMinMaxConstraints().getMaxNumberOfRepayments(); return this.loanProductMinMaxConstraints().getMinNumberOfRepayments();
} }
public LoanProductRelatedDetail loanProductRelatedDetail(){ public Integer getMaxNumberOfRepayments() {
return this.loanProductRelatedDetail; return this.loanProductMinMaxConstraints().getMaxNumberOfRepayments();
} }
public LoanProductMinMaxConstraints loanProductMinMaxConstraints() { public LoanProductRelatedDetail loanProductRelatedDetail() {
//If all min and max fields are null then loanProductMinMaxConstraints initialising to null return this.loanProductRelatedDetail;
//Reset LoanProductMinMaxConstraints with null values. }
this.loanProductMinMaxConstraints = (this.loanProductMinMaxConstraints == null) ? new LoanProductMinMaxConstraints(null, null, null, null, null, null)
: this.loanProductMinMaxConstraints; public LoanProductMinMaxConstraints loanProductMinMaxConstraints() {
return loanProductMinMaxConstraints; // If all min and max fields are null then loanProductMinMaxConstraints
} // initialising to null
// Reset LoanProductMinMaxConstraints with null values.
this.loanProductMinMaxConstraints = (this.loanProductMinMaxConstraints == null) ? new LoanProductMinMaxConstraints(
null, null, null, null, null, null)
: this.loanProductMinMaxConstraints;
return loanProductMinMaxConstraints;
}
} }