Allow externalId to be provided when creating loan charges
This commit is contained in:
committed by
Aleksandar Vidakovic
parent
b387a92b13
commit
b0e37c24eb
+10
-1
@@ -81,6 +81,8 @@ public class LoanChargeData {
|
||||
|
||||
private BigDecimal amountUnrecognized;
|
||||
|
||||
private String externalId;
|
||||
|
||||
public static LoanChargeData template(final Collection<ChargeData> chargeOptions) {
|
||||
return new LoanChargeData(null, null, null, null, null, null, null, null, chargeOptions, false, null, false, false, null, null,
|
||||
null, null, null);
|
||||
@@ -103,7 +105,7 @@ public class LoanChargeData {
|
||||
final EnumOptionData chargeCalculationType, final BigDecimal percentage, final BigDecimal amountPercentageAppliedTo,
|
||||
final boolean penalty, final EnumOptionData chargePaymentMode, final boolean paid, final boolean waived, final Long loanId,
|
||||
final BigDecimal minCap, final BigDecimal maxCap, final BigDecimal amountOrPercentage,
|
||||
Collection<LoanInstallmentChargeData> installmentChargeData) {
|
||||
Collection<LoanInstallmentChargeData> installmentChargeData, final String externalId) {
|
||||
this.id = id;
|
||||
this.chargeId = chargeId;
|
||||
this.name = name;
|
||||
@@ -140,6 +142,7 @@ public class LoanChargeData {
|
||||
this.installmentChargeData = installmentChargeData;
|
||||
this.amountAccrued = null;
|
||||
this.amountUnrecognized = null;
|
||||
this.externalId = externalId;
|
||||
}
|
||||
|
||||
private LoanChargeData(final Long id, final Long chargeId, final String name, final CurrencyData currency, final BigDecimal amount,
|
||||
@@ -306,6 +309,7 @@ public class LoanChargeData {
|
||||
this.installmentChargeData = installmentChargeData;
|
||||
this.amountAccrued = chargeData.amountAccrued;
|
||||
this.amountUnrecognized = chargeData.amountUnrecognized;
|
||||
this.externalId = chargeData.externalId;
|
||||
}
|
||||
|
||||
public LoanChargeData(final Long id, final LocalDate dueAsOfDate, final BigDecimal amount, final EnumOptionData chargeCalculationType,
|
||||
@@ -440,4 +444,9 @@ public class LoanChargeData {
|
||||
public BigDecimal getAmountUnrecognized() {
|
||||
return this.amountUnrecognized;
|
||||
}
|
||||
|
||||
public String getExternalId() {
|
||||
return externalId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+20
-3
@@ -42,6 +42,7 @@ import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
@@ -57,7 +58,7 @@ import org.apache.fineract.portfolio.loanaccount.command.LoanChargeCommand;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanChargePaidDetail;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_loan_charge")
|
||||
@Table(name = "m_loan_charge", uniqueConstraints = { @UniqueConstraint(columnNames = { "external_id" }, name = "external_id") })
|
||||
public class LoanCharge extends AbstractPersistableCustom {
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
@@ -126,6 +127,9 @@ public class LoanCharge extends AbstractPersistableCustom {
|
||||
@Column(name = "is_active", nullable = false)
|
||||
private boolean active = true;
|
||||
|
||||
@Column(name = "external_id")
|
||||
private String externalId;
|
||||
|
||||
@OneToOne(mappedBy = "loancharge", cascade = CascadeType.ALL, optional = true, orphanRemoval = true, fetch = FetchType.EAGER)
|
||||
private LoanOverdueInstallmentCharge overdueInstallmentCharge;
|
||||
|
||||
@@ -204,8 +208,11 @@ public class LoanCharge extends AbstractPersistableCustom {
|
||||
}
|
||||
}
|
||||
|
||||
return new LoanCharge(loan, chargeDefinition, amountPercentageAppliedTo, amount, chargeTime, chargeCalculation, dueDate,
|
||||
chargePaymentMode, null, loanCharge);
|
||||
LoanCharge newLoanCharge = new LoanCharge(loan, chargeDefinition, amountPercentageAppliedTo, amount, chargeTime, chargeCalculation,
|
||||
dueDate, chargePaymentMode, null, loanCharge);
|
||||
final String externalId = command.stringValueOfParameterNamedAllowingNull("externalId");
|
||||
newLoanCharge.setExternalId(externalId);
|
||||
return newLoanCharge;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -264,6 +271,7 @@ public class LoanCharge extends AbstractPersistableCustom {
|
||||
if (chargePaymentMode != null) {
|
||||
this.chargePaymentMode = chargePaymentMode.getValue();
|
||||
}
|
||||
|
||||
populateDerivedFields(loanPrincipal, chargeAmount, numberOfRepayments, loanCharge);
|
||||
this.paid = determineIfFullyPaid();
|
||||
}
|
||||
@@ -1070,4 +1078,13 @@ public class LoanCharge extends AbstractPersistableCustom {
|
||||
public void undoWaived() {
|
||||
this.waived = false;
|
||||
}
|
||||
|
||||
public String getExternalId() {
|
||||
return externalId;
|
||||
}
|
||||
|
||||
public void setExternalId(String externalId) {
|
||||
this.externalId = externalId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+32
-2
@@ -22,8 +22,13 @@ import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -31,6 +36,8 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
@CommandType(entity = "LOANCHARGE", action = "CREATE")
|
||||
public class AddLoanChargeCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AddLoanChargeCommandHandler.class);
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
@@ -41,7 +48,30 @@ public class AddLoanChargeCommandHandler implements NewCommandSourceHandler {
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
return this.writePlatformService.addLoanCharge(command.getLoanId(), command);
|
||||
try {
|
||||
return this.writePlatformService.addLoanCharge(command.getLoanId(), command);
|
||||
} catch (final JpaSystemException | DataIntegrityViolationException dve) {
|
||||
handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) {
|
||||
|
||||
if (realCause.getMessage().contains("external_id")) {
|
||||
|
||||
final String externalId = command.stringValueOfParameterNamed("externalId");
|
||||
throw new PlatformDataIntegrityException("error.msg.loan.charge.duplicate.externalId",
|
||||
"Loan Charge with externalId `" + externalId + "` already exists", "externalId", externalId);
|
||||
}
|
||||
|
||||
logAsErrorUnexpectedDataIntegrityException(dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.loan.charge.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource.");
|
||||
}
|
||||
|
||||
private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) {
|
||||
LOG.error("Error occured.", dve);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -304,7 +304,8 @@ public final class LoanEventApiJsonValidator {
|
||||
throw new InvalidJsonException();
|
||||
}
|
||||
|
||||
final Set<String> disbursementParameters = new HashSet<>(Arrays.asList("chargeId", "amount", "dueDate", "locale", "dateFormat"));
|
||||
final Set<String> disbursementParameters = new HashSet<>(
|
||||
Arrays.asList("chargeId", "amount", "dueDate", "locale", "dateFormat", "externalId"));
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, disbursementParameters);
|
||||
|
||||
+5
-4
@@ -68,9 +68,9 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
|
||||
private static final class LoanChargeMapper implements RowMapper<LoanChargeData> {
|
||||
|
||||
public String schema() {
|
||||
return "lc.id as id, c.id as chargeId, c.name as name, " + "lc.amount as amountDue, " + "lc.amount_paid_derived as amountPaid, "
|
||||
+ "lc.amount_waived_derived as amountWaived, " + "lc.amount_writtenoff_derived as amountWrittenOff, "
|
||||
+ "lc.amount_outstanding_derived as amountOutstanding, "
|
||||
return "lc.id as id, lc.external_id as externalId, c.id as chargeId, c.name as name, " + "lc.amount as amountDue, "
|
||||
+ "lc.amount_paid_derived as amountPaid, " + "lc.amount_waived_derived as amountWaived, "
|
||||
+ "lc.amount_writtenoff_derived as amountWrittenOff, " + "lc.amount_outstanding_derived as amountOutstanding, "
|
||||
+ "lc.calculation_percentage as percentageOf, lc.calculation_on_amount as amountPercentageAppliedTo, "
|
||||
+ "lc.charge_time_enum as chargeTime, " + "lc.is_penalty as penalty, "
|
||||
+ "lc.due_for_collection_as_of_date as dueAsOfDate, " + "lc.charge_calculation_enum as chargeCalculation, "
|
||||
@@ -130,10 +130,11 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
|
||||
if (disbursementDate != null) {
|
||||
dueAsOfDate = disbursementDate;
|
||||
}
|
||||
final String externalId = rs.getString("externalId");
|
||||
|
||||
return new LoanChargeData(id, chargeId, name, currency, amount, amountPaid, amountWaived, amountWrittenOff, amountOutstanding,
|
||||
chargeTimeType, dueAsOfDate, chargeCalculationType, percentageOf, amountPercentageAppliedTo, penalty, paymentMode, paid,
|
||||
waived, null, minCap, maxCap, amountOrPercentage, null);
|
||||
waived, null, minCap, maxCap, amountOrPercentage, null, externalId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,4 +27,5 @@
|
||||
<include file="parts/0005_savings_transaction_reversal.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0006_product_loan_disallow_expected_disbursements.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0007_product_loan_higher_than_applied_loan_amount_management.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0008_loan_charge_add_external_id.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
<changeSet author="fineract" id="1">
|
||||
<addColumn tableName="m_loan_charge">
|
||||
<column name="external_id" type="VARCHAR(100)">
|
||||
<constraints unique="true"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
Reference in New Issue
Block a user