http://jira.mfd.msk:8088/browse/CLS-130 clearing-service
This commit is contained in:
parent
d5a7154a25
commit
ce767ceae1
16 changed files with 610 additions and 1 deletions
72
clearing-parent/clearing-service/pom.xml
Normal file
72
clearing-parent/clearing-service/pom.xml
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>clearing-parent</artifactId>
|
||||
<groupId>ru.spcex.clearing</groupId>
|
||||
<version>SPCEX-1.0.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>clearing-service</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ru.spcex.platform</groupId>
|
||||
<artifactId>platform-messaging</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.spcex.platform</groupId>
|
||||
<artifactId>platform-imdg-api-hazelcast-impl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.spcex.clearing</groupId>
|
||||
<artifactId>classes</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.spcex.platform</groupId>
|
||||
<artifactId>platform-enum</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>application.properties</exclude>
|
||||
</excludes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package ru.spcex.clearing;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class ClearingServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication app = new SpringApplication(ClearingServiceApplication.class);
|
||||
app.run(args);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package ru.spcex.clearing.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import ru.spcex.clearing.config.element.ClearingServiceSettings;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||
|
||||
@Configuration
|
||||
public class ClearingImdgConfig {
|
||||
private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) {
|
||||
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
|
||||
if (maxPoolSz > 2) {
|
||||
pool.setKeepAliveSeconds(60);
|
||||
pool.setAllowCoreThreadTimeOut(true);
|
||||
}
|
||||
pool.setCorePoolSize(maxPoolSz);
|
||||
pool.setWaitForTasksToCompleteOnShutdown(waitForCompletion);
|
||||
return pool;
|
||||
}
|
||||
|
||||
@Bean(name = "taskExecutorHazelcastClientInitializer")
|
||||
public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() {
|
||||
return createThreadPoolTaskExecutor(1, true);
|
||||
}
|
||||
|
||||
@Bean(name = "taskExecutorIdGeneratorAwaiter")
|
||||
public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter() {
|
||||
return createThreadPoolTaskExecutor(1, false);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Bean
|
||||
public ImdgProvider imdgProvider(
|
||||
@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
|
||||
@Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
|
||||
ClearingServiceSettings settings
|
||||
) {
|
||||
return new HazelcastService(taskExecutorHazelcastClientInitializer,
|
||||
taskExecutorIdGeneratorAwaiter,
|
||||
settings.getHazelcast());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package ru.spcex.clearing.config;
|
||||
|
||||
import org.apache.kafka.clients.consumer.Consumer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import ru.spcex.clearing.config.element.ClearingServiceSettings;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.config.KafkaConsumerFactory;
|
||||
import ru.spcex.clearing.platform.messaging.config.KafkaProducerFactory;
|
||||
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
|
||||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgId;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
@Configuration
|
||||
public class KafkaConfig {
|
||||
@Autowired
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
@Bean
|
||||
public Consumer<String, Object> createConsumer(ClearingServiceSettings settings) {
|
||||
return KafkaConsumerFactory.consumer(settings.getKafkaConsumer());
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Bean
|
||||
public Producer<String, Object> createProducer(ClearingServiceSettings settings) {
|
||||
return KafkaProducerFactory.producer(settings.getKafkaProducer());
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Bean
|
||||
public KafkaSender kafkaSender(Producer<String, Object> kafkaProducer, ImdgProvider imdgProvider) {
|
||||
ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator();
|
||||
return KafkaSender
|
||||
.setup()
|
||||
.producer(kafkaProducer)
|
||||
.idGenerator(imdgIdGenerator::nextId)
|
||||
.imdgProvider(s -> {
|
||||
Imdg<RequestInfo> imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class);
|
||||
return imdg::insert;
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package ru.spcex.clearing.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Configuration
|
||||
public class MessageResolverConfig {
|
||||
@Bean
|
||||
public IMessageResolver messageResolver() {
|
||||
return errorMessage -> {
|
||||
if (errorMessage == null) return "null";
|
||||
return String.format("(%d) args %s", errorMessage.getSubject().getId(), Arrays.toString(errorMessage.getArgs()));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package ru.spcex.clearing.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
import ru.spcex.platform.utils.enumeration.SpringPropertiesMessageResolver;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
//@Configuration
|
||||
public class MessagesConfig {
|
||||
@Bean("validation-error-messages")
|
||||
public ResourceBundleMessageSource messages() {
|
||||
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
|
||||
source.setBasenames("messages/error");
|
||||
source.setUseCodeAsDefaultMessage(true);
|
||||
source.setDefaultEncoding("utf8");
|
||||
source.setDefaultLocale(Locale.ROOT);
|
||||
return source;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IMessageResolver errorResolver(@Qualifier("validation-error-messages") ResourceBundleMessageSource messageBundle) {
|
||||
SpringPropertiesMessageResolver resolver = new SpringPropertiesMessageResolver(messageBundle);
|
||||
resolver.setLocale("ru");
|
||||
return resolver;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package ru.spcex.clearing.config.element;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.spcex.clearing.platform.messaging.config.element.KafkaConsumerSettings;
|
||||
import ru.spcex.clearing.platform.messaging.config.element.KafkaProducerSettings;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
|
||||
|
||||
@Component
|
||||
@PropertySource("file:${spring.config.location}/application.properties")
|
||||
@ConfigurationProperties("clearing-service")
|
||||
public class ClearingServiceSettings {
|
||||
private HazelcastClientParams hazelcast;
|
||||
private KafkaConsumerSettings kafkaConsumer;
|
||||
private KafkaProducerSettings kafkaProducer;
|
||||
|
||||
public HazelcastClientParams getHazelcast() {
|
||||
return hazelcast;
|
||||
}
|
||||
|
||||
public void setHazelcast(HazelcastClientParams hazelcast) {
|
||||
this.hazelcast = hazelcast;
|
||||
}
|
||||
|
||||
public KafkaConsumerSettings getKafkaConsumer() {
|
||||
return kafkaConsumer;
|
||||
}
|
||||
|
||||
public void setKafkaConsumer(KafkaConsumerSettings kafkaConsumer) {
|
||||
this.kafkaConsumer = kafkaConsumer;
|
||||
}
|
||||
|
||||
public KafkaProducerSettings getKafkaProducer() {
|
||||
return kafkaProducer;
|
||||
}
|
||||
|
||||
public void setKafkaProducer(KafkaProducerSettings kafkaProducer) {
|
||||
this.kafkaProducer = kafkaProducer;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package ru.spcex.clearing.error;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.IEnumId;
|
||||
|
||||
public enum ClearingError implements IEnumId {
|
||||
CompanyCreditCheck(10012L),
|
||||
CompanyDebitCheck(10013L),
|
||||
//if ever happens, ask to add
|
||||
ClearingMemberCategoryUnknown(19999L),
|
||||
;
|
||||
private final Long id;
|
||||
|
||||
ClearingError(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package ru.spcex.clearing.service;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.platform.enumeration.TransactionStatus;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgId;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@EnableScheduling
|
||||
public class ClearingService {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Imdg<PaymentInstruction> paymentImdgs;
|
||||
private final ExecutorService executor;
|
||||
private final ImdgId idGenerator;
|
||||
private final PaymentBatchProcessor senderGroupProcessor;
|
||||
|
||||
@Autowired
|
||||
public ClearingService(ImdgProvider imdgProvider, PaymentBatchProcessor senderGroupProcessor) {
|
||||
this.paymentImdgs = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
|
||||
this.idGenerator = imdgProvider.getImdgIdGenerator();
|
||||
this.senderGroupProcessor = senderGroupProcessor;
|
||||
this.executor = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
@Scheduled(cron = "${clearing-service.scheduler.check-payment-instruction}")
|
||||
public void run() {
|
||||
executor.execute(this::createSdfFromPaymentInstructionSTLD);
|
||||
}
|
||||
|
||||
private void createSdfFromPaymentInstructionSTLD() {
|
||||
//выгружаем PaymentInstructions с нужным статусом, группируем по компаниям
|
||||
Map<Long, List<PaymentInstruction>> pmtInsBySender = paymentImdgs.getCollectionObjectsByFieldValues(
|
||||
Map.of("transactionStatus", TransactionStatus.stld.getKey()))
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(PaymentInstruction::getSenderId))
|
||||
.collect(Collectors.groupingBy(PaymentInstruction::getSenderId));
|
||||
//generationId для созадаваемых Sdf03/Sdf11
|
||||
Long generationId = idGenerator.nextId();
|
||||
//результатом работы senderGroupProcessor будет Map<senderId -> PaymentBatchInfo>
|
||||
//PaymentBatchInfo содержит возможную ошибку, при необходимости отсортированные Payment
|
||||
//тип ClearingMemberCategory
|
||||
Map<Long, PaymentBatchInfo> processResults = pmtInsBySender
|
||||
.entrySet()
|
||||
.stream()
|
||||
.map(entry -> {
|
||||
Long senderId = entry.getKey();
|
||||
List<PaymentInstruction> pmtInstrcs = entry.getValue();
|
||||
return new AbstractMap.SimpleEntry<>(senderId, senderGroupProcessor.processSingleCompanyPayments(generationId, senderId, pmtInstrcs));
|
||||
})
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
|
||||
//todo export
|
||||
//set status
|
||||
|
||||
}
|
||||
|
||||
private void processSingleCompanyPayments(Long generationId, Long senderId, List<PaymentInstruction> payments) {
|
||||
log.info("processing PaymentInstruction's generationId={} senderId={} size={}", generationId, senderId, payments.size());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package ru.spcex.clearing.service;
|
||||
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.spcex.platform.enumeration.ClearingMemberCategoryD;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PaymentBatchInfo {
|
||||
private List<PaymentInstruction> fromClearingToBank;
|
||||
private List<PaymentInstruction> fromBankToClearing;
|
||||
private ClearingMemberCategoryD categoryD;
|
||||
private EnumMessage error;
|
||||
|
||||
public List<PaymentInstruction> getFromClearingToBank() {
|
||||
return fromClearingToBank;
|
||||
}
|
||||
|
||||
public void setFromClearingToBank(List<PaymentInstruction> fromClearingToBank) {
|
||||
this.fromClearingToBank = fromClearingToBank;
|
||||
}
|
||||
|
||||
public List<PaymentInstruction> getFromBankToClearing() {
|
||||
return fromBankToClearing;
|
||||
}
|
||||
|
||||
public void setFromBankToClearing(List<PaymentInstruction> fromBankToClearing) {
|
||||
this.fromBankToClearing = fromBankToClearing;
|
||||
}
|
||||
|
||||
public ClearingMemberCategoryD getCategoryD() {
|
||||
return categoryD;
|
||||
}
|
||||
|
||||
public void setCategoryD(ClearingMemberCategoryD categoryD) {
|
||||
this.categoryD = categoryD;
|
||||
}
|
||||
|
||||
public EnumMessage getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setError(EnumMessage error) {
|
||||
this.error = error;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
package ru.spcex.clearing.service;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
import ru.clearing.classes.statics.data.generated.ClearingMemberCategory;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.platform.enumeration.AccountType;
|
||||
import ru.spcex.platform.enumeration.ClearingMemberCategoryD;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Component
|
||||
public class PaymentBatchProcessor {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Imdg<ClearingMemberCategory> clrngMmbrImdg;
|
||||
private final Imdg<Account> accImdg;
|
||||
private final IMessageResolver messageResolver;
|
||||
|
||||
@Autowired
|
||||
public PaymentBatchProcessor(ImdgProvider imdgProvider, IMessageResolver messageResolver) {
|
||||
this.clrngMmbrImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
|
||||
this.accImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
|
||||
|
||||
this.messageResolver = messageResolver;
|
||||
}
|
||||
|
||||
PaymentBatchInfo processSingleCompanyPayments(Long generationId, Long senderId, List<PaymentInstruction> payments) {
|
||||
PaymentBatchInfo batchInfo = new PaymentBatchInfo();
|
||||
log.info("processing PaymentInstruction's generationId={} senderId={} size={}", generationId, senderId, payments.size());
|
||||
ClearingMemberCategory category = clrngMmbrImdg.getSingleObjectByFieldValues(Map.of("companyId", senderId));
|
||||
ClearingMemberCategoryD categoryValue;
|
||||
if (category == null || (categoryValue =
|
||||
IEnumKey.getEnumByKey(ClearingMemberCategoryD.class, category.getClearingMemberCategory())) == null) {
|
||||
log.warn("processing PaymentInstructions generationId={} senderId={}: " +
|
||||
"ClearingMemberCategory {}, ClearingMemberCategory.clearingMemberCategory {}",
|
||||
generationId, senderId,
|
||||
category == null ? "null" : "is not null",
|
||||
category == null ? "null" : category.getClearingMemberCategory()
|
||||
);
|
||||
batchInfo.setError(new EnumMessage(ClearingError.ClearingMemberCategoryUnknown));
|
||||
return batchInfo;
|
||||
}
|
||||
batchInfo.setCategoryD(categoryValue);
|
||||
if (ClearingMemberCategoryD.I.equals(categoryValue)) {
|
||||
List<PaymentInstruction> aList = new ArrayList<>();
|
||||
List<PaymentInstruction> bList = new ArrayList<>();
|
||||
for (PaymentInstruction payment : payments) {
|
||||
Account creditLegAcc = accImdg.getSingleObjectByID(payment.getCreditLegAccountId());
|
||||
Account debitLegAcc = accImdg.getSingleObjectByID(payment.getDebitLegAccountId());
|
||||
if (creditLegAcc == null || debitLegAcc == null) {
|
||||
log.warn("generationId={}, senderId={} payment.id={} cannot find account CreditLegAccountId/DebitLegAccountId {}/{}",
|
||||
generationId, senderId, payment.getId(), payment.getCreditLegAccountId(), payment.getDebitLegAccountId());
|
||||
continue;
|
||||
}
|
||||
if (AccountType.Clrn.equalsByKey(creditLegAcc.getAccountType())
|
||||
&& AccountType.Bank.equalsByKey(debitLegAcc.getAccountType())) {
|
||||
aList.add(payment);
|
||||
} else if (AccountType.Bank.equalsByKey(creditLegAcc.getAccountType())
|
||||
&& AccountType.Clrn.equalsByKey(debitLegAcc.getAccountType())) {
|
||||
bList.add(payment);
|
||||
} else {
|
||||
log.warn("generationId={} senderId={} cannot sort payment.id={}, creditLegAccount.type={}, debitLegAccount.type={}",
|
||||
generationId, senderId, payment.getId(),creditLegAcc.getAccountType(), debitLegAcc.getAccountType());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Function<List<PaymentInstruction>, Long> creditAmountSum = paymentInstructions -> paymentInstructions
|
||||
.stream()
|
||||
.map(PaymentInstruction::getCreditLegAmount)
|
||||
.reduce(0L, Long::sum);
|
||||
Function<List<PaymentInstruction>, Long> debitAmountSum = paymentInstructions -> paymentInstructions
|
||||
.stream()
|
||||
.map(PaymentInstruction::getCreditLegAmount)
|
||||
.reduce(0L, Long::sum);
|
||||
Long fromClearingToBankCreditAmount = creditAmountSum.apply(aList);
|
||||
Long fromBankToClearingCreditAmount = creditAmountSum.apply(bList);
|
||||
Long fromClearingToBankDebitAmount = debitAmountSum.apply(aList);
|
||||
Long fromBankToClearingDebitAmount = debitAmountSum.apply(bList);
|
||||
if (!fromClearingToBankCreditAmount.equals(fromBankToClearingCreditAmount)) {
|
||||
log.info("processing PaymentInstruction's generationId={} senderId={} [fromClearingToBankCreditAmount={}, " +
|
||||
"fromBankToClearingCreditAmount={}, " +
|
||||
"fromClearingToBankDebitAmount={}, " +
|
||||
"fromBankToClearingDebitAmount={}] error {}", generationId, senderId,
|
||||
fromClearingToBankCreditAmount,
|
||||
fromBankToClearingCreditAmount,
|
||||
fromClearingToBankDebitAmount,
|
||||
fromBankToClearingDebitAmount,
|
||||
messageResolver.resolve(new EnumMessage(ClearingError.CompanyCreditCheck, senderId.toString())));
|
||||
batchInfo.setError(new EnumMessage(ClearingError.CompanyCreditCheck, senderId.toString()));
|
||||
return batchInfo;
|
||||
} else if (!fromClearingToBankDebitAmount.equals(fromBankToClearingDebitAmount)) {
|
||||
log.info("processing PaymentInstruction's generationId={} senderId={} [fromClearingToBankCreditAmount={}, " +
|
||||
"fromBankToClearingCreditAmount={}, " +
|
||||
"fromClearingToBankDebitAmount={}, " +
|
||||
"fromBankToClearingDebitAmount={}] error {}", generationId, senderId,
|
||||
fromClearingToBankCreditAmount,
|
||||
fromBankToClearingCreditAmount,
|
||||
fromClearingToBankDebitAmount,
|
||||
fromBankToClearingDebitAmount,
|
||||
messageResolver.resolve(new EnumMessage(ClearingError.CompanyDebitCheck, senderId.toString())));
|
||||
batchInfo.setError(new EnumMessage(ClearingError.CompanyDebitCheck, senderId.toString()));
|
||||
return batchInfo;
|
||||
}
|
||||
log.debug("processing PaymentInstruction's generationId={} senderId={} [fromClearingToBankCreditAmount={}, " +
|
||||
"fromBankToClearingCreditAmount={}, " +
|
||||
"fromClearingToBankDebitAmount={}, " +
|
||||
"fromBankToClearingDebitAmount={}]", generationId, senderId,
|
||||
fromClearingToBankCreditAmount,
|
||||
fromBankToClearingCreditAmount,
|
||||
fromClearingToBankDebitAmount,
|
||||
fromBankToClearingDebitAmount);
|
||||
batchInfo.setFromClearingToBank(aList);
|
||||
batchInfo.setFromBankToClearing(bList);
|
||||
return batchInfo;
|
||||
} else if (ClearingMemberCategoryD.B.equals(categoryValue)) {
|
||||
return batchInfo;
|
||||
} else {
|
||||
log.warn("PaymentInstructions generationId={} senderId={} fail - unknown category ",
|
||||
generationId, senderId);
|
||||
batchInfo.setError(new EnumMessage(ClearingError.ClearingMemberCategoryUnknown));
|
||||
return batchInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
spring.main.web-application-type=none
|
||||
|
||||
clearing-service.hazelcast.cluster-members=127.0.0.1:5701
|
||||
clearing-service.hazelcast.login=dev
|
||||
clearing-service.hazelcast.password=dev-pass
|
||||
|
||||
clearing-service.kafka-consumer.bootstrap-servers=localhost:9092
|
||||
clearing-service.kafka-consumer.group-id=dev-group-clearing-service
|
||||
clearing-service.kafka-consumer.enable-auto-commit=false
|
||||
clearing-service.kafka-consumer.session-timeout-ms=30000
|
||||
clearing-service.kafka-consumer.auto-offset-reset=latest
|
||||
clearing-service.kafka-consumer.linger-ms=1
|
||||
clearing-service.kafka-consumer.buffer-memory=33554432
|
||||
|
||||
clearing-service.kafka-producer.bootstrap-servers=localhost:9092
|
||||
clearing-service.kafka-producer.acks=all
|
||||
clearing-service.kafka-producer.retries=0
|
||||
clearing-service.kafka-producer.batch-size=16384
|
||||
clearing-service.kafka-producer.linger-ms=1
|
||||
clearing-service.kafka-producer.buffer-memory=33554432
|
||||
|
||||
clearing-service.scheduler.check-payment-instruction=*/5 * * * * *
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
<module>account-service</module>
|
||||
<module>balance-service</module>
|
||||
<module>scheduler-service</module>
|
||||
<module>clearing-service</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration;
|
|||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public enum AccountType implements IEnumKey {
|
||||
Clrn("CLRN");
|
||||
Clrn("CLRN"), Bank("BANK");
|
||||
|
||||
private final String key;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
package ru.spcex.platform.enumeration;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public enum ClearingMemberCategoryD implements IEnumKey {
|
||||
I("I"), B("B");
|
||||
|
||||
private final String key;
|
||||
|
||||
ClearingMemberCategoryD(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package ru.spcex.platform.enumeration;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public enum TransactionStatus implements IEnumKey {
|
||||
stld("STLD");
|
||||
|
||||
private final String key;
|
||||
|
||||
TransactionStatus(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue