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.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
);
};

View file

@ -28,6 +28,7 @@ public enum ClearingError implements IErrorEnumId {
NewDealsNotFound(5423L),
IdentifiedFundsExceedObligations(5424L),
ObligationsAlreadyCalculated(5425L),
MoreThan1Record(5427L),
//ошибки "перенесенные" из balance-service,
CompanyNotFoundB(5211L),
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.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<SDf21> {
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<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);
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<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;
}
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) {
Registry rgsB = rgs.clone();
rgsB.setRegistryUnit(RegistryUnit.B.getKey());
@ -246,7 +353,7 @@ public class Sdf21Executor extends AbstractExecutor<SDf21> {
}
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()));
}
if (!WorkflowStatus.Active.equalsByKey(account.getStatus())) {
@ -286,6 +393,33 @@ public class Sdf21Executor extends AbstractExecutor<SDf21> {
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 при создании нулевым и исхожу из этого

View file

@ -17,31 +17,59 @@ import java.util.function.Function;
public class CompanyByTradingCodeValidationRule<T> implements IValidationRule<ImdgValidationContext<T>> {
private final Function<T, String> tradingCodeExtractor;
private Enum<?> storeEnum;
private boolean mandatory = true;
private CompanyByTradingCodeValidationRule(Function<T, String> tradingCodeExtractor) {
Objects.requireNonNull(tradingCodeExtractor, "cannot create CompanyByDepoCodeValidationRule: depoCodeExtractor is null");
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) {
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
public Optional<EnumMessage> validate(ImdgValidationContext<T> context) {
T validatedObject = context.getValidatedObject();
Imdg<Company> 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<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);
}
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();
}
}

View file

@ -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<ImdgValidationContext<SDf21>> {
AccountPresent() {
Fields() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<SDf21> 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<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());
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<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() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<SDf21> context) {

View file

@ -12,7 +12,7 @@ public enum ValidationStored {
Sdf10Company, Sdf10Account, Sdf10DepoAccount, Sdf10Tcr,
Sdf21Account,
Sdf21Account, Sdf21AccountCl, Sdf21AccountCorr, Sdf21CompanyCl, Sdf21CompanyCorr, Sdf21OperationCode,
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();
}
}