ialbert 2022-10-05 20:19:16 +03:00
parent 94fbfe9d44
commit 10fa810151
12 changed files with 235 additions and 33 deletions

View file

@ -6,10 +6,13 @@ import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.sdf.SDf01;
import ru.spcex.clearing.balance.validation.AccountBalanceValidation;
import ru.spcex.clearing.balance.validation.AccountBalanceValidationRule;
import ru.spcex.clearing.balance.validation.Sdf01ValidationRule;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
@ -38,4 +41,21 @@ public class ValidationConfig {
};
}
@Autowired
@Bean("accountBalanceValidator")
public Function<AccountBalanceValidation, IValidator> accountBalanceValidator(ImdgProvider imdgProvider) {
return fieldsToValidateWrapper -> {
ImdgValidationContext<AccountBalanceValidation> context = new ImdgValidationContext<>();
context.setValidatedObject(fieldsToValidateWrapper);
BiConsumer<String, Class<? extends SpcexObjectBase>> addImdg = (s, aClass) -> context.addImdg(s, imdgProvider.getImdg(s, aClass));
addImdg.accept(IMDGDistributedNames.Map_Account, Account.class);
addImdg.accept(IMDGDistributedNames.Map_Company, Company.class);
return new ValidatorImpl<>(context,
AccountBalanceValidationRule.CompanyPresent,
AccountBalanceValidationRule.AccountOk);
};
}
}

View file

