sdf21 depoCodeCl depoCodeCorr

This commit is contained in:
ialbert 2023-08-25 19:15:23 +03:00
parent 9f046ae383
commit 20547cb3e4
7 changed files with 366 additions and 94 deletions

View file

@ -28,11 +28,13 @@ import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDe
import ru.spcex.clearing.service.validation.*; import ru.spcex.clearing.service.validation.*;
import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ClearingCategory; import ru.spcex.platform.enumeration.ClearingCategory;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.imdg.validation.LogPrefixId; import ru.spcex.platform.imdg.validation.LogPrefixId;
import ru.spcex.platform.imdg.validation.rule.AccWithTypeValidationRule;
import ru.spcex.platform.imdg.validation.rule.PresentById; import ru.spcex.platform.imdg.validation.rule.PresentById;
import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.IValidator;
@ -211,9 +213,24 @@ public class ValidationConfig {
context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry); context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
context.setLogPrefix(LogPrefixId.INSTANCE); context.setLogPrefix(LogPrefixId.INSTANCE);
return new ValidatorImpl<>(context, return new ValidatorImpl<>(context,
CompanyByTradingCodeValidationRule.instance(SDf21::getDepoCodeCl), Sdf21ValidationRule.Fields,
Sdf21ValidationRule.AccountPresent,
SecurityBySecurityCodeValidationRule.instance(SDf21::getSecurityCode), SecurityBySecurityCodeValidationRule.instance(SDf21::getSecurityCode),
CompanyByTradingCodeValidationRule
.instance(SDf21::getDepoCodeCl)
.store(ValidationStored.Sdf21CompanyCl),
CompanyByTradingCodeValidationRule
.instance(SDf21::getDepoCodeCorr)
.store(ValidationStored.Sdf21CompanyCorr)
.mandatory(false),
AccWithTypeValidationRule.instance(SDf21::getDepoCodeCl,
AccountType.Depo,
ValidationStored.Sdf21AccountCl,
ClearingError.MoreThan1Record),
AccWithTypeValidationRule.instance(SDf21::getDepoCodeCorr,
AccountType.Depo,
ValidationStored.Sdf21AccountCorr,
ClearingError.MoreThan1Record),
Sdf21ValidationRule.AccountClPresent,
Sdf21ValidationRule.TransactionNumberProcessed Sdf21ValidationRule.TransactionNumberProcessed
); );
}; };

View file

@ -28,6 +28,7 @@ public enum ClearingError implements IErrorEnumId {
NewDealsNotFound(5423L), NewDealsNotFound(5423L),
IdentifiedFundsExceedObligations(5424L), IdentifiedFundsExceedObligations(5424L),
ObligationsAlreadyCalculated(5425L), ObligationsAlreadyCalculated(5425L),
MoreThan1Record(5427L),
//ошибки "перенесенные" из balance-service, //ошибки "перенесенные" из balance-service,
CompanyNotFoundB(5211L), CompanyNotFoundB(5211L),
CurrencyNotFound(5213L), CurrencyNotFound(5213L),

View file

@ -25,6 +25,7 @@ import ru.spcex.clearing.service.builder.RegistrySecurityBuilder;
import ru.spcex.clearing.service.model.Result; import ru.spcex.clearing.service.model.Result;
import ru.spcex.clearing.service.validation.ValidationStored; import ru.spcex.clearing.service.validation.ValidationStored;
import ru.spcex.clearing.session.stage.util.RegistryUtil; import ru.spcex.clearing.session.stage.util.RegistryUtil;
import ru.spcex.platform.classes.base.interfaces.WithId;
import ru.spcex.platform.enumeration.*; import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgProvider;
@ -145,83 +146,189 @@ public class Sdf21Executor extends AbstractExecutor<SDf21> {
log.info("skipping after validating sdf21.id={} - {}", sdf21.getId(), messageResolver.resolve(error.get())); log.info("skipping after validating sdf21.id={} - {}", sdf21.getId(), messageResolver.resolve(error.get()));
continue; continue;
} }
Company company = validator.getStored(ValidationStored.CompanyByTradingCode); Company companyCl = validator.getStored(ValidationStored.Sdf21CompanyCl);
Account account = validator.getStored(ValidationStored.Sdf21Account); Company companyCorr = validator.getStored(ValidationStored.Sdf21CompanyCorr);
log.debug("company.id={}, account.id={}", company.getId(), account.getId()); Account accountCl = validator.getStored(ValidationStored.Sdf21AccountCl);
//адресат CREDIT / владелец DEBIT Account accountCorr = validator.getStored(ValidationStored.Sdf21AccountCorr);
Statement stmt = create(sdf21, company, account); Security security = validator.getStored(ValidationStored.SecurityBySecurityCode);
statementImdg.insert(stmt); OperationCode direction = validator.getStored(ValidationStored.Sdf21OperationCode);
log.debug("created statement.id={}", stmt.getId()); //accountCl и companyCl должны быть всегда в наличии.
//accountCorr и companyCorr опциональны
Optional<EnumMessage> err = validateActiveness(company, account); if (direction.equals(OperationCode.RECFREE)) {
if (err.isEmpty()) { stmtAndAssets(sdf21, accountCl, companyCl, companyCorr, security, InOutDirection.in);
Optional<Registry> astFound = RegistrySearch.builder(registryImdg) if (accountCorr != null && companyCorr != null) {
.rgsCode(RegistryTradingParams.AS_T) stmtAndAssets(sdf21, accountCorr, companyCl, companyCorr, security, InOutDirection.out);
.companyId(company.getId()) //раньше было stmt.getAddresseeId() }
.accountId(account.getId()) //раньше было stmt.getAccountId() } else { //DELFREE
.securityId(stmt.getSecurityId()) if (accountCorr != null && companyCorr != null) {
.find(); stmtAndAssets(sdf21, accountCorr, companyCorr, companyCl, security, InOutDirection.in);
astFound.ifPresentOrElse(rgs -> { }
log.debug("stmt.id={}, found AS*T.id={}, updating...", stmt.getId(), rgs.getId()); stmtAndAssets(sdf21, accountCl, companyCorr, companyCl, security, InOutDirection.out);
updateReg(stmt, rgs);
//добавил создание если не найдены
Registry registryUnitB = findRegByUnit(company.getId(), account.getId(), stmt.getContract(), rgs, RegistryUnit.B).orElse(copyRegB(rgs));
Registry registryUnitF = findRegByUnit(company.getId(), account.getId(), stmt.getContract(), rgs, RegistryUnit.F).orElse(copyRegF(rgs, null)); //передаю null т.к. отнимется ниже по коду
registryUnitF.setBalance(rgs.getBalance().subtract(registryUnitB.getBalance()));
registryUnitF.setUpdated(Instant.now());
//registry F всегда меняется
if (registryUnitF.getId() == null) {
registryImdg.insert(registryUnitF);
log.debug("stmt.id={}, new AM*F.id={}", stmt.getId(), registryUnitF.getId());
} else {
registryImdg.update(registryUnitF);
log.debug("stmt.id={}, updated AM*F.id={}", stmt.getId(), registryUnitF.getId());
}
//нужно сохранить registry B только если его не было
if (registryUnitB.getId() == null) {
registryImdg.insert(registryUnitB);
log.debug("stmt.id={}, new AM*B.id={}", stmt.getId(), registryUnitB.getId());
}
registryImdg.update(rgs);
log.debug("stmt.id={}, updated AM*T.id={}: balance {}/debit {}/ credit {}",
stmt.getId(),
rgs.getId(),
rgs.getBalance(),
rgs.getDebit(),
rgs.getCredit());
}, () -> {
Registry registry = RegistrySecurityBuilder.builder(imdgProvider)
.statement(stmt)
.company(company)
.account(account)
.designation(RegistryDesignation.A)
.build();
calcBalance(registry, stmt);
Registry registryB = copyRegB(registry);
Registry registryF = copyRegF(registry, registryB.getBalance());
registryImdg.insert(registry);
registryImdg.insert(registryF);
registryImdg.insert(registryB);
log.debug("stmt.id={}, new AM*T.id={}, new AM*F.id={}, new AM*B.id={}",
stmt.getId(),
registry.getId(),
registryF.getId(),
registryB.getId());
});
stmt.setOperationStatus(OperationStatus.Executed.getKey());
statementImdg.update(stmt);
log.debug("stmt.id={} status -> {}", stmt.getId(), OperationStatus.Executed.getKey());
} else {
log.debug("statement.id={} activness validation failed {}", stmt.getId(), messageResolver.resolve(err.get()));
stmt.setErrorCodeId(err.get().getSubject().getId()); // fixme ErrorText insert
stmt.setOperationStatus(OperationStatus.Rejected.getKey());
statementImdg.update(stmt);
} }
// Company company = validator.getStored(ValidationStored.CompanyByTradingCode);
// Account account = validator.getStored(ValidationStored.Sdf21Account);
// log.debug("company.id={}, account.id={}", company.getId(), account.getId());
// //адресат CREDIT / владелец DEBIT
// Statement stmt = create(sdf21, company, account);
// statementImdg.insert(stmt);
// log.debug("created statement.id={}", stmt.getId());
//
// Optional<EnumMessage> err = validateActiveness(company, account);
// if (err.isEmpty()) {
// Optional<Registry> astFound = RegistrySearch.builder(registryImdg)
// .rgsCode(RegistryTradingParams.AS_T)
// .companyId(company.getId()) //раньше было stmt.getAddresseeId()
// .accountId(account.getId()) //раньше было stmt.getAccountId()
// .securityId(stmt.getSecurityId())
// .find();
// astFound.ifPresentOrElse(rgs -> {
// log.debug("stmt.id={}, found AS*T.id={}, updating...", stmt.getId(), rgs.getId());
// updateReg(stmt, rgs);
// //добавил создание если не найдены
// Registry registryUnitB = findRegByUnit(company.getId(), account.getId(), stmt.getContract(), rgs, RegistryUnit.B).orElse(copyRegB(rgs));
// Registry registryUnitF = findRegByUnit(company.getId(), account.getId(), stmt.getContract(), rgs, RegistryUnit.F).orElse(copyRegF(rgs, null)); //передаю null т.к. отнимется ниже по коду
// registryUnitF.setBalance(rgs.getBalance().subtract(registryUnitB.getBalance()));
// registryUnitF.setUpdated(Instant.now());
// //registry F всегда меняется
// if (registryUnitF.getId() == null) {
// registryImdg.insert(registryUnitF);
// log.debug("stmt.id={}, new AM*F.id={}", stmt.getId(), registryUnitF.getId());
// } else {
// registryImdg.update(registryUnitF);
// log.debug("stmt.id={}, updated AM*F.id={}", stmt.getId(), registryUnitF.getId());
// }
// //нужно сохранить registry B только если его не было
// if (registryUnitB.getId() == null) {
// registryImdg.insert(registryUnitB);
// log.debug("stmt.id={}, new AM*B.id={}", stmt.getId(), registryUnitB.getId());
// }
// registryImdg.update(rgs);
// log.debug("stmt.id={}, updated AM*T.id={}: balance {}/debit {}/ credit {}",
// stmt.getId(),
// rgs.getId(),
// rgs.getBalance(),
// rgs.getDebit(),
// rgs.getCredit());
// }, () -> {
// Registry registry = RegistrySecurityBuilder.builder(imdgProvider)
// .statement(stmt)
// .company(company)
// .account(account)
// .designation(RegistryDesignation.A)
// .build();
// calcBalance(registry, stmt);
// Registry registryB = copyRegB(registry);
// Registry registryF = copyRegF(registry, registryB.getBalance());
//
// registryImdg.insert(registry);
// registryImdg.insert(registryF);
// registryImdg.insert(registryB);
// log.debug("stmt.id={}, new AM*T.id={}, new AM*F.id={}, new AM*B.id={}",
// stmt.getId(),
// registry.getId(),
// registryF.getId(),
// registryB.getId());
// });
// stmt.setOperationStatus(OperationStatus.Executed.getKey());
// statementImdg.update(stmt);
// log.debug("stmt.id={} status -> {}", stmt.getId(), OperationStatus.Executed.getKey());
// } else {
// log.debug("statement.id={} activness validation failed {}", stmt.getId(), messageResolver.resolve(err.get()));
// stmt.setErrorCodeId(err.get().getSubject().getId()); // fixme ErrorText insert
// stmt.setOperationStatus(OperationStatus.Rejected.getKey());
// statementImdg.update(stmt);
// }
} }
return result; return result;
} }
private void stmtAndAssets(SDf21 sdf21,
Account account,
Company companyAddr,
Company companySender,
Security security,
InOutDirection direction) {
Function<WithId, Long> safeId = withId -> withId != null ? withId.getId() : null;
log.debug("sdf21.id={} account.id={}, companyAddressee.id={}, companySender.id={}, security={}, direction={}",
sdf21.getId(),
account.getId(),
safeId.apply(companyAddr),
safeId.apply(companySender),
security.getSecuritySymbol(),
direction);
//адресат CREDIT / владелец DEBIT
Statement stmt = create2(sdf21, safeId.apply(companyAddr), safeId.apply(companySender), account, security, direction);
statementImdg.insert(stmt);
log.debug("created statement.id={}", stmt.getId());
Company rgsCmp = direction.equals(InOutDirection.in) ? companyAddr : companySender;
Optional<EnumMessage> err = validateActiveness(rgsCmp, account);
if (err.isEmpty()) {
Optional<Registry> astFound = RegistrySearch.builder(registryImdg)
.rgsCode(RegistryTradingParams.AS_T)
.companyId(rgsCmp.getId()) //раньше было stmt.getAddresseeId()
.accountId(account.getId()) //раньше было stmt.getAccountId()
.securityId(stmt.getSecurityId())
.find();
astFound.ifPresentOrElse(rgs -> {
log.debug("stmt.id={}, found AS*T.id={}, updating...", stmt.getId(), rgs.getId());
updateReg(stmt, rgs);
//добавил создание если не найдены
Registry registryUnitB = findRegByUnit(rgsCmp.getId(), account.getId(), stmt.getContract(), rgs, RegistryUnit.B).orElse(copyRegB(rgs));
Registry registryUnitF = findRegByUnit(rgsCmp.getId(), account.getId(), stmt.getContract(), rgs, RegistryUnit.F).orElse(copyRegF(rgs, null)); //передаю null т.к. отнимется ниже по коду
registryUnitF.setBalance(rgs.getBalance().subtract(registryUnitB.getBalance()));
registryUnitF.setUpdated(Instant.now());
//registry F всегда меняется
if (registryUnitF.getId() == null) {
registryImdg.insert(registryUnitF);
log.debug("stmt.id={}, new AM*F.id={}", stmt.getId(), registryUnitF.getId());
} else {
registryImdg.update(registryUnitF);
log.debug("stmt.id={}, updated AM*F.id={}", stmt.getId(), registryUnitF.getId());
}
//нужно сохранить registry B только если его не было
if (registryUnitB.getId() == null) {
registryImdg.insert(registryUnitB);
log.debug("stmt.id={}, new AM*B.id={}", stmt.getId(), registryUnitB.getId());
}
registryImdg.update(rgs);
log.debug("stmt.id={}, updated AM*T.id={}: balance {}/debit {}/ credit {}",
stmt.getId(),
rgs.getId(),
rgs.getBalance(),
rgs.getDebit(),
rgs.getCredit());
}, () -> {
Registry registry = RegistrySecurityBuilder.builder(imdgProvider)
.statement(stmt)
.company(rgsCmp)
.account(account)
.designation(RegistryDesignation.A)
.build();
calcBalance(registry, stmt);
Registry registryB = copyRegB(registry);
Registry registryF = copyRegF(registry, registryB.getBalance());
registryImdg.insert(registry);
registryImdg.insert(registryF);
registryImdg.insert(registryB);
log.debug("stmt.id={}, new AM*T.id={}, new AM*F.id={}, new AM*B.id={}",
stmt.getId(),
registry.getId(),
registryF.getId(),
registryB.getId());
});
stmt.setOperationStatus(OperationStatus.Executed.getKey());
statementImdg.update(stmt);
log.debug("stmt.id={} status -> {}", stmt.getId(), OperationStatus.Executed.getKey());
} else {
log.debug("statement.id={} activness validation failed {}", stmt.getId(), messageResolver.resolve(err.get()));
stmt.setErrorCodeId(err.get().getSubject().getId()); // fixme ErrorText insert
stmt.setOperationStatus(OperationStatus.Rejected.getKey());
statementImdg.update(stmt);
}
}
private Registry copyRegB(Registry rgs) { private Registry copyRegB(Registry rgs) {
Registry rgsB = rgs.clone(); Registry rgsB = rgs.clone();
rgsB.setRegistryUnit(RegistryUnit.B.getKey()); rgsB.setRegistryUnit(RegistryUnit.B.getKey());
@ -246,7 +353,7 @@ public class Sdf21Executor extends AbstractExecutor<SDf21> {
} }
private Optional<EnumMessage> validateActiveness(Company company, Account account) { private Optional<EnumMessage> validateActiveness(Company company, Account account) {
if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { if (company != null && !WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) {
return Optional.of(new EnumMessage(ClearingError.CompanyNotActive, company.getId())); return Optional.of(new EnumMessage(ClearingError.CompanyNotActive, company.getId()));
} }
if (!WorkflowStatus.Active.equalsByKey(account.getStatus())) { if (!WorkflowStatus.Active.equalsByKey(account.getStatus())) {
@ -286,6 +393,33 @@ public class Sdf21Executor extends AbstractExecutor<SDf21> {
return statement; return statement;
} }
private Statement create2(SDf21 sdf21,
Long cmpAddrId,
Long cmpSndrId,
Account acc,
Security scr,
InOutDirection dir) {
Statement statement = new Statement();
statement.setAddresseeId(cmpAddrId);
statement.setSenderId(cmpSndrId);
statement.setStatementType(StatementType.incr.getKey());
//fixme statement.setComment(sdf21.());
statement.setAccountId(acc.getId());
statement.setAccount(acc.getAccount());
statement.setSecurityId(scr.getId());
statement.setInOutDirection(dir.getKey());
statement.setSettlementDate(operationDateParse(sdf21.getOperationDate()));
statement.setAmount(TextUtil.isEmpty(sdf21.getQuantity()) ? null : new BigDecimal(sdf21.getQuantity()));
statement.setOperationStatus(OperationStatus.Pending.getKey());
statement.setInSDfId(sdf21.getId());
statement.setInOutSDfType(InOutSDfType.type21.getKey());
statement.setClearingDate(LocalDate.now());
statement.setCreated(Instant.now());
return statement;
}
private void calcBalance(Registry rgs, Statement statement) { private void calcBalance(Registry rgs, Statement statement) {
InOutDirection inOutDirection = IEnumKey.getEnumByKey(InOutDirection.class, statement.getInOutDirection()); InOutDirection inOutDirection = IEnumKey.getEnumByKey(InOutDirection.class, statement.getInOutDirection());
//считаю balance при создании нулевым и исхожу из этого //считаю balance при создании нулевым и исхожу из этого

View file

@ -17,31 +17,59 @@ import java.util.function.Function;
public class CompanyByTradingCodeValidationRule<T> implements IValidationRule<ImdgValidationContext<T>> { public class CompanyByTradingCodeValidationRule<T> implements IValidationRule<ImdgValidationContext<T>> {
private final Function<T, String> tradingCodeExtractor; private final Function<T, String> tradingCodeExtractor;
private Enum<?> storeEnum;
private boolean mandatory = true;
private CompanyByTradingCodeValidationRule(Function<T, String> tradingCodeExtractor) { private CompanyByTradingCodeValidationRule(Function<T, String> tradingCodeExtractor) {
Objects.requireNonNull(tradingCodeExtractor, "cannot create CompanyByDepoCodeValidationRule: depoCodeExtractor is null"); Objects.requireNonNull(tradingCodeExtractor, "cannot create CompanyByDepoCodeValidationRule: depoCodeExtractor is null");
this.tradingCodeExtractor = tradingCodeExtractor; this.tradingCodeExtractor = tradingCodeExtractor;
} }
private CompanyByTradingCodeValidationRule(Function<T, String> tradingCodeExtractor, Enum<?> storeEnum) {
Objects.requireNonNull(tradingCodeExtractor, "cannot create CompanyByDepoCodeValidationRule: depoCodeExtractor is null");
Objects.requireNonNull(storeEnum, "cannot create CompanyByDepoCodeValidationRule: storeEnum is null");
this.tradingCodeExtractor = tradingCodeExtractor;
this.storeEnum = storeEnum;
}
public static <C> CompanyByTradingCodeValidationRule<C> instance(Function<C, String> depoCodeExtractor) { public static <C> CompanyByTradingCodeValidationRule<C> instance(Function<C, String> depoCodeExtractor) {
return new CompanyByTradingCodeValidationRule<>(depoCodeExtractor); return new CompanyByTradingCodeValidationRule<>(depoCodeExtractor);
} }
public CompanyByTradingCodeValidationRule<T> store(Enum<?> storeEnum) {
this.storeEnum = storeEnum;
return this;
}
public CompanyByTradingCodeValidationRule<T> mandatory(boolean mandatory) {
this.mandatory = mandatory;
return this;
}
@Override @Override
public Optional<EnumMessage> validate(ImdgValidationContext<T> context) { public Optional<EnumMessage> validate(ImdgValidationContext<T> context) {
T validatedObject = context.getValidatedObject(); T validatedObject = context.getValidatedObject();
Imdg<Company> companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); Imdg<Company> companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class);
String depoCode = tradingCodeExtractor.apply(validatedObject); String depoCode = tradingCodeExtractor.apply(validatedObject);
if (TextUtil.isEmpty(depoCode) || depoCode.length() < 4) { if (TextUtil.isEmpty(depoCode) || depoCode.length() < 4) {
return of(ClearingError.CompanyNotFoundB, depoCode); if (mandatory) {
return of(ClearingError.CompanyNotFoundB, depoCode);
} else {
return empty();
}
} }
String tradingCode = depoCode.substring(1, 4); String tradingCode = depoCode.substring(1, 4);
tradingCode = tradingCode.replaceFirst("^0+(?!$)", ""); tradingCode = tradingCode.replaceFirst("^0+(?!$)", "");
Collection<Company> companies = companyImdg.getCollectionObjectsBySQL("tradingCode = '%s'".formatted(tradingCode)); Collection<Company> companies = companyImdg.getCollectionObjectsBySQL("tradingCode = '%s'".formatted(tradingCode));
if (companies.size() != 1) { if (companies.size() > 1) {
return of(ClearingError.MoreThan1Record, "tradingCode = '%s'".formatted(tradingCode));
}
if (mandatory && companies.size() < 1) {
return of(ClearingError.CompanyNotFoundB, tradingCode); return of(ClearingError.CompanyNotFoundB, tradingCode);
} }
context.storeObject(ValidationStored.CompanyByTradingCode, companies.iterator().next()); if (companies.size() == 1) {
Enum<?> storeEnum = this.storeEnum == null ? ValidationStored.CompanyByTradingCode : this.storeEnum;
context.storeObject(storeEnum, companies.iterator().next());
}
return empty(); return empty();
} }
} }

View file

@ -7,7 +7,6 @@ import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.sdf.SDf21; import ru.clearing.classes.statics.data.sdf.SDf21;
import ru.spcex.clearing.error.ClearingError; import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.OperationCode; import ru.spcex.platform.enumeration.OperationCode;
import ru.spcex.platform.enumeration.RegistryTradingParams; import ru.spcex.platform.enumeration.RegistryTradingParams;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
@ -16,33 +15,63 @@ import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder; import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.text.TextUtil; import ru.spcex.platform.utils.text.TextUtil;
import ru.spcex.platform.utils.validation.IValidationRule; import ru.spcex.platform.utils.validation.IValidationRule;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Collection;
import java.util.Optional; import java.util.Optional;
public enum Sdf21ValidationRule implements IValidationRule<ImdgValidationContext<SDf21>> { public enum Sdf21ValidationRule implements IValidationRule<ImdgValidationContext<SDf21>> {
Fields() {
AccountPresent() {
@Override @Override
public Optional<EnumMessage> validate(ImdgValidationContext<SDf21> context) { public Optional<EnumMessage> validate(ImdgValidationContext<SDf21> context) {
SDf21 sdf21 = context.getValidatedObject(); SDf21 validatedObject = context.getValidatedObject();
if (TextUtil.isEmpty(sdf21.getDepoCodeCl())) {
return of(ClearingError.AccountNotPresent, sdf21.getDepoCodeCl()); if (TextUtil.isEmpty(validatedObject.getOperationCode())) {
return of(ClearingError.WrongField, "operationCode");
} }
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); OperationCode opCde = IEnumKey.getEnumByKey(OperationCode.class, validatedObject.getOperationCode());
Collection<Account> account = accountImdg.getCollectionObjectsBySQL( if (opCde == null) {
"account = '%s' and accountType = '%s'".formatted(sdf21.getDepoCodeCl(), AccountType.Depo.getKey()) return of(ClearingError.WrongField, "operationCode");
);
if (account.size() != 1) {
return of(ClearingError.AccountNotPresent, sdf21.getDepoCodeCl());
} }
context.storeObject(ValidationStored.Sdf21Account, account.iterator().next()); context.storeObject(ValidationStored.Sdf21OperationCode, opCde);
return empty();
if (TextUtil.isEmpty(validatedObject.getDepoCodeCl()) && TextUtil.isEmpty(validatedObject.getDepoCodeCorr())) {
return of(ClearingError.WrongField, "depoCodeCl/depoCodeCorr");
}
return Optional.empty();
} }
}, },
AccountClPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<SDf21> context) {
Account accCl = context.getStoredObject(ValidationStored.Sdf21AccountCl);
if (accCl == null) {
return of(ClearingError.WrongField, "depoCodeCl='%s' account not found"
.formatted(context.getValidatedObject().getDepoCodeCl()));
}
return Optional.empty();
}
},
// AccountPresent() {
// @Override
// public Optional<EnumMessage> validate(ImdgValidationContext<SDf21> context) {
// SDf21 sdf21 = context.getValidatedObject();
// if (TextUtil.isEmpty(sdf21.getDepoCodeCl())) {
// return of(ClearingError.AccountNotPresent, sdf21.getDepoCodeCl());
// }
// Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
// Collection<Account> account = accountImdg.getCollectionObjectsBySQL(
// "account = '%s' and accountType = '%s'".formatted(sdf21.getDepoCodeCl(), AccountType.Depo.getKey())
// );
// if (account.size() != 1) {
// return of(ClearingError.AccountNotPresent, sdf21.getDepoCodeCl());
// }
// context.storeObject(ValidationStored.Sdf21Account, account.iterator().next());
// return empty();
// }
// },
TransactionNumberProcessed() { TransactionNumberProcessed() {
@Override @Override
public Optional<EnumMessage> validate(ImdgValidationContext<SDf21> context) { public Optional<EnumMessage> validate(ImdgValidationContext<SDf21> context) {

View file

@ -12,7 +12,7 @@ public enum ValidationStored {
Sdf10Company, Sdf10Account, Sdf10DepoAccount, Sdf10Tcr, Sdf10Company, Sdf10Account, Sdf10DepoAccount, Sdf10Tcr,
Sdf21Account, Sdf21Account, Sdf21AccountCl, Sdf21AccountCorr, Sdf21CompanyCl, Sdf21CompanyCorr, Sdf21OperationCode,
PIOutboundAccountDeb, PIOutboundAccountCred, PIOutboundAccountDeb, PIOutboundAccountCred,

View file

@ -0,0 +1,63 @@
package ru.spcex.platform.imdg.validation.rule;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.classes.base.SpcexObjectBase;
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.enumeration.IErrorEnumId;
import ru.spcex.platform.utils.text.TextUtil;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.util.Collection;
import java.util.Optional;
import java.util.function.Function;
//выгружает по account и accountType
//возвращает ошибку если нашлось > 1 счета
//при необходимости сделать жесткую проверку, ввести mandatory как в CompanyByTradingCodeValidationRule.mandatory
public class AccWithTypeValidationRule<T> implements IValidationRule<ImdgValidationContext<T>> {
private final Function<T, String> accountExtractor;
private final AccountType accountType;
private final Enum<?> storeEnum;
private final IErrorEnumId errMsg;
private AccWithTypeValidationRule(Function<T, String> accountExtractor,
AccountType accountType,
Enum<?> storeEnum,
IErrorEnumId errMsg) {
this.accountExtractor = accountExtractor;
this.accountType = accountType;
this.storeEnum = storeEnum;
this.errMsg = errMsg;
}
public static <T> AccWithTypeValidationRule<T> instance(Function<T, String> accountExtractor,
AccountType accountType,
Enum<?> storeEnum,
IErrorEnumId errMsg) {
return new AccWithTypeValidationRule<>(accountExtractor, accountType, storeEnum, errMsg);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<T> context) {
T validatedObject = context.getValidatedObject();
String account = accountExtractor.apply(validatedObject);
if (TextUtil.isEmpty(account)) {
return empty();
}
Imdg<SpcexObjectBase> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, SpcexObjectBase.class);
Collection<SpcexObjectBase> accs = accountImdg.getCollectionObjectsBySQL(
"account = '%s' and accountType = '%s'".formatted(account, accountType.getKey()));
if (accs.size() > 1) {
return of(errMsg, "account='%s', accountType='%s'"
.formatted(account, accountType.getKey()));
}
if (!accs.isEmpty()) {
context.storeObject(storeEnum, accs.iterator().next());
}
return Optional.empty();
}
}