ialbert 2022-11-01 16:31:48 +03:00
parent 7cb1101b52
commit 15f42c96b8
3 changed files with 169 additions and 2 deletions

View file

@ -0,0 +1,167 @@
package ru.spcex.clearing.balance.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountBalance;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.sdf.SDf09;
import ru.clearing.classes.statics.data.sdf.SDf10;
import ru.clearing.classes.statics.data.statement.Statement;
import ru.spcex.clearing.balance.errors.BalanceError;
import ru.spcex.clearing.balance.validation.ValidationStored;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.platform.enumeration.*;
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.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator;
import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
@Service
public class Sdf09Executor extends AbstractExecutor<SDf09> {
private final Logger log = LoggerFactory.getLogger(getClass());
private final static DateTimeFormatter datFormatter = DateTimeFormatter.ofPattern("dd.MM.yy");
private final Imdg<Statement> statementImdg;
private final Function<SDf09, IValidator> sDf09Validator;
private final LoggingService errorLogger;
private final Imdg<SDf10> sdf10Imdg;
private final ImdgProvider imdgProvider;
private final AccountBalanceService accountBalanceService;
private final IMessageResolver errorResolver;
private final Imdg<AccountBalance> accountBalanceImdg;
public Sdf09Executor(Function<SDf09, IValidator> sDf09Validator,
LoggingService errorLogger,
ImdgProvider imdgProvider,
AccountBalanceService accountBalanceService,
IMessageResolver errorResolver) {
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
this.sdf10Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf10, SDf10.class);
this.accountBalanceImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class);;
this.sDf09Validator = sDf09Validator;
this.errorLogger = errorLogger;
this.imdgProvider = imdgProvider;
this.accountBalanceService = accountBalanceService;
this.errorResolver = errorResolver;
}
public Result execute(Collection<SDf09> sdf, StatementRequest statementRequest){
Result result = new Result();
Long generationIdForGroup = imdgProvider.getImdgIdGenerator().nextId();
result.setGenerationId(generationIdForGroup);
for (SDf09 sdf09 : sdf) {
IValidator validator = sDf09Validator.apply(sdf09);
Optional<EnumMessage> error = validator.tillFirstError();
Company company = validator.getStored(ValidationStored.Company);
if (statementRequest.getAccountCreationResults().size() == 0
&& BalanceError.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) {
//на данном шаге company существует -> getId ok
//формируем пакетный запрос на добавление account
//ответ придет в этот же метод, process
result.getAccountRequests().add(createAccountRequestPart(sdf09.getId(), sdf09.getAccount(), company.getId()));
log.info("account {} for sdf01.id={} not found - send request for creation", sdf09.getAccount(), sdf09.getId());
continue;
} else if (BalanceError.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) {
log.error("fatal error: resumed processing after generating accounts, but no account found for sdf01.id={}", sdf09.getId());
}
if (error.isPresent()) {
errorLogger.logError("sdf01.id={}", error.get(), sdf09.getId());
sdf10Imdg.insert(createErrorSdf10(sdf09, error.get(), generationIdForGroup));
continue;
}
Statement statement = statementImdg.getSingleObjectByFieldValues(Map.of("account", sdf09.getAccount()));
if (statement == null) {
statement = createFlow(sdf09,
company,
validator.getStored(ValidationStored.Account));
} else {
updateFlow(statement, sdf09,
validator.getStored(ValidationStored.Account));
}
SDf10 sdf10New = createSuccessSdf10(sdf09, generationIdForGroup);
sdf10Imdg.insert(sdf10New);
statement.setOutSDfId(sdf10New.getId());
AccountResult accountResult = accountBalanceService.createAccountBalance(statement.getAddresseeId(), statement.getAccountId(), statement.getAmount(), statement.getCashMovementCurrencyCode());
if (accountResult.getError() != null) {
statement.setErrorCode(accountResult.getError().getSubject().getId().toString());
statement.setErrorText(errorResolver.resolve(accountResult.getError()));
} else {
accountBalanceImdg.insert(accountResult.getAccount()); //insert == update?
statement.setOperationStatus(OperationStatus.Executed.getKey());
}
statementImdg.update(statement);
}
return result;
}
private Statement createFlow(SDf09 sdf09, Company company, Account account) {
Statement statement = new Statement();
statement.setAddresseeId(company.getId());
statement.setSenderId(Sender.Prc.getId());
statement.setCreated(Instant.now());
statement.setClearingDate(LocalDate.now());
statement.setStatementType(StatementType.full.getKey());
statement.setAccountId(account.getId());
statement.setAccount(sdf09.getAccount());
statement.setInOutDirection(InOutDirection.in.getKey());
statement.setAmount(sdf09.getSum());
statement.setCashMovementCurrencyCode(CurrencyCode.RUB.getKey());
statement.setOperationStatus(OperationStatus.Pending.getKey());
statement.setInSDfId(sdf09.getId());
statement.setInOutSDfType(InOutSDfType.type9.getKey());
statementImdg.insert(statement);
return statement;
}
private void updateFlow(Statement statement, SDf09 sdf09, Account account) {
statement.setUpdated(Instant.now());
statement.setAccountId(account.getId());
statement.setAccount(sdf09.getAccount());
statement.setInOutDirection(InOutDirection.in.getKey());
statement.setAmount(sdf09.getSum());
statement.setCashMovementCurrencyCode(CurrencyCode.RUB.getKey());
statementImdg.update(statement);
}
private AccountSdfRequestPart createAccountRequestPart(Long sdf09Id, String account, Long companyId) {
AccountSdfRequestPart req = new AccountSdfRequestPart();
req.setAccount(account);
req.setCompanyId(companyId);
req.setSdfId(sdf09Id);
return req;
}
private SDf10 createErrorSdf10(SDf09 sdf09, EnumMessage error, Long generationIdForGroup) {
SDf10 sDf10 = createSuccessSdf10(sdf09, generationIdForGroup);
String errorId = error.getSubject().getId().toString();
sDf10.setResult(errorId.substring(errorId.length() - 3));
return sDf10;
}
private SDf10 createSuccessSdf10(SDf09 sdf09, Long generationIdForGroup) {
SDf10 sDf10 = new SDf10();
sDf10.setAccount(sdf09.getAccount());
sDf10.setSum(sdf09.getSum());
sDf10.setMarket(sdf09.getMarket());
sDf10.setType(sdf09.getType());
sDf10.setNumber(sdf09.getNumber());
sDf10.setINN(sdf09.getInn());
sDf10.setResult("OK");
sDf10.setGenerationId(generationIdForGroup);
sDf10.setGenerationTime(Instant.now());
sDf10.setIn_s_df09_id(sdf09.getId());
return sDf10;
}
}

View file

@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration;
import ru.spcex.platform.utils.enumeration.IEnumKey;
public enum InOutSDfType implements IEnumKey {
type1("0102");
type1("0102"), type9("0910");
private final String key;

View file

@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration;
import ru.spcex.platform.utils.enumeration.IEnumKey;
public enum StatementType implements IEnumKey {
full("FULL");
full("FULL"), incr("INCR");
private final String key;