@ -8,7 +8,9 @@ public enum BalanceError implements IEnumId {
CurrentDateOnly(5214L),
WrongMarket(5215L),
WrongAccount(5215L),
AccountNotPresent(-1L);
AccountNotPresent(5217L),
AccountNotActive(5218L)
;
private final Long id;
BalanceError(Long id) {

View file

@ -0,0 +1,79 @@
package ru.spcex.clearing.balance.service;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
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.spcex.clearing.balance.validation.AccountBalanceValidation;
import ru.spcex.clearing.balance.validation.ValidationStored;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.BalanceAccountType;
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.validation.IValidator;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
@Component
public class AccountBalanceService {
private final ImdgProvider imdgProvider;
private final Imdg<AccountBalance> accountBalanceImdg;
private final Function<AccountBalanceValidation, IValidator> validationFactory;
public AccountBalanceService(ImdgProvider imdgProvider,
@Qualifier("accountBalanceValidator") Function<AccountBalanceValidation, IValidator> validationFactory) {
this.imdgProvider = imdgProvider;
this.validationFactory = validationFactory;
this.accountBalanceImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class);
}
public AccountResult createAccountBalance(Long addresseeId, Long accountId, BigDecimal amount,
String cashMovementCurrencyCode) {
IValidator validator = validationFactory.apply(new AccountBalanceValidation(addresseeId, accountId));
Optional<EnumMessage> validationError = validator
.tillFirstError();
if (validationError.isPresent()) return new AccountResult(validationError.get());
Account account = validator.getStored(ValidationStored.Account);
Company company = validator.getStored(ValidationStored.Company);
//которой accountBalance.accountId=statement.accountId и accountBalance.companyId=statement.companyId:
AccountBalance accountBalance = accountBalanceImdg.getSingleObjectByFieldValues(
Map.of("accountId", accountId, "companyId", addresseeId)
);
if (accountBalance == null) {
accountBalance = new AccountBalance();
accountBalance.setCompanyId(addresseeId);
accountBalance.setCreated(Instant.now());
accountBalance.setAccountId(accountId);
//fixme accountBalance.setAccountType(account.getAccountType());
accountBalance.setAccount(account.getAccount());
accountBalance.setOpenBalanceAmount(amount);
accountBalance.setFreeBalanceAmount(amount);
accountBalance.setBalanceAmount(amount);
accountBalance.setBalanceAccountType(BalanceAccountType.Active.getKey());
accountBalance.setClearingDate(LocalDate.now());
accountBalance.setCurrencyCode(cashMovementCurrencyCode);
accountBalance.setTradingCode(company.getTradingCode());
accountBalance.setShortName(company.getShortName());
accountBalance.setFullName(company.getFullName());
return new AccountResult(accountBalance);
} else {
accountBalance.setUpdated(Instant.now());
accountBalance.setAccountId(accountId);
//fixme accountBalance.setAccountType(account.getAccountType());
accountBalance.setAccount(account.getAccount());
accountBalance.setOpenBalanceAmount(amount);
accountBalance.setFreeBalanceAmount(amount);
accountBalance.setBalanceAmount(amount);
accountBalance.setCurrencyCode(cashMovementCurrencyCode);
return new AccountResult(accountBalance);
}
}
}

View file

@ -0,0 +1,25 @@
package ru.spcex.clearing.balance.service;
import ru.clearing.classes.statics.data.account.AccountBalance;
import ru.spcex.platform.utils.enumeration.EnumMessage;
public class AccountResult {
private EnumMessage error; //if was
private AccountBalance account;
public AccountResult(EnumMessage validationError) {
this.error = validationError;
}
public AccountResult(AccountBalance account) {
this.account = account;
}
public EnumMessage getError() {
return error;
}
public AccountBalance getAccount() {
return account;
}
}

View file

@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.SDf01;
import ru.clearing.classes.statics.data.sdf.SDf02;
@ -28,6 +29,7 @@ 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.time.TimeUtil;
import ru.spcex.platform.utils.validation.IValidator;
@ -51,19 +53,25 @@ public class StatementService extends QueueConsumer implements InitializingBean
private final Imdg<AccountBalance> accountBalanceImdg;
private final Imdg<Statement> statementImdg;
private final Function<SDf01, IValidator> sDf01Validator;
private final AccountBalanceService accountBalanceService;
private final IMessageResolver errorResolver;
@Autowired
public StatementService(Consumer<String, Object> kafkaQueue, ImdgProvider imdgProvider, KafkaSender kafkaReqProducer, LoggingService errorLogger,
@Qualifier("sdf01Validator") Function<SDf01, IValidator> sDf01Validator) {
@Qualifier("sdf01Validator") Function<SDf01, IValidator> sDf01Validator,
AccountBalanceService accountBalanceService,
IMessageResolver errorResolver) {
super(kafkaQueue);
this.imdgProvider = imdgProvider;
this.sdf01Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf01, SDf01.class);
this.sdf02Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class);;
this.sdf02Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class);
this.accountBalanceService = accountBalanceService;
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
this.accountBalanceImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class);
this.kafkaReqProducer = kafkaReqProducer;
this.errorLogger = errorLogger;
this.sDf01Validator = sDf01Validator;
this.errorResolver = errorResolver;
}
@Override
@ -95,7 +103,7 @@ public class StatementService extends QueueConsumer implements InitializingBean
for (SDf01 sdf01 : sdf01Group) {
IValidator validator = sDf01Validator.apply(sdf01);
Optional<EnumMessage> error = validator.tillFirstError();
Company company = validator.getStored(ValidationStored.Sdf01Company);
Company company = validator.getStored(ValidationStored.Company);
if (statementRequest.getAccountCreationResults().size() == 0
&& BalanceError.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) {
//на данном шаге company существует -> getId ok
@ -115,18 +123,22 @@ public class StatementService extends QueueConsumer implements InitializingBean
if (statement == null) {
statement = createFlow(sdf01,
company,
validator.getStored(ValidationStored.Sdf01Account));
validator.getStored(ValidationStored.Account));
} else {
updateFlow(statement, sdf01,
validator.getStored(ValidationStored.Sdf01Account));
validator.getStored(ValidationStored.Account));
}
SDf02 sdf02New = createSuccessSdf02(sdf01, generationIdForGroup);
sdf02Imdg.insert(sdf02New);
statement.setOutSDfId(sdf02New.getId());
AccountBalance accountBalance = createSuccessAccountBalance();
accountBalanceImdg.insert(accountBalance);
//fixme possible error from accountBalanceCreation -> other status + errorCode, errorText
statement.setStatus(OperationStatus.Executed.getKey());
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.setStatus(OperationStatus.Executed.getKey());
}
statementImdg.update(statement);
if (accountRequests.size() > 0) {
@ -227,20 +239,4 @@ public class StatementService extends QueueConsumer implements InitializingBean
sDf02.setResult("OK!");
return sDf02;
}
private AccountBalance createSuccessAccountBalance() {
return new AccountBalance();
}
private static class AccountBalance extends SpcexObjectBase {
private String message = "AccountBalance";
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
}

View file

@ -0,0 +1,3 @@
package ru.spcex.clearing.balance.validation;
public record AccountBalanceValidation(Long addresseeId, Long accountId) {}

View file

@ -0,0 +1,55 @@
package ru.spcex.clearing.balance.validation;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
import ru.spcex.clearing.balance.errors.BalanceError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.Optional;
public enum AccountBalanceValidationRule implements IValidationRule<ImdgValidationContext<AccountBalanceValidation>> {
CompanyPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<AccountBalanceValidation> context) {
AccountBalanceValidation validatedObject = context.getValidatedObject();
Imdg<Company> companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class);
Company company = companyImdg.getSingleObjectByID(validatedObject.addresseeId());
if (company == null) {
return of( BalanceError.CompanyNotFound);
}
context.storeObject(ValidationStored.Company, company);
return empty();
}
},
AccountOk() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<AccountBalanceValidation> context) {
AccountBalanceValidation validatedObject = context.getValidatedObject();
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
Account account = accountImdg.getSingleObjectByFieldValues(Map.of("id", validatedObject.accountId(),
"accountType", AccountType.Clrn.getKey()));
if (account == null) {
return of(BalanceError.AccountNotPresent);
}
if (!Status.Active.equalsByKey(account.getStatus())) {
return of(BalanceError.AccountNotActive, account.getId());
}
context.storeObject(ValidationStored.Account, account);
return empty();
}
};
private final static DateTimeFormatter datFormatter = DateTimeFormatter.ofPattern("dd.MM.yy");
@Override
public String ruleName() {
return "Sdf01ValidationRule." + name();
}
}

View file

@ -3,11 +3,11 @@ package ru.spcex.clearing.balance.validation;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.sdf.SDf01;
import ru.spcex.clearing.balance.config.ImdgValidationContext;
import ru.spcex.clearing.balance.errors.BalanceError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
@ -26,7 +26,7 @@ public enum Sdf01ValidationRule implements IValidationRule<ImdgValidationContext
if (company == null) {
return of( BalanceError.CompanyNotFound);
}
context.storeObject(ValidationStored.Sdf01Company, company);
context.storeObject(ValidationStored.Company, company);
return empty();
}
},
@ -40,7 +40,7 @@ public enum Sdf01ValidationRule implements IValidationRule<ImdgValidationContext
if (account == null) {
return of(BalanceError.AccountNotPresent);
}
context.storeObject(ValidationStored.Sdf01Account, account);
context.storeObject(ValidationStored.Account, account);
return empty();
}
},

View file

@ -1,5 +1,5 @@
package ru.spcex.clearing.balance.validation;
public enum ValidationStored {
Sdf01Account, Sdf01Company;
Account, Company;
}

View file

@ -0,0 +1,18 @@
package ru.spcex.platform.enumeration;
import ru.spcex.platform.utils.enumeration.IEnumKey;
public enum BalanceAccountType implements IEnumKey {
Active("ACTV"), Blocked("BLKD");
private final String key;
BalanceAccountType(String key) {
this.key = key;
}
@Override
public String getKey() {
return key;
}
}

View file

@ -25,5 +25,9 @@
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-classes-base</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-utils</artifactId>
</dependency>
</dependencies>
</project>

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.balance.config;
package ru.spcex.platform.imdg.validation;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
@ -17,11 +17,11 @@ public class ImdgValidationContext<T> implements IValidatorContext {
this.storedObjects = new HashMap<>();
}
void addImdg(String key, Imdg<?> imdg) {
public void addImdg(String key, Imdg<?> imdg) {
imdgs.put(key, imdg);
}
void setValidatedObject(T validatedObject) {
public void setValidatedObject(T validatedObject) {
this.validatedObject = validatedObject;
}