Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "WorkingCapitalLoanTransactionAdjustmentDataV1",
"namespace": "org.apache.fineract.avro.workingcapitalloan.v1",
"type": "record",
"fields": [
{
"default": null,
"name": "transactionToAdjust",
"type": [
"null",
"org.apache.fineract.avro.workingcapitalloan.v1.WorkingCapitalLoanTransactionDataV1"
]
},
{
"default": null,
"name": "newTransactionDetail",
"type": [
"null",
"org.apache.fineract.avro.workingcapitalloan.v1.WorkingCapitalLoanTransactionDataV1"
]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"name": "type",
"type": [
"null",
"org.apache.fineract.avro.loan.v1.LoanTransactionEnumDataV1"
"org.apache.fineract.avro.generic.v1.StringEnumOptionDataV1"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public interface BusinessEventNotifierService {
*/
void notifyPostBusinessEvent(BusinessEvent<?> businessEvent);

boolean isExternalEventPostingEnabled(BusinessEvent<?> businessEvent);

/**
* Method is to register a class as listener for pre-processing of any Business event
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,27 +90,30 @@ public <T extends BusinessEvent<?>> void addPreBusinessEventListener(Class<T> ev
@Override
public void notifyPostBusinessEvent(BusinessEvent<?> businessEvent) {
throwExceptionIfBulkEvent(businessEvent);
boolean isExternalEvent = !(businessEvent instanceof NoExternalEvent);
List<BusinessEventListener> businessEventListeners = findSuitableListeners(postListeners, businessEvent.getClass());
for (BusinessEventListener eventListener : businessEventListeners) {
eventListener.onBusinessEvent(businessEvent);
}
if (isExternalEvent && isExternalEventPostingEnabled()) {
// we only want to create external events for operations that were successful, hence the post listener
if (externalBusinessEventConfigurationService.isExternalEventConfiguredForPosting(businessEvent)) {
if (isExternalEventRecordingEnabled()) {
recordedEvents.get().add(businessEvent);
// we only want to create external events for operations that were successful, hence the post listener
if (isExternalEventPostingEnabled(businessEvent)) {
if (isExternalEventRecordingEnabled()) {
recordedEvents.get().add(businessEvent);
} else {
if (transactionHelper.hasTransaction()) {
storeTransactionalBusinessEvent(businessEvent);
} else {
if (transactionHelper.hasTransaction()) {
storeTransactionalBusinessEvent(businessEvent);
} else {
externalEventService.postEvent(businessEvent);
}
externalEventService.postEvent(businessEvent);
}
}
}
}

@Override
public boolean isExternalEventPostingEnabled(final BusinessEvent<?> businessEvent) {
return !(businessEvent instanceof NoExternalEvent) && isExternalEventPostingEnabled()
&& externalBusinessEventConfigurationService.isExternalEventConfiguredForPosting(businessEvent);
}

private List<BusinessEventListener> findSuitableListeners(Map<Class, List<BusinessEventListener>> listeners, Class<?> eventClazz) {
List<BusinessEventListener> result = new ArrayList<>();
for (Map.Entry<Class, List<BusinessEventListener>> entry : listeners.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,8 @@ For a loan that was charged off, the mirrors flip the reclassification instead:

== Business Events

* `WorkingCapitalLoanWrittenOffBusinessEvent` — emitted after a write-off.
* `WorkingCapitalLoanUndoWrittenOffBusinessEvent` — emitted after an undo write-off.
* `WorkingCapitalLoanWriteOffTransactionBusinessEvent` — emitted after a write-off.
* `WorkingCapitalLoanUndoWriteOffTransactionBusinessEvent` — emitted after an undo write-off.
* `WorkingCapitalLoanBalanceChangedBusinessEvent` — emitted by both operations, since the write-off zeroes the
outstanding balance and the undo restores it.
* `WorkingCapitalLoanStatusChangedBusinessEvent` — emitted by both operations, for the transition to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.apache.fineract.avro.workingcapitalloan.v1.WorkingCapitalLoanDelinquencyScheduleTagDataV1;
import org.apache.fineract.avro.workingcapitalloan.v1.WorkingCapitalLoanJournalEntryDataV1;
import org.apache.fineract.avro.workingcapitalloan.v1.WorkingCapitalLoanSummaryDataV1;
import org.apache.fineract.avro.workingcapitalloan.v1.WorkingCapitalLoanTransactionAdjustmentDataV1;
import org.apache.fineract.avro.workingcapitalloan.v1.WorkingCapitalLoanTransactionDataV1;
import org.apache.fineract.client.feign.FineractFeignClient;
import org.apache.fineract.client.models.ExternalTransferData;
Expand Down Expand Up @@ -149,6 +150,10 @@
import org.apache.fineract.test.messaging.event.workingcapitalloan.loan.WorkingCapitalLoanUndoChargeOffEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.loan.WorkingCapitalLoanUndoDisbursalEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.AbstractWorkingCapitalLoanTransactionEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanAccrualAdjustmentTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanAccrualTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanAdjustTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanChargeAdjustmentTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanChargeOffTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanCreditBalanceRefundTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanDisbursalTransactionBusinessEvent;
Expand All @@ -159,8 +164,9 @@
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanGoodwillCreditTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanPayoutRefundTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanRepaymentTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanTransactionReversedBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanUndoDisbursalTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanUndoWriteOffTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanWriteOffTransactionBusinessEvent;
import org.apache.fineract.test.messaging.store.EventStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -418,6 +424,7 @@ private void workingCapitalLoanTransactionEventCheck(final Class<? extends Abstr
.extractingData(WorkingCapitalLoanTransactionDataV1::getWcLoanId).isEqualTo(loanId)//
.extractingBigDecimal(WorkingCapitalLoanTransactionDataV1::getTransactionAmount)
.isEqualTo(expectedAmount == null ? transaction.getTransactionAmount() : expectedAmount)//
.extractingData(data -> data.getType().getCode()).isEqualTo(transaction.getType().getCode())//
.extractingData(WorkingCapitalLoanTransactionDataV1::getReversed).isEqualTo(expectedReversed);
}

Expand Down Expand Up @@ -1165,11 +1172,70 @@ public void workingCapitalLoanGoodwillCreditTransactionEventCheck(final Long loa
expectedAmount, false);
}

public void workingCapitalLoanTransactionReversedEventCheck(final Long loanId, final String transactionType) {
public void workingCapitalLoanAdjustTransactionReversalEventCheck(final Long loanId, final String transactionType) {
waitForTransactionCommit();
final GetWorkingCapitalLoanTransactionIdResponse transaction = findLastWorkingCapitalLoanTransaction(loanId, transactionType, true,
"Reversed " + transactionType + " transaction not found");
workingCapitalLoanTransactionEventCheck(WorkingCapitalLoanTransactionReversedBusinessEvent.class, loanId, transaction, null, true);
eventAssertion.assertEvent(WorkingCapitalLoanAdjustTransactionBusinessEvent.class, transaction.getId())//
.extractingData(data -> data.getTransactionToAdjust().getWcLoanId()).isEqualTo(loanId)//
.extractingBigDecimal(data -> data.getTransactionToAdjust().getTransactionAmount())
.isEqualTo(transaction.getTransactionAmount())//
.extractingData(data -> data.getTransactionToAdjust().getType().getCode()).isEqualTo(transaction.getType().getCode())//
.extractingData(data -> data.getTransactionToAdjust().getReversed()).isEqualTo(true)//
.extractingData(WorkingCapitalLoanTransactionAdjustmentDataV1::getNewTransactionDetail).isEqualTo(null);
}

public void workingCapitalLoanAdjustTransactionReprocessEventCheck(final Long loanId, final String transactionType,
final String transactionDate, final BigDecimal previousPrincipalPortion, final BigDecimal newPrincipalPortion,
final BigDecimal previousFeeChargesPortion, final BigDecimal newFeeChargesPortion) {
final GetWorkingCapitalLoanTransactionIdResponse transaction = workingCapitalLoanTransactionDetails(loanId, transactionType,
transactionDate);
eventAssertion.assertEvent(WorkingCapitalLoanAdjustTransactionBusinessEvent.class, transaction.getId())//
.extractingData(data -> data.getTransactionToAdjust().getWcLoanId()).isEqualTo(loanId)//
.extractingBigDecimal(data -> data.getTransactionToAdjust().getPrincipalPortion()).isEqualTo(previousPrincipalPortion)//
.extractingBigDecimal(data -> data.getTransactionToAdjust().getFeeChargesPortion()).isEqualTo(previousFeeChargesPortion)//
.extractingBigDecimal(data -> data.getNewTransactionDetail().getPrincipalPortion()).isEqualTo(newPrincipalPortion)//
.extractingBigDecimal(data -> data.getNewTransactionDetail().getFeeChargesPortion()).isEqualTo(newFeeChargesPortion);
}

public void workingCapitalLoanAccrualTransactionEventCheck(final Long loanId, final BigDecimal expectedAmount) {
waitForTransactionCommit();
final GetWorkingCapitalLoanTransactionIdResponse transaction = findLastWorkingCapitalLoanTransaction(loanId, "accrual", false,
"Accrual transaction not found");
workingCapitalLoanTransactionEventCheck(WorkingCapitalLoanAccrualTransactionBusinessEvent.class, loanId, transaction,
expectedAmount, false);
}

public void workingCapitalLoanAccrualAdjustmentTransactionEventCheck(final Long loanId, final BigDecimal expectedAmount) {
waitForTransactionCommit();
final GetWorkingCapitalLoanTransactionIdResponse transaction = findLastWorkingCapitalLoanTransaction(loanId, "accrual", true,
"Reversed accrual transaction not found");
workingCapitalLoanTransactionEventCheck(WorkingCapitalLoanAccrualAdjustmentTransactionBusinessEvent.class, loanId, transaction,
expectedAmount, true);
}

public void workingCapitalLoanWriteOffTransactionEventCheck(final Long loanId, final BigDecimal expectedAmount) {
waitForTransactionCommit();
final GetWorkingCapitalLoanTransactionIdResponse transaction = findLastWorkingCapitalLoanTransaction(loanId, "writeOff", false,
"Write-off transaction not found");
workingCapitalLoanTransactionEventCheck(WorkingCapitalLoanWriteOffTransactionBusinessEvent.class, loanId, transaction,
expectedAmount, false);
}

public void workingCapitalLoanUndoWriteOffTransactionEventCheck(final Long loanId, final BigDecimal expectedAmount) {
waitForTransactionCommit();
final GetWorkingCapitalLoanTransactionIdResponse transaction = findLastWorkingCapitalLoanTransaction(loanId, "writeOff", true,
"Reversed write-off transaction not found");
workingCapitalLoanTransactionEventCheck(WorkingCapitalLoanUndoWriteOffTransactionBusinessEvent.class, loanId, transaction,
expectedAmount, true);
}

public void workingCapitalLoanChargeAdjustmentTransactionEventCheck(final Long loanId, final BigDecimal expectedAmount) {
waitForTransactionCommit();
final GetWorkingCapitalLoanTransactionIdResponse transaction = findLastWorkingCapitalLoanTransaction(loanId, "chargeAdjustment",
false, "Charge adjustment transaction not found");
workingCapitalLoanTransactionEventCheck(WorkingCapitalLoanChargeAdjustmentTransactionBusinessEvent.class, loanId, transaction,
expectedAmount, false);
}

public void workingCapitalLoanChargeOffTransactionEventCheck(final Long loanId, final BigDecimal expectedAmount) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.event.business.domain.workingcapitalloan.transaction;
package org.apache.fineract.test.messaging.event.workingcapitalloan.transaction;

import org.apache.fineract.portfolio.workingcapitalloan.domain.WorkingCapitalLoanTransaction;

public class WorkingCapitalLoanTransactionReversedBusinessEvent extends WorkingCapitalLoanTransactionBusinessEvent {

private static final String TYPE = "WorkingCapitalLoanTransactionReversedBusinessEvent";

public WorkingCapitalLoanTransactionReversedBusinessEvent(final WorkingCapitalLoanTransaction value, final Long aggregateRootId) {
super(value, aggregateRootId);
}
public class WorkingCapitalLoanAccrualAdjustmentTransactionBusinessEvent extends AbstractWorkingCapitalLoanTransactionEvent {

@Override
public String getType() {
return TYPE;
public String getEventName() {
return "WorkingCapitalLoanAccrualAdjustmentTransactionBusinessEvent";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* 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.
*/
package org.apache.fineract.test.messaging.event.workingcapitalloan.transaction;

public class WorkingCapitalLoanAccrualTransactionBusinessEvent extends AbstractWorkingCapitalLoanTransactionEvent {

@Override
public String getEventName() {
return "WorkingCapitalLoanAccrualTransactionBusinessEvent";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* 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.
*/
package org.apache.fineract.test.messaging.event.workingcapitalloan.transaction;

import java.util.function.Function;
import org.apache.fineract.avro.workingcapitalloan.v1.WorkingCapitalLoanTransactionAdjustmentDataV1;
import org.apache.fineract.test.messaging.event.Event;

public class WorkingCapitalLoanAdjustTransactionBusinessEvent implements Event<WorkingCapitalLoanTransactionAdjustmentDataV1> {

@Override
public Class<WorkingCapitalLoanTransactionAdjustmentDataV1> getDataClass() {
return WorkingCapitalLoanTransactionAdjustmentDataV1.class;
}

@Override
public Function<WorkingCapitalLoanTransactionAdjustmentDataV1, Long> getIdExtractor() {
return data -> data.getTransactionToAdjust().getId();
}

@Override
public String getEventName() {
return "WorkingCapitalLoanAdjustTransactionBusinessEvent";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* 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.
*/
package org.apache.fineract.test.messaging.event.workingcapitalloan.transaction;

public class WorkingCapitalLoanChargeAdjustmentTransactionBusinessEvent extends AbstractWorkingCapitalLoanTransactionEvent {

@Override
public String getEventName() {
return "WorkingCapitalLoanChargeAdjustmentTransactionBusinessEvent";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* 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.
*/
package org.apache.fineract.test.messaging.event.workingcapitalloan.transaction;

public class WorkingCapitalLoanUndoWriteOffTransactionBusinessEvent extends AbstractWorkingCapitalLoanTransactionEvent {

@Override
public String getEventName() {
return "WorkingCapitalLoanUndoWriteOffTransactionBusinessEvent";
}
}
Loading
Loading