This is an automated email from the ASF dual-hosted git repository.

adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 51203b173 FINERACT-1694: Fix missing payment details data for events
51203b173 is described below

commit 51203b173f788ab60ffda089d82b7060daa6501a
Author: Adam Saghy <[email protected]>
AuthorDate: Tue Feb 7 17:02:59 2023 +0100

    FINERACT-1694: Fix missing payment details data for events
---
 .../api/LoanChargesApiResourceSwagger.java         | 14 ++++++++
 .../loanaccount/data/LoanTransactionEnumData.java  | 13 -------
 .../portfolio/loanaccount/domain/Loan.java         |  2 --
 .../domain/LoanAccountDomainService.java           |  2 +-
 .../domain/LoanAccountDomainServiceJpa.java        |  8 ++---
 .../loanaccount/domain/LoanTransaction.java        | 13 +++----
 .../serialization/LoanChargeApiJsonValidator.java  |  8 +++--
 .../LoanChargeWritePlatformServiceImpl.java        | 40 ++++++++++++++++------
 .../service/LoanReadPlatformServiceImpl.java       | 25 +++++++-------
 .../LoanWritePlatformServiceJpaRepositoryImpl.java | 21 ++++++++----
 .../paymentdetail/domain/PaymentDetail.java        |  1 +
 .../LoanDelinquencyDomainServiceTest.java          |  2 +-
 .../ClientLoanIntegrationTest.java                 |  8 +++--
 ...ccountCreditRefundPayoutWithChargebackTest.java |  8 ++++-
 14 files changed, 102 insertions(+), 63 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanChargesApiResourceSwagger.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanChargesApiResourceSwagger.java
index 17ee409a3..d222ff72d 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanChargesApiResourceSwagger.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanChargesApiResourceSwagger.java
@@ -261,6 +261,20 @@ final class LoanChargesApiResourceSwagger {
         public Double amount;
         @Schema(example = "786444UUUYYH7")
         public String externalId;
+        @Schema(example = "An optional note")
+        public String note;
+        @Schema(example = "3")
+        public Long paymentTypeId;
+        @Schema(example = "acc123")
+        public String accountNumber;
+        @Schema(example = "che123")
+        public String checkNumber;
+        @Schema(example = "rou123")
+        public String routingCode;
+        @Schema(example = "rec123")
+        public String receiptNumber;
+        @Schema(example = "ban123")
+        public String bankNumber;
     }
 
     @Schema(description = "PostLoansLoanIdChargesChargeIdResponse")
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionEnumData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionEnumData.java
index e11dcb6ea..e86183190 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionEnumData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionEnumData.java
@@ -83,19 +83,6 @@ public class LoanTransactionEnumData {
         this.chargeAdjustment = Long.valueOf(26).equals(this.id);
     }
 
