MIFOSX-57 reorganization of loan charges design.
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
DROP TABLE `m_loan_charge`;
|
||||||
|
CREATE TABLE `m_loan_charge` (
|
||||||
|
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||||
|
`loan_id` bigint(20) NOT NULL,
|
||||||
|
`charge_id` bigint(20) NOT NULL,
|
||||||
|
`charge_time_enum` smallint(5) NOT NULL,
|
||||||
|
`charge_calculation_enum` smallint(5) NOT NULL,
|
||||||
|
`amount` decimal(19,6) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `charge_id` (`charge_id`),
|
||||||
|
CONSTRAINT `m_loan_charge_ibfk_1` FOREIGN KEY (`charge_id`) REFERENCES `m_charge` (`id`),
|
||||||
|
CONSTRAINT `m_loan_charge_ibfk_2` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8
|
||||||
@@ -201,6 +201,23 @@ public class DataValidatorBuilder {
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DataValidatorBuilder longGreaterThanZero() {
|
||||||
|
if (value == null && ignoreNullValue) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
Long number = Long.valueOf(value.toString());
|
||||||
|
if (number < 1) {
|
||||||
|
StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(resource).append(".").append(parameter).append(".not.greater.than.zero");
|
||||||
|
StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(parameter).append(" must be greater than 0.");
|
||||||
|
ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), parameter, number, 0);
|
||||||
|
dataValidationErrors.add(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public DataValidatorBuilder arrayNotEmpty() {
|
public DataValidatorBuilder arrayNotEmpty() {
|
||||||
if (value == null && ignoreNullValue) {
|
if (value == null && ignoreNullValue) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.mifosng.platform.api.data.EnumOptionData;
|
|||||||
import org.mifosng.platform.api.data.FundData;
|
import org.mifosng.platform.api.data.FundData;
|
||||||
import org.mifosng.platform.api.data.LoanAccountData;
|
import org.mifosng.platform.api.data.LoanAccountData;
|
||||||
import org.mifosng.platform.api.data.LoanBasicDetailsData;
|
import org.mifosng.platform.api.data.LoanBasicDetailsData;
|
||||||
|
import org.mifosng.platform.api.data.LoanChargeData;
|
||||||
import org.mifosng.platform.api.data.LoanPermissionData;
|
import org.mifosng.platform.api.data.LoanPermissionData;
|
||||||
import org.mifosng.platform.api.data.LoanProductLookup;
|
import org.mifosng.platform.api.data.LoanProductLookup;
|
||||||
import org.mifosng.platform.api.data.LoanRepaymentTransactionData;
|
import org.mifosng.platform.api.data.LoanRepaymentTransactionData;
|
||||||
@@ -148,12 +149,9 @@ public class LoansApiResource {
|
|||||||
ChargeData chargeTemplate = this.chargeReadPlatformService.retrieveLoanChargeTemplate();
|
ChargeData chargeTemplate = this.chargeReadPlatformService.retrieveLoanChargeTemplate();
|
||||||
|
|
||||||
LoanBasicDetailsData loanBasicDetails = this.loanReadPlatformService.retrieveClientAndProductDetails(clientId, productId);
|
LoanBasicDetailsData loanBasicDetails = this.loanReadPlatformService.retrieveClientAndProductDetails(clientId, productId);
|
||||||
if (loanBasicDetails.getCharges() != null) {
|
|
||||||
chargeOptions.removeAll(loanBasicDetails.getCharges());
|
|
||||||
}
|
|
||||||
|
|
||||||
final boolean convenienceDataRequired = false;
|
final boolean convenienceDataRequired = false;
|
||||||
Collection<ChargeData> charges = loanBasicDetails.getCharges();
|
Collection<LoanChargeData> charges = loanBasicDetails.getCharges();
|
||||||
|
|
||||||
Collection<StaffData> allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(loanBasicDetails.getClientOfficeId());
|
Collection<StaffData> allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(loanBasicDetails.getClientOfficeId());
|
||||||
|
|
||||||
@@ -185,7 +183,7 @@ public class LoansApiResource {
|
|||||||
Collection<LoanRepaymentTransactionData> loanRepayments = null;
|
Collection<LoanRepaymentTransactionData> loanRepayments = null;
|
||||||
LoanScheduleData repaymentSchedule = null;
|
LoanScheduleData repaymentSchedule = null;
|
||||||
LoanPermissionData permissions = null;
|
LoanPermissionData permissions = null;
|
||||||
Collection<ChargeData> charges = null;
|
Collection<LoanChargeData> charges = null;
|
||||||
|
|
||||||
boolean convenienceDataRequired = false;
|
boolean convenienceDataRequired = false;
|
||||||
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||||
@@ -250,9 +248,6 @@ public class LoansApiResource {
|
|||||||
fundOptions = this.fundReadPlatformService.retrieveAllFunds();
|
fundOptions = this.fundReadPlatformService.retrieveAllFunds();
|
||||||
repaymentStrategyOptions = this.dropdownReadPlatformService.retreiveTransactionProcessingStrategies();
|
repaymentStrategyOptions = this.dropdownReadPlatformService.retreiveTransactionProcessingStrategies();
|
||||||
chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges();
|
chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges();
|
||||||
if (charges != null) {
|
|
||||||
chargeOptions.removeAll(charges);
|
|
||||||
}
|
|
||||||
allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(loanBasicDetails.getClientOfficeId());
|
allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(loanBasicDetails.getClientOfficeId());
|
||||||
chargeTemplate = this.chargeReadPlatformService.retrieveLoanChargeTemplate();
|
chargeTemplate = this.chargeReadPlatformService.retrieveLoanChargeTemplate();
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-2
@@ -6,6 +6,7 @@ import java.util.Set;
|
|||||||
public class LoanChargeCommand {
|
public class LoanChargeCommand {
|
||||||
|
|
||||||
private final Long id;
|
private final Long id;
|
||||||
|
private final Long chargeId;
|
||||||
private final BigDecimal amount;
|
private final BigDecimal amount;
|
||||||
|
|
||||||
private final Integer chargeTimeType;
|
private final Integer chargeTimeType;
|
||||||
@@ -13,10 +14,11 @@ public class LoanChargeCommand {
|
|||||||
|
|
||||||
private final Set<String> modifiedParameters;
|
private final Set<String> modifiedParameters;
|
||||||
|
|
||||||
public LoanChargeCommand(final Set<String> modifiedParameters, final Long id, final BigDecimal amount,
|
public LoanChargeCommand(final Set<String> modifiedParameters, final Long id, final Long chargeId,
|
||||||
final Integer chargeTimeType, final Integer chargeCalculationType) {
|
final BigDecimal amount, final Integer chargeTimeType, final Integer chargeCalculationType) {
|
||||||
this.modifiedParameters = modifiedParameters;
|
this.modifiedParameters = modifiedParameters;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
this.chargeId = chargeId;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.chargeTimeType = chargeTimeType;
|
this.chargeTimeType = chargeTimeType;
|
||||||
this.chargeCalculationType = chargeCalculationType;
|
this.chargeCalculationType = chargeCalculationType;
|
||||||
@@ -26,6 +28,10 @@ public class LoanChargeCommand {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getChargeId() {
|
||||||
|
return chargeId;
|
||||||
|
}
|
||||||
|
|
||||||
public BigDecimal getAmount() {
|
public BigDecimal getAmount() {
|
||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class LoanAccountData {
|
|||||||
// associations
|
// associations
|
||||||
private final LoanScheduleData repaymentSchedule;
|
private final LoanScheduleData repaymentSchedule;
|
||||||
private final Collection<LoanRepaymentTransactionData> loanRepayments;
|
private final Collection<LoanRepaymentTransactionData> loanRepayments;
|
||||||
private final Collection<ChargeData> charges;
|
private final Collection<LoanChargeData> charges;
|
||||||
private final LoanPermissionData permissions;
|
private final LoanPermissionData permissions;
|
||||||
private final LoanConvenienceData convenienceData;
|
private final LoanConvenienceData convenienceData;
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ public class LoanAccountData {
|
|||||||
final LoanScheduleData repaymentSchedule,
|
final LoanScheduleData repaymentSchedule,
|
||||||
final Collection<LoanRepaymentTransactionData> loanRepayments,
|
final Collection<LoanRepaymentTransactionData> loanRepayments,
|
||||||
final LoanPermissionData permissions,
|
final LoanPermissionData permissions,
|
||||||
final Collection<ChargeData> charges,
|
final Collection<LoanChargeData> charges,
|
||||||
final Collection<LoanProductLookup> productOptions,
|
final Collection<LoanProductLookup> productOptions,
|
||||||
final Collection<EnumOptionData> termFrequencyTypeOptions,
|
final Collection<EnumOptionData> termFrequencyTypeOptions,
|
||||||
final Collection<EnumOptionData> repaymentFrequencyTypeOptions,
|
final Collection<EnumOptionData> repaymentFrequencyTypeOptions,
|
||||||
|
|||||||
+12
-5
@@ -1,6 +1,7 @@
|
|||||||
package org.mifosng.platform.api.data;
|
package org.mifosng.platform.api.data;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
@@ -53,7 +54,7 @@ public class LoanBasicDetailsData {
|
|||||||
private final LocalDate expectedMaturityDate;
|
private final LocalDate expectedMaturityDate;
|
||||||
private final LocalDate lifeCycleStatusDate;
|
private final LocalDate lifeCycleStatusDate;
|
||||||
|
|
||||||
private final Collection<ChargeData> charges;
|
private final Collection<LoanChargeData> charges;
|
||||||
|
|
||||||
public static LoanBasicDetailsData populateForNewLoanCreation(final Long clientId, final String clientName, final LocalDate expectedDisbursementDate,
|
public static LoanBasicDetailsData populateForNewLoanCreation(final Long clientId, final String clientName, final LocalDate expectedDisbursementDate,
|
||||||
final Long clientOfficeId) {
|
final Long clientOfficeId) {
|
||||||
@@ -64,6 +65,12 @@ public class LoanBasicDetailsData {
|
|||||||
|
|
||||||
final Integer termFrequency = product.getNumberOfRepayments() * product.getRepaymentEvery();
|
final Integer termFrequency = product.getNumberOfRepayments() * product.getRepaymentEvery();
|
||||||
final EnumOptionData termPeriodFrequencyType = product.getRepaymentFrequencyType();
|
final EnumOptionData termPeriodFrequencyType = product.getRepaymentFrequencyType();
|
||||||
|
final Collection<LoanChargeData> charges = new ArrayList<LoanChargeData>();
|
||||||
|
for (ChargeData charge : product.getCharges()){
|
||||||
|
charges.add(new LoanChargeData(null, charge.getId(), charge.getName(), charge.getCurrency(),
|
||||||
|
charge.getAmount(), charge.getChargeTimeType(), charge.getChargeCalculationType()));
|
||||||
|
}
|
||||||
|
|
||||||
return new LoanBasicDetailsData(
|
return new LoanBasicDetailsData(
|
||||||
loanAccount.clientId, loanAccount.clientName, loanAccount.clientOfficeId,
|
loanAccount.clientId, loanAccount.clientName, loanAccount.clientOfficeId,
|
||||||
product.getId(), product.getName(), product.getDescription(), product.getFundId(), product.getFundName(),
|
product.getId(), product.getName(), product.getDescription(), product.getFundId(), product.getFundName(),
|
||||||
@@ -71,7 +78,7 @@ public class LoanBasicDetailsData {
|
|||||||
termFrequency, termPeriodFrequencyType, product.getNumberOfRepayments(), product.getRepaymentEvery(), product.getRepaymentFrequencyType(),
|
termFrequency, termPeriodFrequencyType, product.getNumberOfRepayments(), product.getRepaymentEvery(), product.getRepaymentFrequencyType(),
|
||||||
product.getTransactionProcessingStrategyId(), product.getAmortizationType(),
|
product.getTransactionProcessingStrategyId(), product.getAmortizationType(),
|
||||||
product.getInterestRatePerPeriod(), product.getInterestRateFrequencyType(), product.getInterestType(), product.getInterestCalculationPeriodType(),
|
product.getInterestRatePerPeriod(), product.getInterestRateFrequencyType(), product.getInterestType(), product.getInterestCalculationPeriodType(),
|
||||||
loanAccount.expectedDisbursementDate, product.getCharges());
|
loanAccount.expectedDisbursementDate, charges);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanBasicDetailsData(
|
private LoanBasicDetailsData(
|
||||||
@@ -89,7 +96,7 @@ public class LoanBasicDetailsData {
|
|||||||
final EnumOptionData interestRateFrequencyType,
|
final EnumOptionData interestRateFrequencyType,
|
||||||
final EnumOptionData interestType,
|
final EnumOptionData interestType,
|
||||||
final EnumOptionData interestCalculationPeriodType,
|
final EnumOptionData interestCalculationPeriodType,
|
||||||
final LocalDate expectedDisbursementDate, final Collection<ChargeData> charges) {
|
final LocalDate expectedDisbursementDate, final Collection<LoanChargeData> charges) {
|
||||||
this.id = null;
|
this.id = null;
|
||||||
this.externalId = null;
|
this.externalId = null;
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
@@ -219,7 +226,7 @@ public class LoanBasicDetailsData {
|
|||||||
final Integer termFrequency,
|
final Integer termFrequency,
|
||||||
final EnumOptionData termPeriodFrequencyType,
|
final EnumOptionData termPeriodFrequencyType,
|
||||||
final Integer transactionStrategyId,
|
final Integer transactionStrategyId,
|
||||||
final Collection<ChargeData> charges,
|
final Collection<LoanChargeData> charges,
|
||||||
final Long loanOfficerId, String loanOfficerName) {
|
final Long loanOfficerId, String loanOfficerName) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.externalId = externalId;
|
this.externalId = externalId;
|
||||||
@@ -490,7 +497,7 @@ public class LoanBasicDetailsData {
|
|||||||
return transactionStrategyId;
|
return transactionStrategyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<ChargeData> getCharges() {
|
public Collection<LoanChargeData> getCharges() {
|
||||||
return charges;
|
return charges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package org.mifosng.platform.api.data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immutable data object for loan charge data.
|
||||||
|
*/
|
||||||
|
public class LoanChargeData {
|
||||||
|
|
||||||
|
private final Long id;
|
||||||
|
private final Long chargeId;
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final CurrencyData currency;
|
||||||
|
|
||||||
|
private final BigDecimal amount;
|
||||||
|
private final EnumOptionData chargeTimeType;
|
||||||
|
private final EnumOptionData chargeCalculationType;
|
||||||
|
|
||||||
|
public LoanChargeData(Long id, Long chargeId, String name, CurrencyData currency, BigDecimal amount,
|
||||||
|
EnumOptionData chargeTimeType, EnumOptionData chargeCalculationType) {
|
||||||
|
this.id = id;
|
||||||
|
this.chargeId = chargeId;
|
||||||
|
this.name = name;
|
||||||
|
this.currency = currency;
|
||||||
|
this.amount = amount;
|
||||||
|
this.chargeTimeType = chargeTimeType;
|
||||||
|
this.chargeCalculationType = chargeCalculationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getChargeId() {
|
||||||
|
return chargeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CurrencyData getCurrency() {
|
||||||
|
return currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnumOptionData getChargeTimeType() {
|
||||||
|
return chargeTimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnumOptionData getChargeCalculationType() {
|
||||||
|
return chargeCalculationType;
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
-18
@@ -497,25 +497,19 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
|
|||||||
charges = new LoanChargeCommand[array.size()];
|
charges = new LoanChargeCommand[array.size()];
|
||||||
for (int i=0; i<array.size(); i++) {
|
for (int i=0; i<array.size(); i++) {
|
||||||
JsonObject loanCharge = array.get(i).getAsJsonObject();
|
JsonObject loanCharge = array.get(i).getAsJsonObject();
|
||||||
|
Map<String, Object> chargeRequestMap = gsonConverter.fromJson(loanCharge, typeOfMap);
|
||||||
|
if (requestMap.containsKey("locale")){
|
||||||
|
chargeRequestMap.put("locale", requestMap.get("locale"));
|
||||||
|
}
|
||||||
Set<String> chargeModifiedParameters = new HashSet<String>();
|
Set<String> chargeModifiedParameters = new HashSet<String>();
|
||||||
Long id = loanCharge.get("id").getAsLong();
|
|
||||||
BigDecimal amount = null;
|
|
||||||
Integer chargeTimeType = null;
|
|
||||||
Integer chargeCalculationType = null;
|
|
||||||
|
|
||||||
if (loanCharge.has("amount")){
|
Long chargeId = extractLongParameter("chargeId", chargeRequestMap, chargeModifiedParameters);
|
||||||
chargeModifiedParameters.add("amount");
|
BigDecimal amount = extractBigDecimalParameter("amount", chargeRequestMap, chargeModifiedParameters);
|
||||||
amount = convertFrom(loanCharge.get("amount").getAsString(), "amount", extractLocaleValue(requestMap));
|
Integer chargeTimeType = extractIntegerParameter("chargeTimeType", chargeRequestMap, chargeModifiedParameters);
|
||||||
}
|
Integer chargeCalculationType = extractIntegerParameter("chargeCalculationType", chargeRequestMap, chargeModifiedParameters);
|
||||||
if (loanCharge.has("chargeTimeType")){
|
|
||||||
chargeModifiedParameters.add("chargeTimeType");
|
charges[i] = new LoanChargeCommand(chargeModifiedParameters, null, chargeId, amount,
|
||||||
chargeTimeType = loanCharge.get("chargeTimeType").getAsInt();
|
chargeTimeType, chargeCalculationType);
|
||||||
}
|
|
||||||
if (loanCharge.has("chargeCalculationType")){
|
|
||||||
chargeModifiedParameters.add("chargeCalculationType");
|
|
||||||
chargeCalculationType = loanCharge.get("chargeCalculationType").getAsInt();
|
|
||||||
}
|
|
||||||
charges[i] = new LoanChargeCommand(chargeModifiedParameters, id, amount, chargeTimeType, chargeCalculationType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -709,7 +703,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
|
|||||||
}
|
}
|
||||||
return paramValue;
|
return paramValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean extractBooleanParameter(final String paramName, final Map<String, ?> requestMap, final Set<String> modifiedParameters) {
|
private boolean extractBooleanParameter(final String paramName, final Map<String, ?> requestMap, final Set<String> modifiedParameters) {
|
||||||
boolean paramValue = false;
|
boolean paramValue = false;
|
||||||
String paramValueAsString = null;
|
String paramValueAsString = null;
|
||||||
|
|||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
package org.mifosng.platform.charge.service;
|
package org.mifosng.platform.charge.service;
|
||||||
|
|
||||||
import org.mifosng.platform.api.data.ChargeData;
|
import org.mifosng.platform.api.data.ChargeData;
|
||||||
|
import org.mifosng.platform.api.data.LoanChargeData;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ public interface ChargeReadPlatformService {
|
|||||||
|
|
||||||
Collection<ChargeData> retrieveLoanProductCharges(Long loanProductId);
|
Collection<ChargeData> retrieveLoanProductCharges(Long loanProductId);
|
||||||
|
|
||||||
Collection<ChargeData> retrieveLoanCharges(Long loanId);
|
Collection<LoanChargeData> retrieveLoanCharges(Long loanId);
|
||||||
|
|
||||||
ChargeData retrieveLoanChargeTemplate();
|
ChargeData retrieveLoanChargeTemplate();
|
||||||
}
|
}
|
||||||
|
|||||||
+42
-11
@@ -3,6 +3,7 @@ package org.mifosng.platform.charge.service;
|
|||||||
import org.mifosng.platform.api.data.ChargeData;
|
import org.mifosng.platform.api.data.ChargeData;
|
||||||
import org.mifosng.platform.api.data.CurrencyData;
|
import org.mifosng.platform.api.data.CurrencyData;
|
||||||
import org.mifosng.platform.api.data.EnumOptionData;
|
import org.mifosng.platform.api.data.EnumOptionData;
|
||||||
|
import org.mifosng.platform.api.data.LoanChargeData;
|
||||||
import org.mifosng.platform.charge.domain.ChargeAppliesTo;
|
import org.mifosng.platform.charge.domain.ChargeAppliesTo;
|
||||||
import org.mifosng.platform.charge.domain.ChargeCalculationType;
|
import org.mifosng.platform.charge.domain.ChargeCalculationType;
|
||||||
import org.mifosng.platform.charge.domain.ChargeTimeType;
|
import org.mifosng.platform.charge.domain.ChargeTimeType;
|
||||||
@@ -106,10 +107,10 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ChargeData> retrieveLoanCharges(Long loanId) {
|
public Collection<LoanChargeData> retrieveLoanCharges(Long loanId) {
|
||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
ChargeMapper rm = new ChargeMapper();
|
LoanChargeMapper rm = new LoanChargeMapper();
|
||||||
|
|
||||||
String sql = "select " + rm.loanChargeSchema() + " where c.is_deleted=0 and lc.loan_id=?";
|
String sql = "select " + rm.loanChargeSchema() + " where c.is_deleted=0 and lc.loan_id=?";
|
||||||
|
|
||||||
@@ -159,15 +160,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
|
|||||||
return chargeSchema() + " join m_product_loan_charge plc on plc.charge_id = c.id";
|
return chargeSchema() + " join m_product_loan_charge plc on plc.charge_id = c.id";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String loanChargeSchema(){
|
|
||||||
return "c.id as id, c.name as name, lc.amount as amount, c.currency_code as currencyCode, " +
|
|
||||||
"c.charge_applies_to_enum as chargeAppliesTo, lc.charge_time_enum as chargeTime, " +
|
|
||||||
"lc.charge_calculation_enum as chargeCalculation, is_active as active, oc.name as currencyName, " +
|
|
||||||
"oc.decimal_places as currencyDecimalPlaces, oc.display_symbol as currencyDisplaySymbol, " +
|
|
||||||
"oc.internationalized_name_code as currencyNameCode from m_charge c " +
|
|
||||||
"join m_organisation_currency oc on c.currency_code = oc.code " +
|
|
||||||
"join m_loan_charge lc on lc.charge_id = c.id ";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChargeData mapRow(ResultSet rs, int rowNum) throws SQLException {
|
public ChargeData mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
@@ -198,4 +191,42 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
|
|||||||
return new ChargeData(id, name, amount, currency, chargeTimeType, chargeAppliesToType, chargeCalculationType, active);
|
return new ChargeData(id, name, amount, currency, chargeTimeType, chargeAppliesToType, chargeCalculationType, active);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class LoanChargeMapper implements RowMapper<LoanChargeData> {
|
||||||
|
|
||||||
|
public String loanChargeSchema(){
|
||||||
|
return "lc.id as id, c.id as chargeId, c.name as name, lc.amount as amount, c.currency_code as currencyCode, " +
|
||||||
|
"lc.charge_time_enum as chargeTime, " +
|
||||||
|
"lc.charge_calculation_enum as chargeCalculation, oc.name as currencyName, " +
|
||||||
|
"oc.decimal_places as currencyDecimalPlaces, oc.display_symbol as currencyDisplaySymbol, " +
|
||||||
|
"oc.internationalized_name_code as currencyNameCode from m_charge c " +
|
||||||
|
"join m_organisation_currency oc on c.currency_code = oc.code " +
|
||||||
|
"join m_loan_charge lc on lc.charge_id = c.id ";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LoanChargeData mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
|
Long id = rs.getLong("id");
|
||||||
|
Long chargeId = rs.getLong("chargeId");
|
||||||
|
String name = rs.getString("name");
|
||||||
|
BigDecimal amount = rs.getBigDecimal("amount");
|
||||||
|
|
||||||
|
String currencyCode = rs.getString("currencyCode");
|
||||||
|
String currencyName = rs.getString("currencyName");
|
||||||
|
String currencyNameCode = rs.getString("currencyNameCode");
|
||||||
|
String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||||
|
Integer currencyDecimalPlaces = JdbcSupport.getInteger(rs, "currencyDecimalPlaces");
|
||||||
|
|
||||||
|
CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDecimalPlaces,
|
||||||
|
currencyDisplaySymbol, currencyNameCode);
|
||||||
|
|
||||||
|
int chargeTime = rs.getInt("chargeTime");
|
||||||
|
EnumOptionData chargeTimeType = ChargeEnumerations.chargeTimeType(chargeTime);
|
||||||
|
|
||||||
|
int chargeCalculation = rs.getInt("chargeCalculation");
|
||||||
|
EnumOptionData chargeCalculationType = ChargeEnumerations.chargeCalculationType(chargeCalculation);
|
||||||
|
|
||||||
|
return new LoanChargeData(id, chargeId, name, currency, amount, chargeTimeType, chargeCalculationType);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
package org.mifosng.platform.loan.domain;
|
package org.mifosng.platform.loan.domain;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.IdClass;
|
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
@@ -16,17 +13,20 @@ import org.mifosng.platform.api.commands.LoanChargeCommand;
|
|||||||
import org.mifosng.platform.charge.domain.Charge;
|
import org.mifosng.platform.charge.domain.Charge;
|
||||||
import org.mifosng.platform.charge.domain.ChargeCalculationType;
|
import org.mifosng.platform.charge.domain.ChargeCalculationType;
|
||||||
import org.mifosng.platform.charge.domain.ChargeTimeType;
|
import org.mifosng.platform.charge.domain.ChargeTimeType;
|
||||||
|
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@IdClass(LoanCharge.LoanChargePK.class)
|
|
||||||
@Table(name = "m_loan_charge")
|
@Table(name = "m_loan_charge")
|
||||||
public class LoanCharge {
|
public class LoanCharge extends AbstractPersistable<Long> {
|
||||||
|
|
||||||
@Id
|
@SuppressWarnings("unused")
|
||||||
|
@ManyToOne(optional = false)
|
||||||
|
@JoinColumn(name = "loan_id", referencedColumnName = "id", nullable=false)
|
||||||
private Loan loan;
|
private Loan loan;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Id
|
@ManyToOne(optional = false)
|
||||||
|
@JoinColumn(name = "charge_id", referencedColumnName = "id", nullable=false)
|
||||||
private Charge charge;
|
private Charge charge;
|
||||||
|
|
||||||
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
||||||
@@ -85,20 +85,6 @@ public class LoanCharge {
|
|||||||
this.chargeCalculation = chargeCalculation;
|
this.chargeCalculation = chargeCalculation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class LoanChargePK implements Serializable {
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
@Id
|
|
||||||
@ManyToOne(optional = false)
|
|
||||||
@JoinColumn(name = "loan_id", referencedColumnName = "id", nullable=false)
|
|
||||||
private Loan loan;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
@Id
|
|
||||||
@ManyToOne(optional = false)
|
|
||||||
@JoinColumn(name = "charge_id", referencedColumnName = "id", nullable=false)
|
|
||||||
private Charge charge;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(final Loan loan) {
|
public void update(final Loan loan) {
|
||||||
this.loan = loan;
|
this.loan = loan;
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-4
@@ -20,6 +20,7 @@ import org.mifosng.platform.exceptions.ChargeIsNotActiveException;
|
|||||||
import org.mifosng.platform.exceptions.ChargeNotFoundException;
|
import org.mifosng.platform.exceptions.ChargeNotFoundException;
|
||||||
import org.mifosng.platform.exceptions.ClientNotFoundException;
|
import org.mifosng.platform.exceptions.ClientNotFoundException;
|
||||||
import org.mifosng.platform.exceptions.FundNotFoundException;
|
import org.mifosng.platform.exceptions.FundNotFoundException;
|
||||||
|
import org.mifosng.platform.exceptions.InvalidCurrencyException;
|
||||||
import org.mifosng.platform.exceptions.LoanProductNotFoundException;
|
import org.mifosng.platform.exceptions.LoanProductNotFoundException;
|
||||||
import org.mifosng.platform.exceptions.LoanTransactionProcessingStrategyNotFoundException;
|
import org.mifosng.platform.exceptions.LoanTransactionProcessingStrategyNotFoundException;
|
||||||
import org.mifosng.platform.exceptions.StaffNotFoundException;
|
import org.mifosng.platform.exceptions.StaffNotFoundException;
|
||||||
@@ -101,7 +102,7 @@ public class LoanAssembler {
|
|||||||
Staff loanOfficer= findLoanOfficerByIdIfProvided(command.getLoanOfficerId());
|
Staff loanOfficer= findLoanOfficerByIdIfProvided(command.getLoanOfficerId());
|
||||||
|
|
||||||
// optionally, see if charges are associated with loan on creation (through loan product or by being directly added)
|
// optionally, see if charges are associated with loan on creation (through loan product or by being directly added)
|
||||||
final Set<LoanCharge> loanCharges = assembleSetOfLoanCharges(command.getCharges(), loanProduct.getCharges());
|
final Set<LoanCharge> loanCharges = assembleSetOfLoanCharges(command.getCharges(), loanProduct.getCharges(), loanProduct.getCurrency().getCode());
|
||||||
|
|
||||||
Loan loan = Loan.createNew(fund,loanOfficer, loanTransactionProcessingStrategy, loanProduct, client, loanRepaymentScheduleDetail, loanCharges);
|
Loan loan = Loan.createNew(fund,loanOfficer, loanTransactionProcessingStrategy, loanProduct, client, loanRepaymentScheduleDetail, loanCharges);
|
||||||
loan.setExternalId(command.getExternalId());
|
loan.setExternalId(command.getExternalId());
|
||||||
@@ -130,13 +131,14 @@ public class LoanAssembler {
|
|||||||
return loan;
|
return loan;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<LoanCharge> assembleSetOfLoanCharges(LoanChargeCommand[] chargesPassedAtCreation, Set<Charge> chargesInheritedFromProduct) {
|
public Set<LoanCharge> assembleSetOfLoanCharges(LoanChargeCommand[] chargesPassedAtCreation,
|
||||||
|
Set<Charge> chargesInheritedFromProduct, String loanCurrencyCode) {
|
||||||
Set<LoanCharge> loanCharges = new HashSet<LoanCharge>();
|
Set<LoanCharge> loanCharges = new HashSet<LoanCharge>();
|
||||||
|
|
||||||
if (!ObjectUtils.isEmpty(chargesPassedAtCreation)) {
|
if (!ObjectUtils.isEmpty(chargesPassedAtCreation)) {
|
||||||
for (LoanChargeCommand loanChargeCommand : chargesPassedAtCreation) {
|
for (LoanChargeCommand loanChargeCommand : chargesPassedAtCreation) {
|
||||||
|
|
||||||
Long chargeDefinitionId = loanChargeCommand.getId();
|
Long chargeDefinitionId = loanChargeCommand.getChargeId();
|
||||||
Charge chargeDefinition = this.chargeRepository.findOne(chargeDefinitionId);
|
Charge chargeDefinition = this.chargeRepository.findOne(chargeDefinitionId);
|
||||||
if (chargeDefinition == null || chargeDefinition.isDeleted()) {
|
if (chargeDefinition == null || chargeDefinition.isDeleted()) {
|
||||||
throw new ChargeNotFoundException(chargeDefinitionId);
|
throw new ChargeNotFoundException(chargeDefinitionId);
|
||||||
@@ -145,7 +147,12 @@ public class LoanAssembler {
|
|||||||
if (!chargeDefinition.isActive()) {
|
if (!chargeDefinition.isActive()) {
|
||||||
throw new ChargeIsNotActiveException(chargeDefinitionId);
|
throw new ChargeIsNotActiveException(chargeDefinitionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!loanCurrencyCode.equals(chargeDefinition.getCurrencyCode())){
|
||||||
|
String errorMessage = "Charge and Loan must have the same currency.";
|
||||||
|
throw new InvalidCurrencyException("charge", "attach.to.loan", errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
loanCharges.add(LoanCharge.createNew(chargeDefinition, loanChargeCommand));
|
loanCharges.add(LoanCharge.createNew(chargeDefinition, loanChargeCommand));
|
||||||
}
|
}
|
||||||
} else if (chargesPassedAtCreation == null) {
|
} else if (chargesPassedAtCreation == null) {
|
||||||
|
|||||||
+1
@@ -22,6 +22,7 @@ public class LoanChargeCommandValidator {
|
|||||||
|
|
||||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("charge");
|
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("charge");
|
||||||
|
|
||||||
|
baseDataValidator.reset().parameter("chargeId").value(command.getChargeId()).notNull().longGreaterThanZero();
|
||||||
baseDataValidator.reset().parameter("amount").value(command.getAmount()).ignoreIfNull().positiveAmount();
|
baseDataValidator.reset().parameter("amount").value(command.getAmount()).ignoreIfNull().positiveAmount();
|
||||||
baseDataValidator.reset().parameter("chargeTimeType").value(command.getChargeTimeType()).ignoreIfNull().inMinMaxRange(1, 1);
|
baseDataValidator.reset().parameter("chargeTimeType").value(command.getChargeTimeType()).ignoreIfNull().inMinMaxRange(1, 1);
|
||||||
baseDataValidator.reset().parameter("chargeCalculationType").value(command.getChargeCalculationType()).ignoreIfNull().inMinMaxRange(1, 4);
|
baseDataValidator.reset().parameter("chargeCalculationType").value(command.getChargeCalculationType()).ignoreIfNull().inMinMaxRange(1, 4);
|
||||||
|
|||||||
+2
-2
@@ -6,11 +6,11 @@ import java.sql.SQLException;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosng.platform.api.data.ChargeData;
|
|
||||||
import org.mifosng.platform.api.data.ClientData;
|
import org.mifosng.platform.api.data.ClientData;
|
||||||
import org.mifosng.platform.api.data.CurrencyData;
|
import org.mifosng.platform.api.data.CurrencyData;
|
||||||
import org.mifosng.platform.api.data.EnumOptionData;
|
import org.mifosng.platform.api.data.EnumOptionData;
|
||||||
import org.mifosng.platform.api.data.LoanBasicDetailsData;
|
import org.mifosng.platform.api.data.LoanBasicDetailsData;
|
||||||
|
import org.mifosng.platform.api.data.LoanChargeData;
|
||||||
import org.mifosng.platform.api.data.LoanPermissionData;
|
import org.mifosng.platform.api.data.LoanPermissionData;
|
||||||
import org.mifosng.platform.api.data.LoanProductData;
|
import org.mifosng.platform.api.data.LoanProductData;
|
||||||
import org.mifosng.platform.api.data.LoanRepaymentPeriodData;
|
import org.mifosng.platform.api.data.LoanRepaymentPeriodData;
|
||||||
@@ -403,7 +403,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
lifeCycleStatusDate = closedOnDate;
|
lifeCycleStatusDate = closedOnDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<ChargeData> charges = null;
|
Collection<LoanChargeData> charges = null;
|
||||||
return new LoanBasicDetailsData(id, externalId, clientId, clientName, clientOfficeId,
|
return new LoanBasicDetailsData(id, externalId, clientId, clientName, clientOfficeId,
|
||||||
loanProductId, loanProductName, loanProductDescription,
|
loanProductId, loanProductName, loanProductDescription,
|
||||||
fundId, fundName,
|
fundId, fundName,
|
||||||
|
|||||||
+1
-1
@@ -145,7 +145,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
Fund fund = this.loanAssembler.findFundByIdIfProvided(command.getFundId());
|
Fund fund = this.loanAssembler.findFundByIdIfProvided(command.getFundId());
|
||||||
Staff loanOfficer = this.loanAssembler.findLoanOfficerByIdIfProvided(command.getLoanOfficerId());
|
Staff loanOfficer = this.loanAssembler.findLoanOfficerByIdIfProvided(command.getLoanOfficerId());
|
||||||
LoanTransactionProcessingStrategy strategy = this.loanAssembler.findStrategyByIdIfProvided(command.getTransactionProcessingStrategyId());
|
LoanTransactionProcessingStrategy strategy = this.loanAssembler.findStrategyByIdIfProvided(command.getTransactionProcessingStrategyId());
|
||||||
Set<LoanCharge> charges = this.loanAssembler.assembleSetOfLoanCharges(command.getCharges(), loanProduct.getCharges()) ;
|
Set<LoanCharge> charges = this.loanAssembler.assembleSetOfLoanCharges(command.getCharges(), loanProduct.getCharges(), loan.getCurrency().getCode());
|
||||||
|
|
||||||
LoanSchedule loanSchedule = this.calculationPlatformService.calculateLoanSchedule(command.toCalculateLoanScheduleCommand());
|
LoanSchedule loanSchedule = this.calculationPlatformService.calculateLoanSchedule(command.toCalculateLoanScheduleCommand());
|
||||||
loan.modifyLoanApplication(command, client, loanProduct, fund, strategy, loanSchedule, charges, loanOfficer);
|
loan.modifyLoanApplication(command, client, loanProduct, fund, strategy, loanSchedule, charges, loanOfficer);
|
||||||
|
|||||||
Reference in New Issue
Block a user