FINERACT-2418: Add originators details to external business events

This commit is contained in:
mariiaKraievska
2026-02-06 09:37:36 +01:00
committed by Arnold Gálovics
parent 288038d7bb
commit c57f44d3f0
8 changed files with 714 additions and 0 deletions
@@ -22,12 +22,23 @@ import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface LoanOriginatorMappingRepository
extends JpaRepository<LoanOriginatorMapping, Long>, JpaSpecificationExecutor<LoanOriginatorMapping> {
List<LoanOriginatorMapping> findByLoanId(Long loanId);
@Query("""
SELECT m FROM LoanOriginatorMapping m
JOIN FETCH m.originator o
LEFT JOIN FETCH o.originatorType
LEFT JOIN FETCH o.channelType
WHERE m.loanId = :loanId
""")
List<LoanOriginatorMapping> findByLoanIdWithOriginatorDetails(@Param("loanId") Long loanId);
boolean existsByLoanId(Long loanId);
boolean existsByOriginatorId(Long originatorId);
@@ -0,0 +1,72 @@
/**
* 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.portfolio.loanorigination.enricher;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.avro.loan.v1.LoanAccountDataV1;
import org.apache.fineract.avro.loan.v1.OriginatorDetailsV1;
import org.apache.fineract.infrastructure.core.service.DataEnricher;
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginator;
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorMapping;
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorMappingRepository;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
@ConditionalOnProperty(value = "fineract.module.loan-origination.enabled", havingValue = "true")
public class LoanAccountDataV1OriginatorEnricher implements DataEnricher<LoanAccountDataV1> {
private final LoanOriginatorMappingRepository loanOriginatorMappingRepository;
private final LoanOriginatorAvroMapper loanOriginatorAvroMapper;
@Override
public boolean isDataTypeSupported(final Class<LoanAccountDataV1> dataType) {
return dataType.isAssignableFrom(LoanAccountDataV1.class);
}
@Override
public void enrich(final LoanAccountDataV1 data) {
if (data == null || data.getId() == null) {
return;
}
final List<LoanOriginatorMapping> mappings = loanOriginatorMappingRepository.findByLoanIdWithOriginatorDetails(data.getId());
if (mappings == null || mappings.isEmpty()) {
return;
}
final List<OriginatorDetailsV1> originators = new ArrayList<>();
for (LoanOriginatorMapping mapping : mappings) {
final LoanOriginator originator = mapping.getOriginator();
if (originator != null) {
final OriginatorDetailsV1 originatorDetails = loanOriginatorAvroMapper.toAvro(originator);
if (originatorDetails != null) {
originators.add(originatorDetails);
}
}
}
if (!originators.isEmpty()) {
data.setOriginators(originators);
}
}
}
@@ -0,0 +1,70 @@
/**
* 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.portfolio.loanorigination.enricher;
import org.apache.fineract.avro.generic.v1.CodeValueDataV1;
import org.apache.fineract.avro.loan.v1.OriginatorDetailsV1;
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
@Component
@ConditionalOnProperty(value = "fineract.module.loan-origination.enabled", havingValue = "true")
public class LoanOriginatorAvroMapper {
/**
* Converts a LoanOriginator entity to OriginatorDetailsV1 Avro
*/
public OriginatorDetailsV1 toAvro(final LoanOriginator originator) {
if (originator == null) {
return null;
}
final OriginatorDetailsV1.Builder builder = OriginatorDetailsV1.newBuilder();
builder.setId(originator.getId());
builder.setExternalId(originator.getExternalId() != null ? originator.getExternalId().getValue() : null);
builder.setName(originator.getName());
builder.setStatus(originator.getStatus() != null ? originator.getStatus().getValue() : null);
builder.setOriginatorType(mapCodeValue(originator.getOriginatorType()));
builder.setChannelType(mapCodeValue(originator.getChannelType()));
return builder.build();
}
/**
* Converts a CodeValue entity to CodeValueDataV1 Avro
*/
private CodeValueDataV1 mapCodeValue(CodeValue codeValue) {
if (codeValue == null) {
return null;
}
CodeValueDataV1.Builder builder = CodeValueDataV1.newBuilder();
builder.setId(codeValue.getId());
builder.setName(codeValue.getLabel());
builder.setPosition(codeValue.getPosition());
builder.setDescription(codeValue.getDescription());
builder.setActive(codeValue.isActive());
builder.setMandatory(codeValue.isMandatory());
return builder.build();
}
}
@@ -0,0 +1,72 @@
/**
* 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.portfolio.loanorigination.enricher;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1;
import org.apache.fineract.avro.loan.v1.OriginatorDetailsV1;
import org.apache.fineract.infrastructure.core.service.DataEnricher;
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginator;
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorMapping;
import org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorMappingRepository;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
@ConditionalOnProperty(value = "fineract.module.loan-origination.enabled", havingValue = "true")
public class LoanTransactionDataV1OriginatorEnricher implements DataEnricher<LoanTransactionDataV1> {
private final LoanOriginatorMappingRepository loanOriginatorMappingRepository;
private final LoanOriginatorAvroMapper loanOriginatorAvroMapper;
@Override
public boolean isDataTypeSupported(final Class<LoanTransactionDataV1> dataType) {
return dataType.isAssignableFrom(LoanTransactionDataV1.class);
}
@Override
public void enrich(final LoanTransactionDataV1 data) {
if (data == null || data.getLoanId() == null) {
return;
}
final List<LoanOriginatorMapping> mappings = loanOriginatorMappingRepository.findByLoanIdWithOriginatorDetails(data.getLoanId());
if (mappings == null || mappings.isEmpty()) {
return;
}
final List<OriginatorDetailsV1> originators = new ArrayList<>();
for (LoanOriginatorMapping mapping : mappings) {
final LoanOriginator originator = mapping.getOriginator();
if (originator != null) {
final OriginatorDetailsV1 originatorDetails = loanOriginatorAvroMapper.toAvro(originator);
if (originatorDetails != null) {
originators.add(originatorDetails);
}
}
}
if (!originators.isEmpty()) {
data.setOriginators(originators);
}
}
}