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
private LoanProductMinMaxConstraints loanProductMinMaxConstraints;
@Column(name = "accounting_type", nullable = false) @Embedded
private Integer accountingRule; private LoanProductMinMaxConstraints loanProductMinMaxConstraints;
public static LoanProduct assembleFromJson(final Fund fund, final LoanTransactionProcessingStrategy loanTransactionProcessingStrategy, @Column(name = "accounting_type", nullable = false)
final List<Charge> productCharges, final JsonCommand command, final AprCalculator aprCalculator) { private Integer accountingRule;
final String name = command.stringValueOfParameterNamed("name"); public static LoanProduct assembleFromJson(
final String description = command.stringValueOfParameterNamed("description"); final Fund fund,
final String currencyCode = command.stringValueOfParameterNamed("currencyCode"); final LoanTransactionProcessingStrategy loanTransactionProcessingStrategy,
final Integer digitsAfterDecimal = command.integerValueOfParameterNamed("digitsAfterDecimal"); final List<Charge> productCharges, final JsonCommand command,
final AprCalculator aprCalculator) {
final MonetaryCurrency currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal); final String name = command.stringValueOfParameterNamed("name");
final BigDecimal principal = command.bigDecimalValueOfParameterNamed("principal"); final String description = command
final BigDecimal minPrincipal = command.bigDecimalValueOfParameterNamed("minPrincipal"); .stringValueOfParameterNamed("description");
final BigDecimal maxPrincipal = command.bigDecimalValueOfParameterNamed("maxPrincipal"); final String currencyCode = command
.stringValueOfParameterNamed("currencyCode");
final Integer digitsAfterDecimal = command
.integerValueOfParameterNamed("digitsAfterDecimal");
final InterestMethod interestMethod = InterestMethod.fromInt(command.integerValueOfParameterNamed("interestType")); final MonetaryCurrency currency = new MonetaryCurrency(currencyCode,
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command digitsAfterDecimal);
.integerValueOfParameterNamed("interestCalculationPeriodType")); final BigDecimal principal = command
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.integerValueOfParameterNamed("amortizationType")); .bigDecimalValueOfParameterNamed("principal");
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command final BigDecimal minPrincipal = command
.integerValueOfParameterNamed("repaymentFrequencyType")); .bigDecimalValueOfParameterNamed("minPrincipal");
final PeriodFrequencyType interestFrequencyType = PeriodFrequencyType.fromInt(command final BigDecimal maxPrincipal = command
.integerValueOfParameterNamed("interestRateFrequencyType")); .bigDecimalValueOfParameterNamed("maxPrincipal");
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 InterestMethod interestMethod = InterestMethod.fromInt(command
final Integer numberOfRepayments = command.integerValueOfParameterNamed("numberOfRepayments"); .integerValueOfParameterNamed("interestType"));
final Integer minNumberOfRepayments = command.integerValueOfParameterNamed("minNumberOfRepayments"); final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod
final Integer maxNumberOfRepayments = command.integerValueOfParameterNamed("maxNumberOfRepayments"); .fromInt(command
final BigDecimal inArrearsTolerance = command.bigDecimalValueOfParameterNamed("inArrearsTolerance"); .integerValueOfParameterNamed("interestCalculationPeriodType"));
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(command.integerValueOfParameterNamed("accountingRule")); final AmortizationMethod amortizationMethod = AmortizationMethod
.fromInt(command
.integerValueOfParameterNamed("amortizationType"));
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType
.fromInt(command
.integerValueOfParameterNamed("repaymentFrequencyType"));
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);
return new LoanProduct(fund, loanTransactionProcessingStrategy, name, description, currency, principal, minPrincipal, maxPrincipal, final Integer repaymentEvery = command
interestRatePerPeriod, minInterestRatePerPeriod, maxInterestRatePerPeriod, interestFrequencyType, annualInterestRate, interestMethod, interestCalculationPeriodMethod, .integerValueOfParameterNamed("repaymentEvery");
repaymentEvery, repaymentFrequencyType, numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, amortizationMethod, inArrearsTolerance, productCharges, final Integer numberOfRepayments = command
accountingRuleType); .integerValueOfParameterNamed("numberOfRepayments");
} final Integer minNumberOfRepayments = command
.integerValueOfParameterNamed("minNumberOfRepayments");
final Integer maxNumberOfRepayments = command
.integerValueOfParameterNamed("maxNumberOfRepayments");
final BigDecimal inArrearsTolerance = command
.bigDecimalValueOfParameterNamed("inArrearsTolerance");
final AccountingRuleType accountingRuleType = AccountingRuleType
.fromInt(command.integerValueOfParameterNamed("accountingRule"));
protected LoanProduct() { return new LoanProduct(fund, loanTransactionProcessingStrategy, name,
this.loanProductRelatedDetail = null; description, currency, principal, minPrincipal, maxPrincipal,
this.loanProductMinMaxConstraints = null; interestRatePerPeriod, minInterestRatePerPeriod,
} maxInterestRatePerPeriod, interestFrequencyType,
annualInterestRate, interestMethod,
interestCalculationPeriodMethod, repaymentEvery,
repaymentFrequencyType, numberOfRepayments,
minNumberOfRepayments, maxNumberOfRepayments,
amortizationMethod, inArrearsTolerance, productCharges,
accountingRuleType);
}
public LoanProduct(final Fund fund, final LoanTransactionProcessingStrategy transactionProcessingStrategy, final String name, protected LoanProduct() {
final String description, final MonetaryCurrency currency, final BigDecimal defaultPrincipal, this.loanProductRelatedDetail = null;
final BigDecimal defaultMinPrincipal, final BigDecimal defaultMaxPrincipal, this.loanProductMinMaxConstraints = null;
final BigDecimal defaultNominalInterestRatePerPeriod, final BigDecimal defaultMinNominalInterestRatePerPeriod, }
final BigDecimal defaultMaxNominalInterestRatePerPeriod, final PeriodFrequencyType interestPeriodFrequencyType,
final BigDecimal defaultAnnualNominalInterestRate, final InterestMethod interestMethod,
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery,
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) { public LoanProduct(
this.charges = charges; final Fund fund,
} final LoanTransactionProcessingStrategy transactionProcessingStrategy,
final String name,
final String description,
final MonetaryCurrency currency,
final BigDecimal defaultPrincipal,
final BigDecimal defaultMinPrincipal,
final BigDecimal defaultMaxPrincipal,
final BigDecimal defaultNominalInterestRatePerPeriod,
final BigDecimal defaultMinNominalInterestRatePerPeriod,
final BigDecimal defaultMaxNominalInterestRatePerPeriod,
final PeriodFrequencyType interestPeriodFrequencyType,
final BigDecimal defaultAnnualNominalInterestRate,
final InterestMethod interestMethod,
final InterestCalculationPeriodMethod interestCalculationPeriodMethod,
final Integer repayEvery,
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;
}
this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, if (charges != null) {
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, this.charges = charges;
repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod, inArrearsTolerance); }
this.loanProductMinMaxConstraints = new LoanProductMinMaxConstraints(defaultMinPrincipal, defaultMaxPrincipal, this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency,
defaultMinNominalInterestRatePerPeriod, defaultMaxNominalInterestRatePerPeriod, defaultMinNumberOfInstallments, defaultPrincipal, defaultNominalInterestRatePerPeriod,
defaultMaxNumberOfInstallments); interestPeriodFrequencyType, defaultAnnualNominalInterestRate,
interestMethod, interestCalculationPeriodMethod, repayEvery,
if (accountingRuleType != null) { repaymentFrequencyType, defaultNumberOfInstallments,
this.accountingRule = accountingRuleType.getValue(); amortizationMethod, inArrearsTolerance);
}
}
public MonetaryCurrency getCurrency() { this.loanProductMinMaxConstraints = new LoanProductMinMaxConstraints(
return this.loanProductRelatedDetail.getCurrency(); defaultMinPrincipal, defaultMaxPrincipal,
} defaultMinNominalInterestRatePerPeriod,
defaultMaxNominalInterestRatePerPeriod,
defaultMinNumberOfInstallments, defaultMaxNumberOfInstallments);
public void update(final Fund fund) { if (accountingRuleType != null) {
this.fund = fund; this.accountingRule = accountingRuleType.getValue();
} }
}
public void update(final LoanTransactionProcessingStrategy strategy) { public MonetaryCurrency getCurrency() {
this.transactionProcessingStrategy = strategy; return this.loanProductRelatedDetail.getCurrency();
} }
public boolean update(final List<Charge> newProductCharges) { public void update(final Fund fund) {
boolean updated = false; this.fund = fund;
if (this.charges != null) { }
final Set<Charge> setOfCharges = new HashSet<Charge>(this.charges);
updated = setOfCharges.addAll(newProductCharges); public void update(final LoanTransactionProcessingStrategy strategy) {
if (updated) { this.transactionProcessingStrategy = strategy;
this.charges = newProductCharges; }
}
}
return updated;
}
public Integer getAccountingType() { public boolean update(final List<Charge> newProductCharges) {
return this.accountingRule; if (newProductCharges == null)
} return false;
public Map<String, Object> update(final JsonCommand command, final AprCalculator aprCalculator) { boolean updated = false;
if (this.charges != null) {
final Set<Charge> currentSetOfCharges = new HashSet<Charge>(
this.charges);
final Set<Charge> newSetOfCharges = new HashSet<Charge>(
newProductCharges);
final Map<String, Object> actualChanges = this.loanProductRelatedDetail.update(command, aprCalculator); if (!(currentSetOfCharges.equals(newSetOfCharges))) {
actualChanges.putAll(this.loanProductMinMaxConstraints().update(command)); updated = true;
this.charges = newProductCharges;
}
} else {
updated = true;
this.charges = newProductCharges;
}
return updated;
}
final String accountingTypeParamName = "accountingRule"; public Integer getAccountingType() {
if (command.isChangeInIntegerParameterNamed(accountingTypeParamName, this.accountingRule)) { return this.accountingRule;
final Integer newValue = command.integerValueOfParameterNamed(accountingTypeParamName); }
actualChanges.put(accountingTypeParamName, newValue);
this.accountingRule = newValue;
}
final String nameParamName = "name"; public Map<String, Object> update(final JsonCommand command,
if (command.isChangeInStringParameterNamed(nameParamName, this.name)) { final AprCalculator aprCalculator) {
final String newValue = command.stringValueOfParameterNamed(nameParamName);
actualChanges.put(nameParamName, newValue);
this.name = newValue;
}
final String descriptionParamName = "description"; final Map<String, Object> actualChanges = this.loanProductRelatedDetail
if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) { .update(command, aprCalculator);
final String newValue = command.stringValueOfParameterNamed(descriptionParamName); actualChanges.putAll(this.loanProductMinMaxConstraints()
actualChanges.put(descriptionParamName, newValue); .update(command));
this.description = newValue;
}
Long existingFundId = null; final String accountingTypeParamName = "accountingRule";
if (this.fund != null) { if (command.isChangeInIntegerParameterNamed(accountingTypeParamName,
existingFundId = this.fund.getId(); this.accountingRule)) {
} final Integer newValue = command
final String fundIdParamName = "fundId"; .integerValueOfParameterNamed(accountingTypeParamName);
if (command.isChangeInLongParameterNamed(fundIdParamName, existingFundId)) { actualChanges.put(accountingTypeParamName, newValue);
final Long newValue = command.longValueOfParameterNamed(fundIdParamName); this.accountingRule = newValue;
actualChanges.put(fundIdParamName, newValue); }
}
Long existingStrategyId = null; final String nameParamName = "name";
if (this.transactionProcessingStrategy != null) { if (command.isChangeInStringParameterNamed(nameParamName, this.name)) {
existingStrategyId = this.transactionProcessingStrategy.getId(); final String newValue = command
} .stringValueOfParameterNamed(nameParamName);
final String transactionProcessingStrategyParamName = "transactionProcessingStrategyId"; actualChanges.put(nameParamName, newValue);
if (command.isChangeInLongParameterNamed(transactionProcessingStrategyParamName, existingStrategyId)) { this.name = newValue;
final Long newValue = command.longValueOfParameterNamed(transactionProcessingStrategyParamName); }
actualChanges.put(transactionProcessingStrategyParamName, newValue);
}
final String chargesParamName = "charges"; final String descriptionParamName = "description";
if (command.hasParameter(chargesParamName)) { if (command.isChangeInStringParameterNamed(descriptionParamName,
JsonArray jsonArray = command.arrayOfParameterNamed(chargesParamName); this.description)) {
if (jsonArray != null) { final String newValue = command
.stringValueOfParameterNamed(descriptionParamName);
actualChanges.put(descriptionParamName, newValue);
this.description = newValue;
}
} Long existingFundId = null;
actualChanges.put(chargesParamName, command.jsonFragment(chargesParamName)); if (this.fund != null) {
} existingFundId = this.fund.getId();
}
final String fundIdParamName = "fundId";
if (command.isChangeInLongParameterNamed(fundIdParamName,
existingFundId)) {
final Long newValue = command
.longValueOfParameterNamed(fundIdParamName);
actualChanges.put(fundIdParamName, newValue);
}
return actualChanges; Long existingStrategyId = null;
} if (this.transactionProcessingStrategy != null) {
existingStrategyId = this.transactionProcessingStrategy.getId();
}
final String transactionProcessingStrategyParamName = "transactionProcessingStrategyId";
if (command.isChangeInLongParameterNamed(
transactionProcessingStrategyParamName, existingStrategyId)) {
final Long newValue = command
.longValueOfParameterNamed(transactionProcessingStrategyParamName);
actualChanges.put(transactionProcessingStrategyParamName, newValue);
}
public boolean isCashBasedAccountingEnabled() { final String chargesParamName = "charges";
return AccountingRuleType.CASH_BASED.getValue().equals(this.accountingRule); if (command.hasParameter(chargesParamName)) {
} JsonArray jsonArray = command
.arrayOfParameterNamed(chargesParamName);
if (jsonArray != null) {
public boolean isAccrualBasedAccountingEnabled() { }
return AccountingRuleType.ACCRUAL_BASED.getValue().equals(this.accountingRule); actualChanges.put(chargesParamName,
} command.jsonFragment(chargesParamName));
}
public Money getPrincipalAmount(){
return this.loanProductRelatedDetail.getPrincipal();
}
public Money getMinPrincipalAmount(){
return Money.of(this.loanProductRelatedDetail.getCurrency(), this.loanProductMinMaxConstraints().getMinPrincipal());
}
public Money getMaxPrincipalAmount(){
return Money.of(this.loanProductRelatedDetail.getCurrency(), this.loanProductMinMaxConstraints().getMaxPrincipal());
}
public BigDecimal getNominalInterestRatePerPeriod() {
return this.loanProductRelatedDetail.getNominalInterestRatePerPeriod();
}
public BigDecimal getMinNominalInterestRatePerPeriod() {
return this.loanProductMinMaxConstraints().getMinNominalInterestRatePerPeriod();
}
public BigDecimal getMaxNominalInterestRatePerPeriod(){
return this.loanProductMinMaxConstraints().getMaxNominalInterestRatePerPeriod();
}
public Integer getNumberOfRepayments(){
return this.loanProductRelatedDetail().getNumberOfRepayments();
}
public Integer getMinNumberOfRepayments() {
return this.loanProductMinMaxConstraints().getMinNumberOfRepayments();
}
public Integer getMaxNumberOfRepayments() { return actualChanges;
return this.loanProductMinMaxConstraints().getMaxNumberOfRepayments(); }
}
public boolean isCashBasedAccountingEnabled() {
public LoanProductRelatedDetail loanProductRelatedDetail(){ return AccountingRuleType.CASH_BASED.getValue().equals(
return this.loanProductRelatedDetail; this.accountingRule);
} }
public LoanProductMinMaxConstraints loanProductMinMaxConstraints() { public boolean isAccrualBasedAccountingEnabled() {
//If all min and max fields are null then loanProductMinMaxConstraints initialising to null return AccountingRuleType.ACCRUAL_BASED.getValue().equals(
//Reset LoanProductMinMaxConstraints with null values. this.accountingRule);
this.loanProductMinMaxConstraints = (this.loanProductMinMaxConstraints == null) ? new LoanProductMinMaxConstraints(null, null, null, null, null, null) }
: this.loanProductMinMaxConstraints;
return loanProductMinMaxConstraints; public Money getPrincipalAmount() {
} return this.loanProductRelatedDetail.getPrincipal();
}
public Money getMinPrincipalAmount() {
return Money.of(this.loanProductRelatedDetail.getCurrency(), this
.loanProductMinMaxConstraints().getMinPrincipal());
}
public Money getMaxPrincipalAmount() {
return Money.of(this.loanProductRelatedDetail.getCurrency(), this
.loanProductMinMaxConstraints().getMaxPrincipal());
}
public BigDecimal getNominalInterestRatePerPeriod() {
return this.loanProductRelatedDetail.getNominalInterestRatePerPeriod();
}
public BigDecimal getMinNominalInterestRatePerPeriod() {
return this.loanProductMinMaxConstraints()
.getMinNominalInterestRatePerPeriod();
}
public BigDecimal getMaxNominalInterestRatePerPeriod() {
return this.loanProductMinMaxConstraints()
.getMaxNominalInterestRatePerPeriod();
}
public Integer getNumberOfRepayments() {
return this.loanProductRelatedDetail().getNumberOfRepayments();
}
public Integer getMinNumberOfRepayments() {
return this.loanProductMinMaxConstraints().getMinNumberOfRepayments();
}
public Integer getMaxNumberOfRepayments() {
return this.loanProductMinMaxConstraints().getMaxNumberOfRepayments();
}
public LoanProductRelatedDetail loanProductRelatedDetail() {
return this.loanProductRelatedDetail;
}
public LoanProductMinMaxConstraints 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;
}
} }