-    /**
-     * Returns true if the transaction involves either a payment 
(disbursement) or a receipt (repayments, repayments
-     * during disbursement etc)
-     *
-     * @return
-     */
-    public boolean isPaymentOrReceipt() {
-        if (isDisbursement() || isRepaymentType() || 
isRepaymentAtDisbursement() || isRecoveryRepayment()) {
-            return true;
-        }
-        return false;
-    }
-
     public boolean isRepaymentType() {
         if (isRepayment() || isMerchantIssuedRefund() || isPayoutRefund() || 
isGoodwillCredit() || isChargeRefund()
                 || isChargeAdjustment()) {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
index 3e443586c..497e2c441 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
@@ -6272,8 +6272,6 @@ public class Loan extends 
AbstractAuditableWithUTCDateTimeCustom {
     public void handleChargebackTransaction(final LoanTransaction 
chargebackTransaction,
             final LoanLifecycleStateMachine loanLifecycleStateMachine) {
 
-        chargebackTransaction.updateLoan(this);
-
         if (!chargebackTransaction.isChargeback()) {
             final String errorMessage = "A transaction of type chargeback was 
expected but not received.";
             throw new InvalidLoanTransactionTypeException("transaction", 
"is.not.a.chargeback.transaction", errorMessage);
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainService.java
index d378ffc2c..e10c3a841 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainService.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainService.java
@@ -97,5 +97,5 @@ public interface LoanAccountDomainService {
     void recalculateAccruals(Loan loan, boolean isInterestCalcualtionHappened);
 
     LoanTransaction creditBalanceRefund(Loan loan, LocalDate transactionDate, 
BigDecimal transactionAmount, String noteText,
-            ExternalId externalId);
+            ExternalId externalId, PaymentDetail paymentDetail);
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
index 114040a0c..7fadb8e01 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
@@ -632,19 +632,19 @@ public class LoanAccountDomainServiceJpa implements 
LoanAccountDomainService {
 
     @Override
     public LoanTransaction creditBalanceRefund(final Loan loan, final 
LocalDate transactionDate, final BigDecimal transactionAmount,
-            final String noteText, final ExternalId externalId) {
+            final String noteText, final ExternalId externalId, PaymentDetail 
paymentDetail) {
         businessEventNotifierService.notifyPreBusinessEvent(new 
LoanCreditBalanceRefundPreBusinessEvent(loan));
         final List<Long> existingTransactionIds = new ArrayList<>();
         final List<Long> existingReversedTransactionIds = new ArrayList<>();
 
         final Money refundAmount = Money.of(loan.getCurrency(), 
transactionAmount);
-        final LoanTransaction newCreditBalanceRefundTransaction = 
LoanTransaction.creditBalanceRefund(loan, loan.getOffice(), refundAmount,
-                transactionDate, externalId);
+        LoanTransaction newCreditBalanceRefundTransaction = 
LoanTransaction.creditBalanceRefund(loan, loan.getOffice(), refundAmount,
+                transactionDate, externalId, paymentDetail);
 
         loan.creditBalanceRefund(newCreditBalanceRefundTransaction, 
defaultLoanLifecycleStateMachine, existingTransactionIds,
                 existingReversedTransactionIds);
 
-        
this.loanTransactionRepository.saveAndFlush(newCreditBalanceRefundTransaction);
+        newCreditBalanceRefundTransaction = 
this.loanTransactionRepository.saveAndFlush(newCreditBalanceRefundTransaction);
 
         if (StringUtils.isNotBlank(noteText)) {
             final Note note = Note.loanTransactionNote(loan, 
newCreditBalanceRefundTransaction, noteText);
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
index 2ae376090..3faf4c9ee 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
@@ -159,9 +159,9 @@ public class LoanTransaction extends 
AbstractAuditableWithUTCDateTimeCustom {
         return new LoanTransaction(null, office, 
LoanTransactionType.REPAYMENT, paymentDetail, amount.getAmount(), paymentDate, 
externalId);
     }
 
-    public static LoanTransaction chargeback(final Office office, final Money 
amount, final PaymentDetail paymentDetail,
+    public static LoanTransaction chargeback(final Loan loan, final Money 
amount, final PaymentDetail paymentDetail,
             final LocalDate paymentDate, final ExternalId externalId) {
-        LoanTransaction loanTransaction = new LoanTransaction(null, office, 
LoanTransactionType.CHARGEBACK, paymentDetail,
+        LoanTransaction loanTransaction = new LoanTransaction(loan, 
loan.getOffice(), LoanTransactionType.CHARGEBACK, paymentDetail,
                 amount.getAmount(), paymentDate, externalId);
         loanTransaction.principalPortion = amount.getAmount();
         return loanTransaction;
@@ -175,8 +175,9 @@ public class LoanTransaction extends 
AbstractAuditableWithUTCDateTimeCustom {
     }
 
     public static LoanTransaction chargeAdjustment(final Loan loan, final 
BigDecimal amount, final LocalDate transactionDate,
-            final ExternalId externalId) {
-        return new LoanTransaction(loan, loan.getOffice(), 
LoanTransactionType.CHARGE_ADJUSTMENT, amount, transactionDate, externalId);
+            final ExternalId externalId, PaymentDetail paymentDetail) {
+        return new LoanTransaction(loan, loan.getOffice(), 
LoanTransactionType.CHARGE_ADJUSTMENT, paymentDetail, amount, transactionDate,
+                externalId);
     }
 
     public void setLoanTransactionToRepaymentScheduleMappings(final Integer 
installmentId, final BigDecimal chargePerInstallment) {
@@ -290,9 +291,9 @@ public class LoanTransaction extends 
AbstractAuditableWithUTCDateTimeCustom {
     }
 
     public static LoanTransaction creditBalanceRefund(final Loan loan, final 
Office office, final Money amount, final LocalDate paymentDate,
-            final ExternalId externalId) {
+            final ExternalId externalId, PaymentDetail paymentDetail) {
         return new LoanTransaction(loan, office, 
LoanTransactionType.CREDIT_BALANCE_REFUND.getValue(), paymentDate, 
amount.getAmount(),
-                null, null, null, null, amount.getAmount(), false, null, 
externalId);
+                null, null, null, null, amount.getAmount(), false, 
paymentDetail, externalId);
     }
 
     public static LoanTransaction refundForActiveLoan(final Office office, 
final Money amount, final PaymentDetail paymentDetail,
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanChargeApiJsonValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanChargeApiJsonValidator.java
index 2de7cb129..f9149a9e0 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanChargeApiJsonValidator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanChargeApiJsonValidator.java
@@ -184,13 +184,14 @@ public final class LoanChargeApiJsonValidator {
         throwExceptionIfValidationWarningsExist(dataValidationErrors);
     }
 
-    public void validateLoanAdjustmentRequest(final Long loanId, final Long 
loanChargeId, final String json) {
+    public void validateLoanChargeAdjustmentRequest(final Long loanId, final 
Long loanChargeId, final String json) {
 
         if (StringUtils.isBlank(json)) {
             throw new InvalidJsonException();
         }
 
-        Set<String> transactionParameters = new HashSet<>(List.of("amount", 
"externalId", "locale"));
+        Set<String> transactionParameters = new HashSet<>(List.of("amount", 
"externalId", "locale", "paymentTypeId", "accountNumber",
+                "checkNumber", "routingCode", "receiptNumber", "bankNumber", 
"note"));
 
         final Type typeOfMap = new TypeToken<Map<String, Object>>() {
 
@@ -208,6 +209,9 @@ public final class LoanChargeApiJsonValidator {
         
baseDataValidator.reset().parameter("loanId").value(loanId).notNull().positiveAmount();
         
baseDataValidator.reset().parameter("loanChargeId").value(loanChargeId).notNull().positiveAmount();
 
+        final String note = this.fromApiJsonHelper.extractStringNamed("note", 
element);
+        
baseDataValidator.reset().parameter("note").value(note).notExceedingLengthOf(1000);
+
         throwExceptionIfValidationWarningsExist(dataValidationErrors);
     }
 
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java
index 493ec971d..bd4fbb614 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java
@@ -123,6 +123,10 @@ import 
org.apache.fineract.portfolio.loanaccount.serialization.LoanChargeApiJson
 import org.apache.fineract.portfolio.loanproduct.data.LoanOverdueDTO;
 import 
org.apache.fineract.portfolio.loanproduct.exception.InvalidCurrencyException;
 import 
org.apache.fineract.portfolio.loanproduct.exception.LinkedAccountRequiredException;
+import org.apache.fineract.portfolio.note.domain.Note;
+import org.apache.fineract.portfolio.note.domain.NoteRepository;
+import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
+import 
org.apache.fineract.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
 import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -154,6 +158,8 @@ public class LoanChargeWritePlatformServiceImpl implements 
LoanChargeWritePlatfo
     private final AccountTransferDetailRepository 
accountTransferDetailRepository;
     private final LoanChargeAssembler loanChargeAssembler;
     private final ReplayedTransactionBusinessEventService 
replayedTransactionBusinessEventService;
+    private final PaymentDetailWritePlatformService 
paymentDetailWritePlatformService;
+    private final NoteRepository noteRepository;
 
     private static boolean isPartOfThisInstallment(LoanCharge loanCharge, 
LoanRepaymentScheduleInstallment e) {
         return e.getFromDate().isBefore(loanCharge.getDueDate()) && 
!loanCharge.getDueDate().isAfter(e.getDueDate());
@@ -640,7 +646,7 @@ public class LoanChargeWritePlatformServiceImpl implements 
LoanChargeWritePlatfo
     @Transactional
     @Override
     public CommandProcessingResult adjustmentForLoanCharge(Long loanId, Long 
loanChargeId, JsonCommand command) {
-        this.loanChargeApiJsonValidator.validateLoanAdjustmentRequest(loanId, 
loanChargeId, command.json());
+        
this.loanChargeApiJsonValidator.validateLoanChargeAdjustmentRequest(loanId, 
loanChargeId, command.json());
 
         final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, 
loanChargeId);
         final LocalDate transactionDate = DateUtils.getBusinessLocalDate();
@@ -648,12 +654,22 @@ public class LoanChargeWritePlatformServiceImpl 
implements LoanChargeWritePlatfo
         final ExternalId externalId = 
externalIdFactory.createFromCommand(command, "externalId");
         final String locale = command.locale();
 
+        Map<String, Object> changes = new HashMap<>();
+        changes.put("externalId", externalId);
+        changes.put("amount", transactionAmount);
+        changes.put("transactionDate", transactionDate);
+        changes.put("locale", locale);
+
         loanChargeAdjustmentEntranceValidation(loanCharge, transactionAmount);
         final Loan loan = loanAssembler.assembleFrom(loanId);
 
         final CommandProcessingResultBuilder commandProcessingResultBuilder = 
new CommandProcessingResultBuilder();
-
-        LoanTransaction loanTransaction = applyChargeAdjustment(loan, 
loanCharge, transactionAmount, transactionDate, externalId);
+        PaymentDetail paymentDetail = 
this.paymentDetailWritePlatformService.createPaymentDetail(command, changes);
+        if (paymentDetail != null) {
+            paymentDetail = 
this.paymentDetailWritePlatformService.persistPaymentDetail(paymentDetail);
+        }
+        LoanTransaction loanTransaction = applyChargeAdjustment(loan, 
loanCharge, transactionAmount, transactionDate, externalId,
+                paymentDetail);
 
         // Update loan transaction on repayment.
         if (AccountType.fromInt(loan.getLoanType()).isIndividualAccount()) {
@@ -671,13 +687,17 @@ public class LoanChargeWritePlatformServiceImpl 
implements LoanChargeWritePlatfo
             }
             
this.loanAccountDomainService.updateLoanCollateralTransaction(loanCollateralManagements);
         }
+
+        final String noteText = command.stringValueOfParameterNamed("note");
+        if (StringUtils.isNotBlank(noteText)) {
+            final Note note = Note.loanNote(loan, noteText);
+            changes.put("note", noteText);
+            this.noteRepository.save(note);
+        }
+
         businessEventNotifierService.notifyPostBusinessEvent(new 
LoanBalanceChangedBusinessEvent(loan));
         businessEventNotifierService.notifyPostBusinessEvent(new 
LoanChargeAdjustmentPostBusinessEvent(loanTransaction));
-        Map<String, Object> changes = new HashMap<>();
-        changes.put("externalId", externalId);
-        changes.put("amount", transactionAmount);
-        changes.put("transactionDate", transactionDate);
-        changes.put("locale", locale);
+
         return 
commandProcessingResultBuilder.withCommandId(command.commandId()) //
                 .withLoanId(loanId) //
                 .withEntityId(loanChargeId) //
@@ -753,13 +773,13 @@ public class LoanChargeWritePlatformServiceImpl 
implements LoanChargeWritePlatfo
     }
 
     private LoanTransaction applyChargeAdjustment(final Loan loan, final 
LoanCharge loanCharge, final BigDecimal transactionAmount,
-            final LocalDate transactionDate, final ExternalId txnExternalId) {
+            final LocalDate transactionDate, final ExternalId txnExternalId, 
PaymentDetail paymentDetail) {
         businessEventNotifierService.notifyPreBusinessEvent(new 
LoanChargeAdjustmentPreBusinessEvent(loan));
         final List<Long> existingTransactionIds = new 
ArrayList<>(loan.findExistingTransactionIds());
         final List<Long> existingReversedTransactionIds = new 
ArrayList<>(loan.findExistingReversedTransactionIds());
 
         LoanTransaction loanChargeAdjustmentTransaction = 
LoanTransaction.chargeAdjustment(loan, transactionAmount, transactionDate,
-                txnExternalId);
+                txnExternalId, paymentDetail);
         LoanTransactionRelation loanTransactionRelation = 
LoanTransactionRelation.linkToCharge(loanChargeAdjustmentTransaction, 
loanCharge,
                 LoanTransactionRelationTypeEnum.CHARGE_ADJUSTMENT);
         
loanChargeAdjustmentTransaction.getLoanTransactionRelations().add(loanTransactionRelation);
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
index 7b587c043..0cf51c28e 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
@@ -1386,20 +1386,19 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService {
 
             PaymentDetailData paymentDetailData = null;
 
-            if (transactionType.isPaymentOrReceipt()) {
-                final Long paymentTypeId = JdbcSupport.getLong(rs, 
"paymentType");
-                if (paymentTypeId != null) {
-                    final String typeName = rs.getString("paymentTypeName");
-                    final PaymentTypeData paymentType = 
PaymentTypeData.instance(paymentTypeId, typeName);
-                    final String accountNumber = rs.getString("accountNumber");
-                    final String checkNumber = rs.getString("checkNumber");
-                    final String routingCode = rs.getString("routingCode");
-                    final String receiptNumber = rs.getString("receiptNumber");
-                    final String bankNumber = rs.getString("bankNumber");
-                    paymentDetailData = new PaymentDetailData(id, paymentType, 
accountNumber, checkNumber, routingCode, receiptNumber,
-                            bankNumber);
-                }
+            final Long paymentTypeId = JdbcSupport.getLong(rs, "paymentType");
+            if (paymentTypeId != null) {
+                final String typeName = rs.getString("paymentTypeName");
+                final PaymentTypeData paymentType = 
PaymentTypeData.instance(paymentTypeId, typeName);
+                final String accountNumber = rs.getString("accountNumber");
+                final String checkNumber = rs.getString("checkNumber");
+                final String routingCode = rs.getString("routingCode");
+                final String receiptNumber = rs.getString("receiptNumber");
+                final String bankNumber = rs.getString("bankNumber");
+                paymentDetailData = new PaymentDetailData(id, paymentType, 
accountNumber, checkNumber, routingCode, receiptNumber,
+                        bankNumber);
             }
+
             final LocalDate date = JdbcSupport.getLocalDate(rs, "date");
             final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, 
"submittedOnDate");
             final BigDecimal totalAmount = 
JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "total");
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
index a6a358fdb..53400439a 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
@@ -1256,20 +1256,21 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
         changes.put("paymentTypeId", 
command.longValueOfParameterNamed(LoanApiConstants.PAYMENT_TYPE_PARAMNAME));
 
         final Money transactionAmountAsMoney = Money.of(loan.getCurrency(), 
transactionAmount);
-        final PaymentDetail paymentDetail = 
this.paymentDetailWritePlatformService.createPaymentDetail(command, changes);
-        LoanTransaction newTransaction = 
LoanTransaction.chargeback(loan.getOffice(), transactionAmountAsMoney, 
paymentDetail,
-                transactionDate, txnExternalId);
+        PaymentDetail paymentDetail = 
this.paymentDetailWritePlatformService.createPaymentDetail(command, changes);
+        if (paymentDetail != null) {
+            paymentDetail = 
this.paymentDetailWritePlatformService.persistPaymentDetail(paymentDetail);
+        }
+        LoanTransaction newTransaction = LoanTransaction.chargeback(loan, 
transactionAmountAsMoney, paymentDetail, transactionDate,
+                txnExternalId);
 
         validateLoanTransactionAmountChargeBack(loanTransaction, 
newTransaction);
 
-        
this.paymentDetailWritePlatformService.persistPaymentDetail(paymentDetail);
-
         // Store the Loan Transaction Relation
         LoanTransactionRelation loanTransactionRelation = 
LoanTransactionRelation.linkToTransaction(loanTransaction, newTransaction,
                 LoanTransactionRelationTypeEnum.CHARGEBACK);
         this.loanTransactionRelationRepository.save(loanTransactionRelation);
 
-        this.loanTransactionRepository.save(newTransaction);
+        newTransaction = 
this.loanTransactionRepository.saveAndFlush(newTransaction);
 
         loan.handleChargebackTransaction(newTransaction, 
defaultLoanLifecycleStateMachine);
 
@@ -2439,9 +2440,15 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
         if (!externalId.isEmpty()) {
             changes.put(LoanApiConstants.externalIdParameterName, externalId);
         }
+        changes.put("paymentTypeId", 
command.longValueOfParameterNamed(LoanApiConstants.PAYMENT_TYPE_PARAMNAME));
+
+        PaymentDetail paymentDetail = 
this.paymentDetailWritePlatformService.createPaymentDetail(command, changes);
+        if (paymentDetail != null) {
+            paymentDetail = 
this.paymentDetailWritePlatformService.persistPaymentDetail(paymentDetail);
+        }
 
         final LoanTransaction loanTransaction = 
this.loanAccountDomainService.creditBalanceRefund(loan, transactionDate, 
transactionAmount,
-                noteText, externalId);
+                noteText, externalId, paymentDetail);
 
         return new CommandProcessingResultBuilder() //
                 .withEntityId(loanTransaction.getId()) //
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymentdetail/domain/PaymentDetail.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymentdetail/domain/PaymentDetail.java
index b737c7631..f110c6841 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymentdetail/domain/PaymentDetail.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymentdetail/domain/PaymentDetail.java
@@ -82,6 +82,7 @@ public final class PaymentDetail extends 
AbstractPersistableCustom {
         if (StringUtils.isNotBlank(bankNumber)) {
             changes.put(PaymentDetailConstants.bankNumberParamName, 
bankNumber);
         }
+        changes.put("paymentTypeId", paymentType.getId());
         final PaymentDetail paymentDetail = new PaymentDetail(paymentType, 
accountNumber, checkNumber, routingCode, receiptNumber,
                 bankNumber);
         return paymentDetail;
diff --git 
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/deliquency/LoanDelinquencyDomainServiceTest.java
 
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/deliquency/LoanDelinquencyDomainServiceTest.java
index ef48eb58a..09dfeb1fe 100644
--- 
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/deliquency/LoanDelinquencyDomainServiceTest.java
+++ 
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/deliquency/LoanDelinquencyDomainServiceTest.java
@@ -163,7 +163,7 @@ public class LoanDelinquencyDomainServiceTest {
         final Money zeroMoney = Money.zero(currency);
         LoanRepaymentScheduleInstallment installment = new 
LoanRepaymentScheduleInstallment(loan, 1, fromDate, dueDate, principal,
                 zeroAmount, zeroAmount, zeroAmount, false, new HashSet<>(), 
zeroAmount);
-        LoanTransaction loanTransaction = LoanTransaction.chargeback(null, 
Money.of(currency, principal), paymentDetail, transactionDate,
+        LoanTransaction loanTransaction = LoanTransaction.chargeback(loan, 
Money.of(currency, principal), paymentDetail, transactionDate,
                 null);
         
installment.getLoanTransactionToRepaymentScheduleMappings().add(LoanTransactionToRepaymentScheduleMapping
                 .createFrom(loanTransaction, installment, zeroMoney, 
zeroMoney, zeroMoney, zeroMoney));
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
index 3aa41f676..4745dee28 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
@@ -6169,7 +6169,8 @@ public class ClientLoanIntegrationTest {
 
             String externalId = UUID.randomUUID().toString();
             PostLoansLoanIdChargesChargeIdResponse chargeAdjustmentResponse = 
this.loanTransactionHelper.chargeAdjustment((long) loanID,
-                    (long) penalty1LoanChargeId, new 
PostLoansLoanIdChargesChargeIdRequest().amount(10.0).externalId(externalId));
+                    (long) penalty1LoanChargeId,
+                    new 
PostLoansLoanIdChargesChargeIdRequest().amount(10.0).externalId(externalId).paymentTypeId(1L));
 
             loanSchedule = 
this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec, 
loanID);
             assertEquals(2, loanSchedule.size());
@@ -6196,6 +6197,7 @@ public class ClientLoanIntegrationTest {
             assertEquals(chargeAdjustmentResponse.getSubResourceId(), 
transactionRelation.getFromLoanTransaction());
             assertEquals((long) penalty1LoanChargeId, 
transactionRelation.getToLoanCharge());
             assertEquals("CHARGE_ADJUSTMENT", 
transactionRelation.getRelationType());
+            assertEquals(1L, 
chargeAdjustmentTransaction.getPaymentDetailData().getPaymentType().getId());
 
             PostLoansLoanIdTransactionsResponse repaymentResult = 
loanTransactionHelper.makeLoanRepayment((long) loanID,
                     new PostLoansLoanIdTransactionsRequest().dateFormat("dd 
MMMM yyyy").transactionDate("06 September 2022").locale("en")
@@ -7177,7 +7179,7 @@ public class ClientLoanIntegrationTest {
             assertTrue(loanDetails.getStatus().getOverpaid());
 
             this.loanTransactionHelper.makeCreditBalanceRefund((long) loanID, 
new PostLoansLoanIdTransactionsRequest()
-                    .transactionAmount(200.0).transactionDate("10 October 
2022").dateFormat("dd MMMM yyyy").locale("en"));
+                    .transactionAmount(200.0).transactionDate("10 October 
2022").dateFormat("dd MMMM yyyy").locale("en").paymentTypeId(1L));
 
             loanDetails = this.loanTransactionHelper.getLoanDetails((long) 
loanID);
             assertTrue(loanDetails.getStatus().getClosedObligationsMet());
@@ -7198,7 +7200,7 @@ public class ClientLoanIntegrationTest {
             assertEquals(200.0, 
loanDetails.getTransactions().get(3).getOverpaymentPortion());
             assertEquals(LocalDate.of(2022, 10, 10), 
loanDetails.getTransactions().get(3).getDate());
             assertEquals(0.0, 
loanDetails.getTransactions().get(3).getOutstandingLoanBalance());
-
+            assertEquals(1L, 
loanDetails.getTransactions().get(3).getPaymentDetailData().getPaymentType().getId());
             GetJournalEntriesTransactionIdResponse 
journalEntriesForTransaction = journalEntryHelper
                     .getJournalEntries("L" + 
loanDetails.getTransactions().get(3).getId());
             List<JournalEntryTransactionItem> journalItems = 
journalEntriesForTransaction.getPageItems();
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountCreditRefundPayoutWithChargebackTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountCreditRefundPayoutWithChargebackTest.java
index d619b9d3e..1e266b071 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountCreditRefundPayoutWithChargebackTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountCreditRefundPayoutWithChargebackTest.java
@@ -32,6 +32,7 @@ import java.util.HashMap;
 import java.util.UUID;
 import org.apache.fineract.client.models.GetDelinquencyBucketsResponse;
 import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
+import 
org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse;
 import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
 import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
 import 
org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
@@ -91,9 +92,14 @@ public class LoanAccountCreditRefundPayoutWithChargebackTest 
{
                         .transactionAmount(1000.0));
 
         // Chargeback full repayment amount to add to principal balance
-        loanTransactionHelper.chargebackLoanTransaction(loanExternalIdStr, 
repaymentTransaction_1.getResourceId(),
+        PostLoansLoanIdTransactionsResponse chargebackResponse = 
loanTransactionHelper.chargebackLoanTransaction(loanExternalIdStr,
+                repaymentTransaction_1.getResourceId(),
                 new 
PostLoansLoanIdTransactionsTransactionIdRequest().locale("en").transactionAmount(1000.0).paymentTypeId(1L));
 
+        GetLoansLoanIdTransactionsTransactionIdResponse 
chargebackTransactionResponse = loanTransactionHelper
+                .getLoanTransactionDetails(chargebackResponse.getLoanId(), 
chargebackResponse.getResourceId());
+        assertEquals(1L, 
chargebackTransactionResponse.getPaymentDetailData().getPaymentType().getId());
+
         // Verify Goodwill Credit can be created with full amount
         final PostLoansLoanIdTransactionsResponse goodwillCredit_1 = 
loanTransactionHelper.makeGoodwillCredit((long) loanId,
                 new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM 
yyyy").transactionDate("8 September 2022").locale("en")

Reply via email to