This commit is contained in:
parent
7647a0ff5b
commit
2363c3362c
5 changed files with 223 additions and 1 deletions
|
|
@ -0,0 +1,61 @@
|
|||
package ru.spcex.clearing.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.company.relation.Relation;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.service.validation.ClrngValidationStored;
|
||||
import ru.spcex.clearing.service.validation.ExecutionDepositValidationRule;
|
||||
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||
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.utils.validation.IValidator;
|
||||
import ru.spcex.platform.utils.validation.ValidatorImpl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@Configuration
|
||||
public class ValidationConfig {
|
||||
private final Map<String, Imdg<? extends SpcexObjectBase>> imdgs;
|
||||
|
||||
public ValidationConfig(ImdgProvider imdgProvider) {
|
||||
this.imdgs = new HashMap<>();
|
||||
BiConsumer<String, Class<? extends SpcexObjectBase>> addImdg = (s, aClass) -> imdgs.put(s, imdgProvider.getImdg(s, aClass));
|
||||
addImdg.accept(IMDGDistributedNames.Map_Relation, Relation.class);
|
||||
addImdg.accept(IMDGDistributedNames.Map_Company, Company.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* чтобы во всех валидаторах был один экземпляр Imdg
|
||||
*/
|
||||
private Imdg<?> getImdg(String key) {
|
||||
return imdgs.get(key);
|
||||
}
|
||||
|
||||
private final BiConsumer<ImdgValidationContext<?>, String> addImdg = (context, s)
|
||||
-> context.addImdg(s, getImdg(s));
|
||||
|
||||
@Bean("executionDepositValidator")
|
||||
public BiFunction<ClearingCategory, ExecutionDeposit, IValidator> executionDepositValidator() {
|
||||
return (category, execDeposit) -> {
|
||||
ImdgValidationContext<ExecutionDeposit> context = new ImdgValidationContext<>();
|
||||
context.setValidatedObject(execDeposit);
|
||||
context.storeObject(ClrngValidationStored.categoryPredefined, category);
|
||||
addImdg.accept(context, IMDGDistributedNames.Map_Relation);
|
||||
addImdg.accept(context, IMDGDistributedNames.Map_Company);
|
||||
return new ValidatorImpl<>(context,
|
||||
ExecutionDepositValidationRule.ClearingIsAllowed,
|
||||
ExecutionDepositValidationRule.AccountIsNotBlocked,
|
||||
ExecutionDepositValidationRule.CompanyIsNotBlocked,
|
||||
ExecutionDepositValidationRule.FinancialObligationSecurity);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package ru.spcex.clearing.error;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.IEnumId;
|
||||
|
||||
public enum ClearingErrorInternal implements IEnumId {
|
||||
ClearingNotAllowed(1L),
|
||||
AccountNotActive(2L),
|
||||
CompanyNotActive(3L),
|
||||
FinancialObligationNotSatisfied(4L),
|
||||
;
|
||||
private final Long id;
|
||||
|
||||
ClearingErrorInternal(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +1,44 @@
|
|||
package ru.spcex.clearing.service;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
||||
import ru.clearing.classes.statics.data.generated.ClearingMemberCategory;
|
||||
import ru.spcex.clearing.error.ClearingErrorInternal;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.service.order.ExecutionDepositSorter;
|
||||
import ru.spcex.platform.enumeration.Allowed;
|
||||
import ru.spcex.platform.enumeration.ClearingCategory;
|
||||
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.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@Service
|
||||
public class Clearing {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Imdg<ExecutionDeposit> executionDepositImdg;
|
||||
private final Imdg<ClearingMemberCategory> clearingCategoryImdg;
|
||||
private final ExecutionDepositSorter sorter;
|
||||
private final BiFunction<ClearingCategory, ExecutionDeposit, IValidator> validation;
|
||||
|
||||
@Autowired
|
||||
public Clearing(ImdgProvider imdgProvider, ExecutionDepositSorter sorter) {
|
||||
public Clearing(ImdgProvider imdgProvider,
|
||||
ExecutionDepositSorter sorter,
|
||||
BiFunction<ClearingCategory, ExecutionDeposit, IValidator> validation) {
|
||||
this.executionDepositImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionDeposit, ExecutionDeposit.class);
|
||||
this.clearingCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
|
||||
this.sorter = sorter;
|
||||
this.validation = validation;
|
||||
}
|
||||
|
||||
public void startClearing() {
|
||||
|
|
@ -41,6 +55,37 @@ public class Clearing {
|
|||
}
|
||||
|
||||
private void processSingleCompany(ClearingCategory category, List<ExecDepositWCategory> executionDeposits) {
|
||||
log.info("Start clearing for category: {}, company: {}", category, executionDeposits.get(0).getCompanyId());
|
||||
boolean financialError = false;
|
||||
for (ExecDepositWCategory execDepositWrapper : executionDeposits) {
|
||||
ExecutionDeposit execDeposit = execDepositWrapper.getExecutionDeposit();
|
||||
if (financialError) {
|
||||
updateDenied(execDeposit);
|
||||
continue;
|
||||
}
|
||||
IValidator validator = validation.apply(category, execDeposit);
|
||||
Optional<EnumMessage> errorMsg = validator.tillFirstError();
|
||||
if (errorMsg.isPresent() && !ClearingErrorInternal.FinancialObligationNotSatisfied.equals(errorMsg.get().getSubject())) {
|
||||
updateDenied(execDeposit);
|
||||
continue;
|
||||
} else if (errorMsg.isPresent()) {
|
||||
financialError = true;
|
||||
updateDenied(execDeposit);
|
||||
continue;
|
||||
}
|
||||
updateAllowed(execDeposit);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDenied(ExecutionDeposit execDeposit) {
|
||||
execDeposit.setCoverageStatus(Allowed.DENIED.getKey());
|
||||
execDeposit.setUpdated(Instant.now());
|
||||
executionDepositImdg.update(execDeposit);
|
||||
}
|
||||
|
||||
private void updateAllowed(ExecutionDeposit execDeposit) {
|
||||
execDeposit.setCoverageStatus(Allowed.ALLOWED.getKey());
|
||||
execDeposit.setUpdated(Instant.now());
|
||||
executionDepositImdg.update(execDeposit);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
package ru.spcex.clearing.service.validation;
|
||||
|
||||
public enum ClrngValidationStored {
|
||||
relation, categoryPredefined
|
||||
;
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package ru.spcex.clearing.service.validation;
|
||||
|
||||
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.company.relation.Relation;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
||||
import ru.spcex.clearing.error.ClearingErrorInternal;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.platform.enumeration.AccountStatus;
|
||||
import ru.spcex.platform.enumeration.ClearingCategory;
|
||||
import ru.spcex.platform.enumeration.ServiceStatus;
|
||||
import ru.spcex.platform.enumeration.WorkflowStatus;
|
||||
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.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public enum ExecutionDepositValidationRule implements IValidationRule<ImdgValidationContext<ExecutionDeposit>> {
|
||||
ClearingIsAllowed() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<ExecutionDeposit> context) {
|
||||
ExecutionDeposit validatedObject = context.getValidatedObject();
|
||||
Imdg<Relation> relationImdg = context.obtainMap(IMDGDistributedNames.Map_Relation, Relation.class);
|
||||
Relation relation = relationImdg.getSingleObjectByFieldValues(Map.of("consumerId", validatedObject.getCompanyId()));
|
||||
if (relation == null || !ServiceStatus.Active.equalsByKey(relation.getServiceStatus())) {
|
||||
return of(ClearingErrorInternal.ClearingNotAllowed);
|
||||
}
|
||||
context.storeObject(ClrngValidationStored.relation, relation);
|
||||
return empty();
|
||||
}
|
||||
},
|
||||
AccountIsNotBlocked() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<ExecutionDeposit> context) {
|
||||
ExecutionDeposit validatedObject = context.getValidatedObject();
|
||||
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
|
||||
Relation relation = context.getStoredObject(ClrngValidationStored.relation);
|
||||
Account account = accountImdg.getSingleObjectByFieldValues(
|
||||
Map.of("id", validatedObject.getAccountId(), "relationId", relation.getId()));
|
||||
if (account == null || !AccountStatus.ACTIVE.equalsByKey(account.getAccountStatus())) {
|
||||
return of(ClearingErrorInternal.AccountNotActive);
|
||||
}
|
||||
return empty();
|
||||
}
|
||||
},
|
||||
CompanyIsNotBlocked() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<ExecutionDeposit> context) {
|
||||
ExecutionDeposit validatedObject = context.getValidatedObject();
|
||||
Imdg<Company> companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class);
|
||||
Company company = companyImdg.getSingleObjectByFieldValues(Map.of("id", validatedObject.getCompanyId()));
|
||||
if (company == null || !WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) {
|
||||
return of(ClearingErrorInternal.CompanyNotActive);
|
||||
}
|
||||
return empty();
|
||||
}
|
||||
},
|
||||
FinancialObligationSecurity() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<ExecutionDeposit> context) {
|
||||
ClearingCategory category = context.getStoredObject(ClrngValidationStored.categoryPredefined);
|
||||
if (!category.equals(ClearingCategory.V)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
ExecutionDeposit validatedObject = context.getValidatedObject();
|
||||
Imdg<AccountBalance> accountBalanceImdg = context.obtainMap(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class);
|
||||
AccountBalance accountBalance = accountBalanceImdg.getSingleObjectByFieldValues(
|
||||
Map.of("accountId", validatedObject.getAccountId(),
|
||||
"companyId", validatedObject.getCompanyId()));
|
||||
if (accountBalance == null) {
|
||||
return of(ClearingErrorInternal.FinancialObligationNotSatisfied);
|
||||
}
|
||||
//todo ABS
|
||||
if (validatedObject.getFirstLegAmount().compareTo(accountBalance.getFreeBalanceAmount()) > 0) {
|
||||
return of(ClearingErrorInternal.FinancialObligationNotSatisfied);
|
||||
}
|
||||
return empty();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String ruleName() {
|
||||
return "Sdf09ValidationRule." + name();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue