From 20547cb3e437b036ebf4cb13d8da6f5933042f2a Mon Sep 17 00:00:00 2001 From: ialbert Date: Fri, 25 Aug 2023 19:15:23 +0300 Subject: [PATCH] sdf21 depoCodeCl depoCodeCorr --- .../clearing/config/ValidationConfig.java | 21 +- .../spcex/clearing/error/ClearingError.java | 1 + .../service/executors/Sdf21Executor.java | 280 +++++++++++++----- .../CompanyByTradingCodeValidationRule.java | 34 ++- .../validation/Sdf21ValidationRule.java | 59 +++- .../service/validation/ValidationStored.java | 2 +- .../rule/AccWithTypeValidationRule.java | 63 ++++ 7 files changed, 366 insertions(+), 94 deletions(-) create mode 100644 platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/validation/rule/AccWithTypeValidationRule.java diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java index 35cf92ea5..5f0e5eebd 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java @@ -28,11 +28,13 @@ import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDe import ru.spcex.clearing.service.validation.*; import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.rules.IdPresentRule; +import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.ClearingCategory; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.validation.ImdgValidationContext; 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.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.validation.IValidator; @@ -211,9 +213,24 @@ public class ValidationConfig { context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry); context.setLogPrefix(LogPrefixId.INSTANCE); return new ValidatorImpl<>(context, - CompanyByTradingCodeValidationRule.instance(SDf21::getDepoCodeCl), - Sdf21ValidationRule.AccountPresent, + Sdf21ValidationRule.Fields, 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 ); }; diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingError.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingError.java index 01dbb950e..dc1d2ef7b 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingError.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingError.java @@ -28,6 +28,7 @@ public enum ClearingError implements IErrorEnumId { NewDealsNotFound(5423L), IdentifiedFundsExceedObligations(5424L), ObligationsAlreadyCalculated(5425L), + MoreThan1Record(5427L), //ошибки "перенесенные" из balance-service, CompanyNotFoundB(5211L), CurrencyNotFound(5213L), diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf21Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf21Executor.java index 98a02d682..5117f8392 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf21Executor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf21Executor.java @@ -25,6 +25,7 @@ import ru.spcex.clearing.service.builder.RegistrySecurityBuilder; import ru.spcex.clearing.service.model.Result; import ru.spcex.clearing.service.validation.ValidationStored; 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.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -145,83 +146,189 @@ public class Sdf21Executor extends AbstractExecutor { log.info("skipping after validating sdf21.id={} - {}", sdf21.getId(), messageResolver.resolve(error.get())); continue; } - 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 err = validateActiveness(company, account); - if (err.isEmpty()) { - Optional 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); + Company companyCl = validator.getStored(ValidationStored.Sdf21CompanyCl); + Company companyCorr = validator.getStored(ValidationStored.Sdf21CompanyCorr); + Account accountCl = validator.getStored(ValidationStored.Sdf21AccountCl); + Account accountCorr = validator.getStored(ValidationStored.Sdf21AccountCorr); + Security security = validator.getStored(ValidationStored.SecurityBySecurityCode); + OperationCode direction = validator.getStored(ValidationStored.Sdf21OperationCode); + //accountCl и companyCl должны быть всегда в наличии. + //accountCorr и companyCorr опциональны + if (direction.equals(OperationCode.RECFREE)) { + stmtAndAssets(sdf21, accountCl, companyCl, companyCorr, security, InOutDirection.in); + if (accountCorr != null && companyCorr != null) { + stmtAndAssets(sdf21, accountCorr, companyCl, companyCorr, security, InOutDirection.out); + } + } else { //DELFREE + if (accountCorr != null && companyCorr != null) { + stmtAndAssets(sdf21, accountCorr, companyCorr, companyCl, security, InOutDirection.in); + } + stmtAndAssets(sdf21, accountCl, companyCorr, companyCl, security, InOutDirection.out); } + +// 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 err = validateActiveness(company, account); +// if (err.isEmpty()) { +// Optional 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; } + private void stmtAndAssets(SDf21 sdf21, + Account account, + Company companyAddr, + Company companySender, + Security security, + InOutDirection direction) { + Function 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 err = validateActiveness(rgsCmp, account); + if (err.isEmpty()) { + Optional 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) { Registry rgsB = rgs.clone(); rgsB.setRegistryUnit(RegistryUnit.B.getKey()); @@ -246,7 +353,7 @@ public class Sdf21Executor extends AbstractExecutor { } private Optional 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())); } if (!WorkflowStatus.Active.equalsByKey(account.getStatus())) { @@ -286,6 +393,33 @@ public class Sdf21Executor extends AbstractExecutor { 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) { InOutDirection inOutDirection = IEnumKey.getEnumByKey(InOutDirection.class, statement.getInOutDirection()); //считаю balance при создании нулевым и исхожу из этого diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/CompanyByTradingCodeValidationRule.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/CompanyByTradingCodeValidationRule.java index 363614094..7202c8303 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/CompanyByTradingCodeValidationRule.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/CompanyByTradingCodeValidationRule.java @@ -17,31 +17,59 @@ import java.util.function.Function; public class CompanyByTradingCodeValidationRule implements IValidationRule> { private final Function tradingCodeExtractor; + private Enum storeEnum; + private boolean mandatory = true; private CompanyByTradingCodeValidationRule(Function tradingCodeExtractor) { Objects.requireNonNull(tradingCodeExtractor, "cannot create CompanyByDepoCodeValidationRule: depoCodeExtractor is null"); this.tradingCodeExtractor = tradingCodeExtractor; } + private CompanyByTradingCodeValidationRule(Function 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 CompanyByTradingCodeValidationRule instance(Function depoCodeExtractor) { return new CompanyByTradingCodeValidationRule<>(depoCodeExtractor); } + public CompanyByTradingCodeValidationRule store(Enum storeEnum) { + this.storeEnum = storeEnum; + return this; + } + public CompanyByTradingCodeValidationRule mandatory(boolean mandatory) { + this.mandatory = mandatory; + return this; + } + @Override public Optional validate(ImdgValidationContext context) { T validatedObject = context.getValidatedObject(); Imdg companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); String depoCode = tradingCodeExtractor.apply(validatedObject); 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); tradingCode = tradingCode.replaceFirst("^0+(?!$)", ""); Collection 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); } - 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(); } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/Sdf21ValidationRule.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/Sdf21ValidationRule.java index 63c6ac97b..403496ff5 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/Sdf21ValidationRule.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/Sdf21ValidationRule.java @@ -7,7 +7,6 @@ import ru.clearing.classes.statics.data.registry.Registry; import ru.clearing.classes.statics.data.sdf.SDf21; import ru.spcex.clearing.error.ClearingError; import ru.spcex.clearing.imdg.IMDGDistributedNames; -import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.OperationCode; import ru.spcex.platform.enumeration.RegistryTradingParams; 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.validation.ImdgValidationContext; 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.validation.IValidationRule; import java.math.BigDecimal; -import java.util.Collection; import java.util.Optional; public enum Sdf21ValidationRule implements IValidationRule> { - - AccountPresent() { + Fields() { @Override public Optional validate(ImdgValidationContext context) { - SDf21 sdf21 = context.getValidatedObject(); - if (TextUtil.isEmpty(sdf21.getDepoCodeCl())) { - return of(ClearingError.AccountNotPresent, sdf21.getDepoCodeCl()); + SDf21 validatedObject = context.getValidatedObject(); + + if (TextUtil.isEmpty(validatedObject.getOperationCode())) { + return of(ClearingError.WrongField, "operationCode"); } - Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); - Collection account = accountImdg.getCollectionObjectsBySQL( - "account = '%s' and accountType = '%s'".formatted(sdf21.getDepoCodeCl(), AccountType.Depo.getKey()) - ); - if (account.size() != 1) { - return of(ClearingError.AccountNotPresent, sdf21.getDepoCodeCl()); + OperationCode opCde = IEnumKey.getEnumByKey(OperationCode.class, validatedObject.getOperationCode()); + if (opCde == null) { + return of(ClearingError.WrongField, "operationCode"); } - context.storeObject(ValidationStored.Sdf21Account, account.iterator().next()); - return empty(); + context.storeObject(ValidationStored.Sdf21OperationCode, opCde); + + if (TextUtil.isEmpty(validatedObject.getDepoCodeCl()) && TextUtil.isEmpty(validatedObject.getDepoCodeCorr())) { + return of(ClearingError.WrongField, "depoCodeCl/depoCodeCorr"); + } + return Optional.empty(); } }, + AccountClPresent() { + @Override + public Optional validate(ImdgValidationContext 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 validate(ImdgValidationContext context) { +// SDf21 sdf21 = context.getValidatedObject(); +// if (TextUtil.isEmpty(sdf21.getDepoCodeCl())) { +// return of(ClearingError.AccountNotPresent, sdf21.getDepoCodeCl()); +// } +// Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); +// Collection 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() { @Override public Optional validate(ImdgValidationContext context) { diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/ValidationStored.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/ValidationStored.java index c5a0efe7c..d4fcc8047 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/ValidationStored.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/ValidationStored.java @@ -12,7 +12,7 @@ public enum ValidationStored { Sdf10Company, Sdf10Account, Sdf10DepoAccount, Sdf10Tcr, - Sdf21Account, + Sdf21Account, Sdf21AccountCl, Sdf21AccountCorr, Sdf21CompanyCl, Sdf21CompanyCorr, Sdf21OperationCode, PIOutboundAccountDeb, PIOutboundAccountCred, diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/validation/rule/AccWithTypeValidationRule.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/validation/rule/AccWithTypeValidationRule.java new file mode 100644 index 000000000..352255af2 --- /dev/null +++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/validation/rule/AccWithTypeValidationRule.java @@ -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 implements IValidationRule> { + private final Function accountExtractor; + private final AccountType accountType; + private final Enum storeEnum; + private final IErrorEnumId errMsg; + + private AccWithTypeValidationRule(Function accountExtractor, + AccountType accountType, + Enum storeEnum, + IErrorEnumId errMsg) { + this.accountExtractor = accountExtractor; + this.accountType = accountType; + this.storeEnum = storeEnum; + this.errMsg = errMsg; + } + + public static AccWithTypeValidationRule instance(Function accountExtractor, + AccountType accountType, + Enum storeEnum, + IErrorEnumId errMsg) { + return new AccWithTypeValidationRule<>(accountExtractor, accountType, storeEnum, errMsg); + } + + + @Override + public Optional validate(ImdgValidationContext context) { + T validatedObject = context.getValidatedObject(); + String account = accountExtractor.apply(validatedObject); + if (TextUtil.isEmpty(account)) { + return empty(); + } + Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, SpcexObjectBase.class); + Collection 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(); + } +} \ No newline at end of file