diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/AccountNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/AccountNewAction.java index 7c428a8c9..b6cd22d8f 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/AccountNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/AccountNewAction.java @@ -30,18 +30,6 @@ public class AccountNewAction implements IAction { @JsonProperty private String accountType; - @Override - public Collection validate() { - List errors = new ArrayList<>(); - if (this.companyId == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "companyId")); - if (!StringUtils.hasLength(this.account)) - errors.add(new EnumMessage(BackEndError.ValidationError, "account")); - if (!StringUtils.hasLength(this.accountType)) - errors.add(new EnumMessage(BackEndError.ValidationError, "accountType")); - return errors.isEmpty() ? Collections.emptyList() : errors; - } - @Override public AccountNewRequest toRequest() { var req = new AccountNewRequest(); diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/AccountUpdateAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/AccountUpdateAction.java index 9bbabc425..9bae6cd20 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/AccountUpdateAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/AccountUpdateAction.java @@ -32,16 +32,6 @@ public class AccountUpdateAction implements IAction { @JsonProperty private String accountType; - @Override - public Collection validate() { - List errors = new ArrayList<>(); - if (this.id == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "id")); - if (!StringUtils.hasLength(this.accountType)) - errors.add(new EnumMessage(BackEndError.ValidationError, "accountType")); - return errors.isEmpty() ? Collections.emptyList() : errors; - } - @Override public AccountUpdateRequest toRequest() { var req = new AccountUpdateRequest(); diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/BankAccountNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/BankAccountNewAction.java index a758e3e93..694729b3e 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/BankAccountNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/BankAccountNewAction.java @@ -51,31 +51,18 @@ public class BankAccountNewAction implements IAction { @Override public Collection validate() { List errors = new ArrayList<>(); - if (!StringUtils.hasLength(this.bankIdentificationCode)) - errors.add(new EnumMessage(BackEndError.ValidationError, "bankIdentificationCode")); - if (!StringUtils.hasLength(this.bankName)) - errors.add(new EnumMessage(BackEndError.ValidationError, "bankIdentificationCode")); if ("RUB".equalsIgnoreCase(this.currency) && !StringUtils.hasLength(correspondentAccount)) { errors.add(new EnumMessage(BackEndError.ValidationError, "correspondentAccount")); } if ("RUB".equalsIgnoreCase(this.currency) && !StringUtils.hasLength(correspondentAccountName)) { errors.add(new EnumMessage(BackEndError.ValidationError, "correspondentAccountName")); } - if (!StringUtils.hasLength(currency)) { - errors.add(new EnumMessage(BackEndError.ValidationError, "currency")); - } - if (!StringUtils.hasLength(destination)) { - errors.add(new EnumMessage(BackEndError.ValidationError, "destination")); - } if ("RUB".equalsIgnoreCase(this.currency) && !StringUtils.hasLength(taxpayerIdentificationNumber)) { errors.add(new EnumMessage(BackEndError.ValidationError, "taxpayerIdentificationNumber")); } if ("RUB".equalsIgnoreCase(this.currency) && !StringUtils.hasLength(taxRegistrationReasonCode)) { errors.add(new EnumMessage(BackEndError.ValidationError, "taxRegistrationReasonCode")); } - if (TextUtil.isEmpty(account)) { - errors.add(new EnumMessage(BackEndError.ValidationError, "account")); - } return errors.isEmpty() ? Collections.emptyList() : errors; } @@ -172,4 +159,12 @@ public class BankAccountNewAction implements IAction { public void setAccount(String account) { this.account = account; } + + public Long getCompanyId() { + return companyId; + } + + public void setCompanyId(Long companyId) { + this.companyId = companyId; + } } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/BankAccountUpdateAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/BankAccountUpdateAction.java index 326bfed47..f5073d567 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/BankAccountUpdateAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/BankAccountUpdateAction.java @@ -42,11 +42,6 @@ public class BankAccountUpdateAction implements IAction validate() { - return Collections.emptyList(); - } - @Override public BankAccountUpdateRequest toRequest() { var req = new BankAccountUpdateRequest(); diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/ClientCodeNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/ClientCodeNewAction.java index ef0a6b1b1..527f1881f 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/ClientCodeNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/ClientCodeNewAction.java @@ -35,16 +35,6 @@ public class ClientCodeNewAction implements IAction { @JsonProperty private String status; - @Override - public Collection validate() { - List errors = new ArrayList<>(); - if (this.companyId == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "companyId")); - if (!StringUtils.hasLength(this.code)) - errors.add(new EnumMessage(BackEndError.ValidationError, "code")); - return errors.isEmpty() ? Collections.emptyList() : errors; - } - @Override public ClientCodeNewRequest toRequest() { var req = new ClientCodeNewRequest(); diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/ClientCodeUpdateAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/ClientCodeUpdateAction.java index 97f92a06e..d5ff04da8 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/ClientCodeUpdateAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/ClientCodeUpdateAction.java @@ -36,13 +36,6 @@ public class ClientCodeUpdateAction implements IAction @JsonProperty private String status; - @Override - public Collection validate() { - List errors = new ArrayList<>(); - if (this.id == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "id")); - return errors.isEmpty() ? Collections.emptyList() : errors; - } @Override public ClientCodeUpdateRequest toRequest() { diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/CompanySymbolNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/CompanySymbolNewAction.java index 0ed4dcd1a..2ec0b8681 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/CompanySymbolNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/CompanySymbolNewAction.java @@ -4,9 +4,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModelProperty; import ru.spcex.clearing.backendapi.domain.actions.IAction; import ru.spcex.clearing.platform.messaging.domain.ActionType; -import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolNewRequest; -public class CompanySymbolNewAction implements IAction { +public class CompanySymbolNewAction implements IAction { @ApiModelProperty(value = "Идентификатор Компании", example = "1234") @JsonProperty private Long companyId; @@ -18,8 +18,8 @@ public class CompanySymbolNewAction implements IAction validate() { - List errors = new ArrayList<>(); - if (this.senderId == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "senderId")); - if (this.addresseeId == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "addresseeId")); - return errors.isEmpty() ? Collections.emptyList() : errors; - } - @Override public PIClearingOutbondActionNewRequest toRequest() { var req = new PIClearingOutbondActionNewRequest(); diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/RSplitDepositActionNew.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/RSplitDepositActionNew.java index 1abe96c9f..9dc27ad99 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/RSplitDepositActionNew.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/RSplitDepositActionNew.java @@ -37,17 +37,6 @@ public class RSplitDepositActionNew implements IAction validate() { - List errors = new ArrayList<>(); - if (StringUtils.isEmpty(this.contract)) - errors.add(new EnumMessage(BackEndError.ValidationError, "contract")); - if (this.refundDate == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "refundDate")); - if (this.outboundAmount == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "outboundAmount")); - return errors.isEmpty() ? Collections.emptyList() : errors; - } @Override public RegistrySplitDepositActionRequest toRequest() { diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/TradingClearingRegistryNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/TradingClearingRegistryNewAction.java index dacbfd3ce..2e157edf8 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/TradingClearingRegistryNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/TradingClearingRegistryNewAction.java @@ -27,15 +27,6 @@ public class TradingClearingRegistryNewAction implements IAction validate() { - List errors = new ArrayList<>(); - if (this.companyId == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "companyId")); - if (this.moneyAccountId == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "moneyAccountId")); - return errors.isEmpty() ? Collections.emptyList() : errors; - } @Override public TradingClearingRegistryNewRequest toRequest() { diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/TradingClearingRegistryUpdateAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/TradingClearingRegistryUpdateAction.java index f7615a3ac..f10e0f4f8 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/TradingClearingRegistryUpdateAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/TradingClearingRegistryUpdateAction.java @@ -35,15 +35,6 @@ public class TradingClearingRegistryUpdateAction implements IAction validate() { - List errors = new ArrayList<>(); - if (this.id == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "id")); - if (StringUtils.isEmpty(this.status)) - errors.add(new EnumMessage(BackEndError.ValidationError, "status")); - return errors.isEmpty() ? Collections.emptyList() : errors; - } @Override public TradingClearingRegistryUpdateRequest toRequest() { diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/ClearingCalendarNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/ClearingCalendarNewAction.java index 6d17ee7de..5ff82a9f9 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/ClearingCalendarNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/ClearingCalendarNewAction.java @@ -46,18 +46,6 @@ public class ClearingCalendarNewAction implements IAction validate() { - List errors = new ArrayList<>(); - if (clearingDate == null) { - errors.add(new EnumMessage(BackEndError.ValidationError,"clearingDate")); - } - if (TextUtil.isEmpty(dayStatus)) { - errors.add(new EnumMessage(BackEndError.ValidationError,"taskStatus")); - } - return errors; - } - public LocalDate getClearingDate() { return clearingDate; } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/ClearingCalendarUpdateAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/ClearingCalendarUpdateAction.java index b092b1bce..0f16bfb9e 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/ClearingCalendarUpdateAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/ClearingCalendarUpdateAction.java @@ -52,21 +52,6 @@ public class ClearingCalendarUpdateAction implements IAction validate() { - List errors = new ArrayList<>(); - if (id == null) { - errors.add(new EnumMessage(BackEndError.ValidationError,"id")); - } - if (clearingDate == null) { - errors.add(new EnumMessage(BackEndError.ValidationError,"clearingDate")); - } - if (TextUtil.isEmpty(dayStatus)) { - errors.add(new EnumMessage(BackEndError.ValidationError,"taskStatus")); - } - return errors; - } - @Override public Long getId() { return id; diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerNewAction.java index 6867b0fca..6fcaa3836 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerNewAction.java @@ -78,23 +78,6 @@ public class PlannerNewAction implements IAction { return ActionType.NEW; } - @Override - public Collection validate() { - List errors = new ArrayList<>(); - if (TextUtil.isEmpty(task)) { - errors.add(new EnumMessage(BackEndError.ValidationError,"task")); - } - if (taskTime == null) { - errors.add(new EnumMessage(BackEndError.ValidationError,"taskTime")); - } - if (clearingDate == null) { - errors.add(new EnumMessage(BackEndError.ValidationError,"clearingDate")); - } - if (TextUtil.isEmpty(taskStatus)) { - errors.add(new EnumMessage(BackEndError.ValidationError,"taskStatus")); - } - return errors; - } public String getTask() { return task; diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerTemplateNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerTemplateNewAction.java index 3b8ce5635..debf99ebc 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerTemplateNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerTemplateNewAction.java @@ -62,20 +62,6 @@ public class PlannerTemplateNewAction implements IAction validate() { - List errors = new ArrayList<>(); - if (TextUtil.isEmpty(task)) { - errors.add(new EnumMessage(BackEndError.ValidationError,"task")); - } - if (taskTime == null) { - errors.add(new EnumMessage(BackEndError.ValidationError,"taskTime")); - } - if (TextUtil.isEmpty(taskStatus)) { - errors.add(new EnumMessage(BackEndError.ValidationError,"taskStatus")); - } - return errors; - } public String getTask() { return task; diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerTemplateUpdateAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerTemplateUpdateAction.java index 058258d7c..7fe3c1150 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerTemplateUpdateAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerTemplateUpdateAction.java @@ -67,23 +67,6 @@ public class PlannerTemplateUpdateAction implements IAction validate() { - List errors = new ArrayList<>(); - if (id == null) { - errors.add(new EnumMessage(BackEndError.ValidationError,"id")); - } - if (TextUtil.isEmpty(task)) { - errors.add(new EnumMessage(BackEndError.ValidationError,"task")); - } - if (taskTime == null) { - errors.add(new EnumMessage(BackEndError.ValidationError,"taskTime")); - } - if (TextUtil.isEmpty(taskStatus)) { - errors.add(new EnumMessage(BackEndError.ValidationError,"taskStatus")); - } - return errors; - } @Override public Long getId() { diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerUpdateAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerUpdateAction.java index 66fa62fb4..f326d3a76 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerUpdateAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/schedule/PlannerUpdateAction.java @@ -84,27 +84,6 @@ public class PlannerUpdateAction implements IAction, WithI return ActionType.UPDATE; } - @Override - public Collection validate() { - List errors = new ArrayList<>(); - if (id == null) { - errors.add(new EnumMessage(BackEndError.ValidationError,"id")); - } - if (TextUtil.isEmpty(task)) { - errors.add(new EnumMessage(BackEndError.ValidationError,"task")); - } - if (taskTime == null) { - errors.add(new EnumMessage(BackEndError.ValidationError,"taskTime")); - } - if (clearingDate == null) { - errors.add(new EnumMessage(BackEndError.ValidationError,"clearingDate")); - } - if (TextUtil.isEmpty(taskStatus)) { - errors.add(new EnumMessage(BackEndError.ValidationError,"taskStatus")); - } - return errors; - } - @Override public Long getId() { return id; diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/EquitySecurityNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/EquitySecurityNewAction.java index eb062b3af..637b49405 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/EquitySecurityNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/EquitySecurityNewAction.java @@ -51,20 +51,6 @@ public class EquitySecurityNewAction implements IAction validate() { - List errors = new ArrayList<>(); - if (TextUtil.isEmpty(shortName)) - errors.add(new EnumMessage(BackEndError.ValidationError, "shortName")); - if (TextUtil.isEmpty(securitySymbol)) - errors.add(new EnumMessage(BackEndError.ValidationError, "securitySymbol")); - if (lotSize == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "lotSize")); - if (TextUtil.isEmpty(instrumentType)) - errors.add(new EnumMessage(BackEndError.ValidationError, "instrumentType")); - return errors.size() > 0 ? errors : Collections.emptyList(); - } - @Override public EquitySecurityNewRequest toRequest() { var req = new EquitySecurityNewRequest(); diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/EquitySecurityUpdateAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/EquitySecurityUpdateAction.java index b60c07046..c94e266a4 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/EquitySecurityUpdateAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/EquitySecurityUpdateAction.java @@ -53,13 +53,6 @@ public class EquitySecurityUpdateAction implements IAction validate() { - List errors = new ArrayList<>(); - if (id == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "id")); - return errors.size() > 0 ? errors : Collections.emptyList(); - } @Override public EquitySecurityUpdateRequest toRequest() { diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/FixedIncomeSecurityNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/FixedIncomeSecurityNewAction.java index 0832d6846..efbdbb538 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/FixedIncomeSecurityNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/FixedIncomeSecurityNewAction.java @@ -73,19 +73,6 @@ public class FixedIncomeSecurityNewAction implements IAction validate() { - List errors = new ArrayList<>(); - if (TextUtil.isEmpty(securitySymbol)) - errors.add(new EnumMessage(BackEndError.ValidationError, "securitySymbol")); - if (TextUtil.isEmpty(shortName)) - errors.add(new EnumMessage(BackEndError.ValidationError, "shortName")); - if (lotSize == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "lotSize")); - if (TextUtil.isEmpty(instrumentType)) - errors.add(new EnumMessage(BackEndError.ValidationError, "instrumentType")); - return errors.size() > 0 ? errors : Collections.emptyList(); - } @Override public FixedIncomeSecurityNewRequest toRequest() { diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/FixedIncomeSecurityUpdateAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/FixedIncomeSecurityUpdateAction.java index 1ea013ee6..87734f1eb 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/FixedIncomeSecurityUpdateAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/FixedIncomeSecurityUpdateAction.java @@ -75,14 +75,6 @@ public class FixedIncomeSecurityUpdateAction implements IAction validate() { - List errors = new ArrayList<>(); - if (id == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "id")); - return errors.size() > 0 ? errors : Collections.emptyList(); - } - @Override public FixedIncomeSecurityUpdateRequest toRequest() { var req = new FixedIncomeSecurityUpdateRequest(); diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java index e8c258b59..b24ad5e04 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java @@ -74,29 +74,6 @@ public class MoneyMarketSecurityNewAction implements IAction validate() { - List errors = new ArrayList<>(); - if (TextUtil.isEmpty(securitySymbol)) - errors.add(new EnumMessage(BackEndError.ValidationError, "securitySymbol")); - if (TextUtil.isEmpty(shortName)) - errors.add(new EnumMessage(BackEndError.ValidationError, "shortName")); - if (this.lotSize == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "lotSize")); - if (this.nominalValue == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "nominalValue")); - if (TextUtil.isEmpty(nominalCurrency)) - errors.add(new EnumMessage(BackEndError.ValidationError, "nominalCurrency")); - if (this.startDate == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "startDate")); - if (this.endDate == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "endDate")); - if (this.termType == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "termType")); - if (TextUtil.isEmpty(instrumentType)) - errors.add(new EnumMessage(BackEndError.ValidationError, "instrumentType")); - return errors.size() > 0 ? errors : Collections.emptyList(); - } @Override public MoneyMarketSecurityNewRequest toRequest() { diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityUpdateAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityUpdateAction.java index 1ac00a5eb..8ab36a8f4 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityUpdateAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityUpdateAction.java @@ -99,14 +99,6 @@ public class MoneyMarketSecurityUpdateAction implements IAction validate() { - List errors = new ArrayList<>(); - if (this.id == null) - errors.add(new EnumMessage(BackEndError.ValidationError, "id")); - return errors.size() > 0 ? errors : Collections.emptyList(); - } - @ApiModelProperty(hidden = true) @Override public ActionType getActionType() { diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/MetaServer.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/MetaServer.java index e345d0911..82557d2ba 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/MetaServer.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/MetaServer.java @@ -82,7 +82,9 @@ public class MetaServer extends MetaBase { log.warn("META SERVER >>> {}", e.getLocalizedMessage()); continue; } - actionObjectsExtracted.put(actionElement.getDestination(), oe); + String actionDestination = // обычно бывают =null о этому эффективнее по имени класса а не по: objectElement.getSubscription().destination + "/"+ actionElement.getDestination(); + oe.getClassName(); + actionObjectsExtracted.put(actionDestination, oe); } } } catch (Throwable e) { diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/impl/OperatorImpl.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/impl/OperatorImpl.java index 3757706ad..009d24485 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/impl/OperatorImpl.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/impl/OperatorImpl.java @@ -17,6 +17,7 @@ import ru.spcex.clearing.backendapi.errors.BackEndError; import ru.spcex.clearing.backendapi.errors.NotFound404Exception; import ru.spcex.clearing.backendapi.security.KeycloakUtils; import ru.spcex.clearing.backendapi.service.IOperator; +import ru.spcex.clearing.backendapi.service.validation.ActionMetaValidation; import ru.spcex.clearing.backendapi.service.validation.ActionValidationProvider; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; @@ -39,13 +40,16 @@ public class OperatorImpl implements IOperator { private final Producer kafka; private final ImdgId idGenerator; private final ImdgProvider imdgProvider; + private final ActionMetaValidation actionMetaValidation; private final ActionValidationProvider validation; private final Imdg userImdg; - public OperatorImpl(Producer kafka, ImdgProvider imdgProvider, ActionValidationProvider validation) { + public OperatorImpl(Producer kafka, ImdgProvider imdgProvider, + ActionMetaValidation actionMetaValidation, ActionValidationProvider validation) { this.kafka = kafka; this.idGenerator = imdgProvider.getImdgIdGenerator(); this.imdgProvider = imdgProvider; + this.actionMetaValidation = actionMetaValidation; this.validation = validation; this.userImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_User, User.class); } @@ -112,6 +116,18 @@ public class OperatorImpl implements IOperator { if (validationErrors.size() > 0) { throw new ActionValidationException(validationErrors); } + // Валидация по мете (рекомендуется использовать её,а не iAction.validate(); + IValidator metaValidator = actionMetaValidation.getValidator(destination, iAction); + if (metaValidator != null) { + metaValidator.tillFirstError().ifPresent(enumMessage -> { + if (enumMessage.getSubject().equalsById(BackEndError.ResourceNotFound.getId())) { + throw new NotFound404Exception(enumMessage); + } else { + throw new ActionValidationException(enumMessage); + } + }); + } + //валидация требующая IMDG поиска других сущностей и т.д. IValidator validator = validation.getValidator(destination, iAction); if (validator != null) { diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/validation/ActionMetaValidation.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/validation/ActionMetaValidation.java new file mode 100644 index 000000000..c9d171354 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/validation/ActionMetaValidation.java @@ -0,0 +1,142 @@ +package ru.spcex.clearing.backendapi.service.validation; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import ru.spcex.clearing.backendapi.controller.request.cud.securities.MoneyMarketSecurityUpdateAction; +import ru.spcex.clearing.backendapi.domain.actions.IAction; +import ru.spcex.clearing.backendapi.errors.BackEndError; +import ru.spcex.clearing.backendapi.meta.FieldExtracted; +import ru.spcex.clearing.backendapi.meta.MetaServer; +import ru.spcex.clearing.backendapi.meta.ObjectExtracted; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; +import ru.spcex.platform.utils.validation.IValidator; +import ru.spcex.platform.utils.validation.ValidatorImpl; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; + +/** + * Проверка обязательности полей для IAction по мете + */ +@Component +public class ActionMetaValidation implements InitializingBean { + protected static final Logger log = LoggerFactory.getLogger(ActionMetaValidation.class); + protected final Map> validators; + protected final MetaServer meta; + + @Autowired + public ActionMetaValidation(MetaServer meta) { + this.validators = new HashMap<>(); + this.meta = meta; + } + + @Override + public void afterPropertiesSet() { + for (Map.Entry entry : meta.getActionObjectsExtracted().entrySet()) { + if (StringUtils.isEmpty(entry.getKey())) continue; + Function validator = validatorConstructor(entry.getValue()); + if (validator == null) continue; + validators.put(entry.getKey(), validator); + } + log.debug("Init {} IAction validator for: {}", validators.size(), validators.keySet()); + } + + @SuppressWarnings("unchecked") + public IValidator getValidator(String destination, Object action) { + if (action == null) + return null; + //if (destination == null) destination = action.getClass().getName(); + String actionDestination = action.getClass().getName(); // см. реализацию в MetaServer String actionDestination =... + Function constructor = (Function) validators.get(actionDestination); + if (constructor != null) + return constructor.apply(action); + return null; + } + + private Function validatorConstructor(ObjectExtracted metaAction) { + if (!metaAction.getFields().stream().anyMatch(field -> field.getField().isRequired())) { + log.debug("Action {}: no any required fields. Do not need validator.", metaAction.getClassName()); + // нет обязательных полей для валидации + return null; + } + // Тестирование getter + { + Object object; + try { + object = metaAction.getClazz().getDeclaredConstructor().newInstance(); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new RuntimeException("Error self-test validator on class " + metaAction.getClazz(), e); + } + for (FieldExtracted field : metaAction.getFields()) { + try { + if (field.getField().isRequired() != null && field.getField().isRequired()) { + Object value = field.extractValue(object); + } + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + log.warn("Error self-test validator on class {} and field {}: {}", + metaAction.getClazz(), field.getMemberName(), ExceptionUtils.getStackTrace(e)); + } + } + } + final MetaValidatorRule metaValidatorRule = new MetaValidatorRule(metaAction); + return iAcc -> { + ImdgValidationContext ctx = new ImdgValidationContext<>(); + ctx.setValidatedObject(iAcc); + ValidatorImpl> iValidator = new ValidatorImpl(ctx); + iValidator.addRule(metaValidatorRule); + // в дальнейшем можно улучшить и разделить валидатор по полям + return iValidator; + }; + } + + static class MetaValidatorRule implements IValidationRule> { + public final ObjectExtracted metaAction; + + public MetaValidatorRule(ObjectExtracted metaAction) { + this.metaAction = metaAction; + } + + @Override + public Optional validate(ImdgValidationContext context) { + IAction object = context.getValidatedObject(); + for (FieldExtracted field : metaAction.getFields()) { + try { + if (field.getField().isRequired() != null && field.getField().isRequired()) { + Object value = field.extractValue(object); + if (value == null) + return of(BackEndError.ValidationError, field.getMemberName()); +// if (value instanceof String && ((String)value).isEmpty()) // пустое поле, но не null +// return of(BackEndError.ValidationError, field.getMemberName()); + } + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + if (object instanceof MoneyMarketSecurityUpdateAction) { + //todo в мете для moneyMarketSecurity / actions / put / для поля lotSize field="securityId" исключение - там надо оставить field, требуется для frontend + if (((MoneyMarketSecurityUpdateAction) object).getLotSize() == null) + return of(BackEndError.ValidationError, "LotSize"); + } else { + log.warn("Error apply meta-validator {} for {} : {}", + metaAction, object, e.toString()); + } + } + } + return empty(); + } + + @Override + public String ruleName() { + return getClass().getSimpleName() + " of " + metaAction.getClassName(); + } + + } + +} diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.json b/clearing-parent/backend-api/src/main/resources/meta/meta.json index 84394d492..00716c327 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.json +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.json @@ -2501,6 +2501,8 @@ "confirmation": "securitySymbol,shortName,fullName,lotSize,nominalValue,nominalCurrency", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.securities.MoneyMarketSecurityNewAction", + "fields": [ {"code": "instrumentType", "type": 12,"name": "Наименование типа инструмента","shortname": "Тип инструмента","link": "instrumentType","required": true,"enabled": false @@ -2578,6 +2580,8 @@ "confirmation": "securitySymbol,shortName,fullName,lotSize,nominalValue,nominalCurrency", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.securities.MoneyMarketSecurityUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "moneyMarketSecurity","linkCode": "id","required": true @@ -2770,6 +2774,8 @@ "confirmation": "securitySymbol,shortName,fullName,isin,shareType", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.securities.EquitySecurityNewAction", + "fields": [ {"code": "instrumentType", "type": 12,"name": "Наименование типа инструмента","shortname": "Тип инструмента","link": "instrumentType","required": true,"enabled": false @@ -2823,6 +2829,8 @@ "confirmation": "securitySymbol,shortName,fullName,isin,shareType", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.securities.EquitySecurityUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "equitySecurity","linkCode": "id","required": true @@ -2981,6 +2989,8 @@ "confirmation": "securitySymbol,shortName,fullName,isin,bondType,nominalValue,nominalCurrency", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.securities.FixedIncomeSecurityNewAction", + "fields": [ {"code": "instrumentType", "type": 12,"name": "Наименование типа инструмента","shortname": "Тип инструмента","link": "instrumentType","required": true,"enabled": false @@ -3054,6 +3064,8 @@ "confirmation": "securitySymbol,shortName,fullName,isin,bondType,nominalValue,nominalCurrency", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.securities.FixedIncomeSecurityUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "fixedIncomeSecurity","linkCode": "id","required": true @@ -3131,6 +3143,8 @@ "confirmation": "securitySymbol,shortName", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "fixedIncomeSecurity","linkCode": "id","required": true @@ -3505,6 +3519,8 @@ "confirmation": "companyId,code,tradingClearingRegistryId,moneyAccountId,depoAccountId,status", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.account.ClientCodeNewAction", + "fields": [ {"code": "companyId", "type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true,"enabled": false @@ -3538,6 +3554,8 @@ "confirmation": "companyId,code,tradingClearingRegistryId,moneyAccountId,depoAccountId,status", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.account.ClientCodeUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "clientCode","linkCode": "id","required": true @@ -3648,6 +3666,8 @@ "confirmation": "companyId,moneyAccountId,depoAccountId,status", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.TradingClearingRegistryNewAction", + "fields": [ {"code": "companyId", "type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true @@ -3673,6 +3693,8 @@ "confirmation": "companyId,code,moneyAccountId,depoAccountId,status", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.TradingClearingRegistryUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "clientCode","linkCode": "id","required": true @@ -3925,6 +3947,8 @@ "confirmation": "contract,outboundAmount,refundDate", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.RSplitDepositActionNew", + "fields": [ {"code": "contract", "type": 2,"length": 255,"name": "Договор","shortname": "Договор","required": true @@ -4006,6 +4030,8 @@ "confirmation": "companyId,account,status", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.account.AccountNewAction", + "fields": [ {"code": "companyId", "type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true @@ -4031,6 +4057,8 @@ "confirmation": "companyId,account,status", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.account.AccountUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "account","linkCode": "id","required": true @@ -4060,6 +4088,8 @@ "confirmation": "companyId,account", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "account","linkCode": "id","required": true @@ -4226,6 +4256,8 @@ "confirmation": "currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account,destination", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountNewAction", + "fields": [ {"code": "currency", "type": 12,"name": "Код валюты","shortname": "Валюта","required": true,"link": "currencyCode","linkCode": "code" @@ -4275,6 +4307,8 @@ "confirmation": "currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account,destination", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "bankAccount","linkCode": "id","required": true @@ -4489,6 +4523,8 @@ "name": "Новый шаблон расписания операционного дня", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.schedule.PlannerTemplateNewAction", + "fields": [ {"code": "task", "type": 12,"name": "Наименование задачи","shortname": "Задача","link": "task","required": true @@ -4524,6 +4560,8 @@ "name": "Изменение шаблона расписания операционного дня", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.schedule.PlannerTemplateUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "plannerTemplate","linkCode": "id","required": true @@ -4614,6 +4652,8 @@ "name": "Добавление записи в календарь", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.schedule.ClearingCalendarNewAction", + "fields": [ {"code": "clearingDate", "type": 6,"name": "Дата","shortname": "Дата","required": true @@ -4633,6 +4673,8 @@ "name": "Изменение записи в календаре", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.schedule.ClearingCalendarUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "clearingCalendar","linkCode": "id","required": true @@ -4731,6 +4773,8 @@ "name": "Новое расписание", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.schedule.PlannerNewAction", + "fields": [ {"code": "task", "type": 12,"name": "Наименование задачи","shortname": "Задача","link": "task","required": true @@ -4770,6 +4814,8 @@ "name": "Изменение расписания", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.schedule.PlannerUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "planner","required": true,"linkCode": "id" @@ -6666,6 +6712,8 @@ "destination": "payment-instructions/clearing-outbound", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.payment.PIClearingOutbondActionNew", + "fields": [ {"code": "senderId", "type": 1,"name": "Участник отправитель","shortname": "Отправитель","link": "company","required": true diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.xml b/clearing-parent/backend-api/src/main/resources/meta/meta.xml index d7d11b810..a7999061e 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.xml +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.xml @@ -578,7 +578,7 @@ - + @@ -597,7 +597,7 @@ - + @@ -643,7 +643,7 @@ - + @@ -656,7 +656,7 @@ - + @@ -695,7 +695,7 @@ - + @@ -713,7 +713,7 @@ - + @@ -732,7 +732,7 @@ - + @@ -818,7 +818,7 @@ - + @@ -826,7 +826,7 @@ - + @@ -853,13 +853,13 @@ - + - + @@ -921,7 +921,7 @@ - + @@ -941,20 +941,20 @@ - + - + - + @@ -995,7 +995,7 @@ - + @@ -1007,7 +1007,7 @@ - + @@ -1055,7 +1055,7 @@ - +
@@ -1064,7 +1064,7 @@ - + @@ -1087,12 +1087,12 @@ - + - + @@ -1117,7 +1117,7 @@ - + @@ -1127,7 +1127,7 @@ - + @@ -1554,7 +1554,7 @@ - + diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/IOperatorTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/IOperatorTest.java index e82944594..c31d29f3c 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/IOperatorTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/IOperatorTest.java @@ -5,7 +5,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import ru.spcex.clearing.backendapi.meta.MetaServer; import ru.spcex.clearing.backendapi.service.impl.OperatorImpl; +import ru.spcex.clearing.backendapi.service.validation.ActionMetaValidation; import ru.spcex.clearing.backendapi.service.validation.ActionValidationProvider; import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; @@ -18,8 +20,9 @@ public class IOperatorTest { @Autowired @Bean("iOperatorTest") - public OperatorImpl createIOperator(Producer kafka, ActionValidationProvider validationProvider) { - return new OperatorImpl(kafka, hazelcastServiceTest, validationProvider); + public OperatorImpl createIOperator(Producer kafka, + ActionMetaValidation actionMetaValidation, ActionValidationProvider validationProvider) { + return new OperatorImpl(kafka, hazelcastServiceTest, actionMetaValidation, validationProvider); } @Bean @@ -27,4 +30,10 @@ public class IOperatorTest { return new ActionValidationProvider(hazelcastServiceTest); } + @Bean + public ActionMetaValidation actionMetaValidation(MetaServer metaServer) { + return new ActionMetaValidation(metaServer); + } + + } diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/service/validation/ActionMetaValidationTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/service/validation/ActionMetaValidationTest.java new file mode 100644 index 000000000..568ea0fd8 --- /dev/null +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/service/validation/ActionMetaValidationTest.java @@ -0,0 +1,94 @@ +package ru.spcex.clearing.backendapi.service.validation; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountNewAction; +import ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction; +import ru.spcex.clearing.backendapi.controller.request.cud.company.ListingNewAction; +import ru.spcex.clearing.backendapi.domain.actions.IAction; +import ru.spcex.clearing.backendapi.meta.GetResponseFactoryTestConfiguration; +import ru.spcex.clearing.backendapi.meta.MetaServer; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumKey; +import ru.spcex.platform.utils.validation.IValidator; + +import java.util.ArrayList; +import java.util.Collection; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = GetResponseFactoryTestConfiguration.class) +class ActionMetaValidationTest { + + @Autowired @Qualifier("metaJsonTest") + protected MetaServer meta; + + @Test + void getValidator() { + ActionMetaValidation metaValidator = new ActionMetaValidation(meta); + metaValidator.afterPropertiesSet(); + + { + IAction action = new ListingNewAction(); + assertTrue(action.validate().isEmpty()); + IValidator v = metaValidator.getValidator(null, action); + assertNull(v, "Пока не прописан в мете"); + } + { + IAction action = new CommonDeleteAction(); + assertFalse(action.validate().isEmpty()); // стандартный валидатор - требуется id + + IValidator v = metaValidator.getValidator(null, action); + Collection vResult = v.validateAll(); + assertEquals("[EnumMessage{subject=ValidationError, args: [id]}]", vResult.toString()); + } + { + CommonDeleteAction action = new CommonDeleteAction(); + action.setId(123L); + assertTrue(action.validate().isEmpty()); // стандартный валидатор - требуется id + + IValidator v = metaValidator.getValidator(null, action); + Collection vResult = v.validateAll(); + assertEquals("[]", vResult.toString()); + } + } + + @Test + void testForBankAccountNewAction() { + ActionMetaValidation metaValidator = new ActionMetaValidation(meta); + metaValidator.afterPropertiesSet(); + + { + BankAccountNewAction action = new BankAccountNewAction(); + assertTrue(action.validate().isEmpty()); + IValidator v = metaValidator.getValidator(null, action); + assertNotNull(v); + Collection vResult = v.validateAll(); + assertEquals("[EnumMessage{subject=ValidationError, args: [currency]}]", vResult.toString()); + } + { + BankAccountNewAction action = new BankAccountNewAction(); + action.setBankIdentificationCode("Hello world"); + action.setBankName("Hello world"); + action.setCorrespondentAccount("Hello world"); + action.setCorrespondentAccountName("Hello world"); + action.setCurrency("Hello world"); + action.setDestination("Hello world"); + action.setTaxpayerIdentificationNumber("Hello world"); + action.setTaxRegistrationReasonCode("Hello world"); + action.setAccount("Hello world"); + action.setCompanyId(123L); + + IValidator v = metaValidator.getValidator(null, action); + assertNotNull(v); + Collection vResult = v.validateAll(); + assertEquals("[]", vResult.toString()); + } + } + +} \ No newline at end of file diff --git a/clearing-parent/backend-api/src/test/resources/meta.json b/clearing-parent/backend-api/src/test/resources/meta.json index 84394d492..00716c327 100644 --- a/clearing-parent/backend-api/src/test/resources/meta.json +++ b/clearing-parent/backend-api/src/test/resources/meta.json @@ -2501,6 +2501,8 @@ "confirmation": "securitySymbol,shortName,fullName,lotSize,nominalValue,nominalCurrency", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.securities.MoneyMarketSecurityNewAction", + "fields": [ {"code": "instrumentType", "type": 12,"name": "Наименование типа инструмента","shortname": "Тип инструмента","link": "instrumentType","required": true,"enabled": false @@ -2578,6 +2580,8 @@ "confirmation": "securitySymbol,shortName,fullName,lotSize,nominalValue,nominalCurrency", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.securities.MoneyMarketSecurityUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "moneyMarketSecurity","linkCode": "id","required": true @@ -2770,6 +2774,8 @@ "confirmation": "securitySymbol,shortName,fullName,isin,shareType", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.securities.EquitySecurityNewAction", + "fields": [ {"code": "instrumentType", "type": 12,"name": "Наименование типа инструмента","shortname": "Тип инструмента","link": "instrumentType","required": true,"enabled": false @@ -2823,6 +2829,8 @@ "confirmation": "securitySymbol,shortName,fullName,isin,shareType", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.securities.EquitySecurityUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "equitySecurity","linkCode": "id","required": true @@ -2981,6 +2989,8 @@ "confirmation": "securitySymbol,shortName,fullName,isin,bondType,nominalValue,nominalCurrency", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.securities.FixedIncomeSecurityNewAction", + "fields": [ {"code": "instrumentType", "type": 12,"name": "Наименование типа инструмента","shortname": "Тип инструмента","link": "instrumentType","required": true,"enabled": false @@ -3054,6 +3064,8 @@ "confirmation": "securitySymbol,shortName,fullName,isin,bondType,nominalValue,nominalCurrency", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.securities.FixedIncomeSecurityUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "fixedIncomeSecurity","linkCode": "id","required": true @@ -3131,6 +3143,8 @@ "confirmation": "securitySymbol,shortName", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "fixedIncomeSecurity","linkCode": "id","required": true @@ -3505,6 +3519,8 @@ "confirmation": "companyId,code,tradingClearingRegistryId,moneyAccountId,depoAccountId,status", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.account.ClientCodeNewAction", + "fields": [ {"code": "companyId", "type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true,"enabled": false @@ -3538,6 +3554,8 @@ "confirmation": "companyId,code,tradingClearingRegistryId,moneyAccountId,depoAccountId,status", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.account.ClientCodeUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "clientCode","linkCode": "id","required": true @@ -3648,6 +3666,8 @@ "confirmation": "companyId,moneyAccountId,depoAccountId,status", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.TradingClearingRegistryNewAction", + "fields": [ {"code": "companyId", "type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true @@ -3673,6 +3693,8 @@ "confirmation": "companyId,code,moneyAccountId,depoAccountId,status", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.TradingClearingRegistryUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "clientCode","linkCode": "id","required": true @@ -3925,6 +3947,8 @@ "confirmation": "contract,outboundAmount,refundDate", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.registry.RSplitDepositActionNew", + "fields": [ {"code": "contract", "type": 2,"length": 255,"name": "Договор","shortname": "Договор","required": true @@ -4006,6 +4030,8 @@ "confirmation": "companyId,account,status", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.account.AccountNewAction", + "fields": [ {"code": "companyId", "type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true @@ -4031,6 +4057,8 @@ "confirmation": "companyId,account,status", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.account.AccountUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "account","linkCode": "id","required": true @@ -4060,6 +4088,8 @@ "confirmation": "companyId,account", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "account","linkCode": "id","required": true @@ -4226,6 +4256,8 @@ "confirmation": "currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account,destination", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountNewAction", + "fields": [ {"code": "currency", "type": 12,"name": "Код валюты","shortname": "Валюта","required": true,"link": "currencyCode","linkCode": "code" @@ -4275,6 +4307,8 @@ "confirmation": "currency,bankIdentificationCode,bankName,correspondentAccount,correspondentAccountName,taxpayerIdentificationNumber,taxRegistrationReasonCode,account,destination", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "bankAccount","linkCode": "id","required": true @@ -4489,6 +4523,8 @@ "name": "Новый шаблон расписания операционного дня", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.schedule.PlannerTemplateNewAction", + "fields": [ {"code": "task", "type": 12,"name": "Наименование задачи","shortname": "Задача","link": "task","required": true @@ -4524,6 +4560,8 @@ "name": "Изменение шаблона расписания операционного дня", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.schedule.PlannerTemplateUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "plannerTemplate","linkCode": "id","required": true @@ -4614,6 +4652,8 @@ "name": "Добавление записи в календарь", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.schedule.ClearingCalendarNewAction", + "fields": [ {"code": "clearingDate", "type": 6,"name": "Дата","shortname": "Дата","required": true @@ -4633,6 +4673,8 @@ "name": "Изменение записи в календаре", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.schedule.ClearingCalendarUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "clearingCalendar","linkCode": "id","required": true @@ -4731,6 +4773,8 @@ "name": "Новое расписание", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.schedule.PlannerNewAction", + "fields": [ {"code": "task", "type": 12,"name": "Наименование задачи","shortname": "Задача","link": "task","required": true @@ -4770,6 +4814,8 @@ "name": "Изменение расписания", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.schedule.PlannerUpdateAction", + "fields": [ {"code": "id", "type": 1,"name": "Идентификатор записи","shortname": "ID","link": "planner","required": true,"linkCode": "id" @@ -6666,6 +6712,8 @@ "destination": "payment-instructions/clearing-outbound", + "class": "ru.spcex.clearing.backendapi.controller.request.cud.payment.PIClearingOutbondActionNew", + "fields": [ {"code": "senderId", "type": 1,"name": "Участник отправитель","shortname": "Отправитель","link": "company","required": true diff --git a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/registry/Registry.java b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/registry/Registry.java index 93836225e..dd68a819e 100644 --- a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/registry/Registry.java +++ b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/registry/Registry.java @@ -2,10 +2,8 @@ package ru.clearing.classes.statics.data.registry; import ru.clearing.classes.ConstSerializable; import ru.clearing.classes.objects.BusinessObject; -import ru.spcex.platform.classes.base.SpcexObjectBase; import java.math.BigDecimal; -import java.time.Instant; import java.time.LocalDate; /** @@ -414,9 +412,9 @@ public class Registry extends BusinessObject implements Cloneable { } @Override - public Object clone() { + public Registry clone() { try { - return super.clone(); + return (Registry) super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException("never", e); // it is Cloneable } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/SdfExecutorsConfig.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/SdfExecutorsConfig.java index 86a1142e9..03fe117b0 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/SdfExecutorsConfig.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/SdfExecutorsConfig.java @@ -2,9 +2,8 @@ package ru.spcex.clearing.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import ru.spcex.clearing.service.executors.AbstractExecutor; -import ru.spcex.clearing.service.executors.Sdf01Executor; -import ru.spcex.clearing.service.executors.Sdf57Executor; +import ru.spcex.clearing.service.executors.*; +import ru.spcex.clearing.service.executors.SdfLegacyExecutor; import ru.spcex.platform.enumeration.SdfTable; import java.util.HashMap; @@ -14,11 +13,15 @@ import java.util.Map; public class SdfExecutorsConfig { @Bean("sdfExecutors") - public Map> executorsMap(Sdf01Executor sdf01Executor, - Sdf57Executor sdf57Executor) { + public Map> executorsMap(SdfLegacyExecutor sdf01Executor, + Sdf57Executor sdf57Executor, + Sdf04Executor sdf04Executor, + Sdf13Executor sdf13Executor) { Map> executors = new HashMap<>(); executors.put(SdfTable.SDF_01, sdf01Executor); executors.put(SdfTable.SDF_57, sdf57Executor); + executors.put(SdfTable.SDF_04, sdf04Executor); + executors.put(SdfTable.SDF_13, sdf13Executor); return executors; } } 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 afa056312..4ad5956a6 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 @@ -140,4 +140,22 @@ public class ValidationConfig { ); }; } + + @Bean("sdf01ValidatorNew") + public Function sdf01ValidatorNew() { + return sDf01 -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(sDf01); + Consumer addImdg = (s) -> context.addImdg(s, getImdg(s)); + addImdg.accept(IMDGDistributedNames.Map_Account); + addImdg.accept(IMDGDistributedNames.Map_Company); + return new ValidatorImpl<>(context, + Sdf01NewValidationRule.CompanyPresent, + Sdf01NewValidationRule.AccountType, + Sdf01NewValidationRule.AccountPresent, + Sdf01NewValidationRule.CurrencyCode, + Sdf01NewValidationRule.DatIsCurrentDt + ); + }; + } } 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 578fd53ac..085fa9555 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 @@ -19,6 +19,11 @@ public enum ClearingError implements IErrorEnumId { ClearingUnavailableForCompany(5421L), InsecurityObligation(5422L), NewDealsNotFound(5423L), + //ошибки "перенесенные" из balance-service + CompanyNotFoundB(5211L), + CurrencyNotFound(5213L), + OperationCanBeRunForTodayOnly(5214L), + AccountWrongType(5216L), ; private final Long id; diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingErrorInternal.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingErrorInternal.java index c1d029a7e..c6f81e7c4 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingErrorInternal.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingErrorInternal.java @@ -5,6 +5,7 @@ import ru.spcex.platform.utils.enumeration.IErrorEnumId; public enum ClearingErrorInternal implements IErrorEnumId { ClearingNotAllowed(1L), AccountNotActive(5415L), + AccountNotPresent(3L), CompanyNotActive(5411L), FinancialObligationNotSatisfied(4L), SessionGeneralError(2L); diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java index 3e51ed48e..0fcbdca38 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java @@ -62,8 +62,11 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean { .setConsumer(primaryAuctionBnSession::runSession) .forDestination(Task.startOfClearing.topic(), callbacks::put); callback(Object.class) - .setConsumer(primaryAuctionBnSession::continueSession) - .forDestination(Consts.SDF57_PROCESS, callbacks::put); + .setConsumer(primaryAuctionBnSession::continueSessionFirstPart) + .forDestination(Consts.CONTINUE_SESSION_BN_FIRST_PART, callbacks::put); + callback(Object.class) + .setConsumer(primaryAuctionBnSession::continueSessionSecondPart) + .forDestination(Consts.CONTINUE_SESSION_BN_SECOND_PART, callbacks::put); callback(Object.class) .setConsumer(event -> clearingService.executeSTrade()) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/StatementService.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/StatementService.java index dd42e9530..e2b076037 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/StatementService.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/StatementService.java @@ -8,14 +8,16 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.sdf.SDf01; +import ru.clearing.classes.statics.data.sdf.SDf04; +import ru.clearing.classes.statics.data.sdf.SDf13; import ru.clearing.classes.statics.data.sdf.SDf57; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdf01Request; import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart; -import ru.spcex.clearing.platform.messaging.domain.cud.balance.ExportToFileRequest; import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.clearing.ContinueSessionBnRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.service.executors.AbstractExecutor; @@ -24,11 +26,9 @@ import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.enumeration.SdfTable; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.collection.Pair; -import java.util.Collection; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; @Service @@ -40,6 +40,11 @@ public class StatementService extends QueueConsumer implements InitializingBean private final Map> sdfImdgs; private final Map> executorsMap; + /** + * Пары sdf запросов пришедшие с модуля dbf-import + */ + private final Map> pairOfSdfRequest = new HashMap<>(); + @Autowired public StatementService(Consumer kafkaQueue, ImdgProvider imdgProvider, @@ -52,6 +57,8 @@ public class StatementService extends QueueConsumer implements InitializingBean this.executorsMap = executorsMap; this.sdfImdgs.put(SdfTable.SDF_01, imdgProvider.getImdg(IMDGDistributedNames.Map_SDf01, SDf01.class)); this.sdfImdgs.put(SdfTable.SDF_57, imdgProvider.getImdg(IMDGDistributedNames.Map_SDf57, SDf57.class)); + this.sdfImdgs.put(SdfTable.SDF_04, imdgProvider.getImdg(IMDGDistributedNames.Map_SDf04, SDf04.class)); + this.sdfImdgs.put(SdfTable.SDF_13, imdgProvider.getImdg(IMDGDistributedNames.Map_SDf13, SDf13.class)); } @Override @@ -64,31 +71,145 @@ public class StatementService extends QueueConsumer implements InitializingBean private void process(BaseRequest systemRequest) { StatementRequest statementRequest = systemRequest.getRequestPayload(); - Collection sdfGroup; SdfTable table = statementRequest.getTable(); - Imdg sdfImdg = sdfImdgs.get(table); + + Optional completePairKey = saveRequest(statementRequest); + if (completePairKey.isPresent()) { + if (List.of(SdfTable.SDF_01, SdfTable.SDF_57).contains(table)) { + { + //всегда сначала обработаем sdf57 + Long key = completePairKey.get(); + Pair pair = pairOfSdfRequest.get(key); + processSdf57(pair.getSecond()); + + //затем sdf01 + processSdf01(pair.getFirst()); + //теперь можем продолжить сессию с шага 1 + ContinueSessionBnRequest continueSessionBn = new ContinueSessionBnRequest(); + kafkaSender.sendRequestToQueue(Consts.CONTINUE_SESSION_BN_FIRST_PART, continueSessionBn); + pairOfSdfRequest.remove(key); + } + } else if (List.of(SdfTable.SDF_08, SdfTable.SDF_13).contains(table)) { + //not implemented part; it's actually stage number 8 from any session + { + //всегда сначала обработаем sdf04 + Long key = completePairKey.get(); + Pair pair = pairOfSdfRequest.get(key); + processSdf04(pair.getFirst()); + + //затем sdf01 + processSdf13(pair.getSecond()); + //теперь можем продолжить сессию с шага 1 + ContinueSessionBnRequest continueSessionBn = new ContinueSessionBnRequest(); + kafkaSender.sendRequestToQueue(Consts.CONTINUE_SESSION_BN_SECOND_PART, continueSessionBn); + pairOfSdfRequest.remove(key); + } + } + } + } + + private void processSdf57(StatementRequest statementRequest) { + Imdg sdfImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf57, SDf57.class); + Collection sdfGroup = sdfImdg.getCollectionObjectsByFieldValues(Map.of( + "generationId", statementRequest.getGroupId())); + AbstractExecutor service = executorsMap.get(SdfTable.SDF_57); + service.execute(sdfGroup, statementRequest); + } + + private void processSdf04(StatementRequest statementRequest) { + Imdg sdfImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf04, SDf04.class); + Collection sdfGroup = sdfImdg.getCollectionObjectsByFieldValues(Map.of( + "generationId", statementRequest.getGroupId())); + AbstractExecutor service = executorsMap.get(SdfTable.SDF_04); + service.execute(sdfGroup, statementRequest); + } + + private void processSdf13(StatementRequest statementRequest) { + Imdg sdfImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf13, SDf13.class); + Collection sdfGroup = sdfImdg.getCollectionObjectsByFieldValues(Map.of( + "generationId", statementRequest.getGroupId())); + AbstractExecutor service = executorsMap.get(SdfTable.SDF_13); + service.execute(sdfGroup, statementRequest); + } + + private void processSdf01(StatementRequest statementRequest) { + Imdg sdfImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf01, SDf01.class); + Collection sdfGroup; if (statementRequest.getAccountCreationResults().size() == 0) { - sdfGroup = sdfImdg.getCollectionObjectsByFieldValues(Map.of("generationId", statementRequest.getGroupId())); + sdfGroup = sdfImdg.getCollectionObjectsByFieldValues(Map.of( + "generationId", statementRequest.getGroupId())); } else { + //todo могут ли тут реквесты бегать по кругу, если да, то у нас проблемы sdfGroup = statementRequest.getAccountCreationResults() .stream() .filter(part -> part.getErrorCode() == null) //fixme эти случае должны попадать в ошибочный sdf02 .map(part -> sdfImdg.getSingleObjectByID(part.getSdfId())) .collect(Collectors.toList()); } - - AbstractExecutor service = executorsMap.get(table); + AbstractExecutor service = executorsMap.get(SdfTable.SDF_01); Result res = service.execute(sdfGroup, statementRequest); if (res.getAccountRequests().size() != 0) { kafkaSender.sendRequestToQueue(Consts.ACCOUNT_NEW_SDF01, createAccountsRequest(statementRequest.getGroupId(), res.getAccountRequests())); - } else if (service.isNeedToSendCommandToExport()) { - ExportToFileRequest exportRequest = new ExportToFileRequest(); - exportRequest.setSdfGroupId(res.getGenerationId()); - exportRequest.setNameOfTable(service.exportTableName()); - kafkaSender.sendRequestToQueue(Consts.EXPORT_PROCESS, exportRequest); + } else if (service.isNeedToSendCommand()) { + service.sendCommand(kafkaSender, res); } } + private Optional saveRequest(StatementRequest statementRequest) { + SdfTable sdfTable = statementRequest.getTable(); + if (pairOfSdfRequest.isEmpty()) { + Long id = imdgProvider.getImdgIdGenerator().nextId(); + pairOfSdfRequest.put(id, getPairByTableName(sdfTable, statementRequest)); + } else { + //найдем первую неполноценную пару + Optional uncompletedPairId = findUncompletedPairByTableName(sdfTable); + if (uncompletedPairId.isPresent()) { + Long key = uncompletedPairId.get(); + Pair completed = pairOfSdfRequest.get(key); + if (completed.getFirst() == null) { + completed.setFirst(statementRequest); + } else { + completed.setSecond(statementRequest); + } + pairOfSdfRequest.put(key, completed); + //укомплектованная пара + return Optional.of(key); + } else { + //если таких нет, то просто создаем новую с одной частью + Long id = imdgProvider.getImdgIdGenerator().nextId(); + ; + pairOfSdfRequest.put(id, getPairByTableName(sdfTable, statementRequest)); + } + } + return Optional.empty(); + } + + private Pair getPairByTableName(SdfTable sdfTable, StatementRequest statementRequest) { + Pair pair = null; + switch (sdfTable) { + case SDF_01 -> pair = new Pair<>(statementRequest, null); + case SDF_57 -> pair = new Pair<>(null, statementRequest); + case SDF_04 -> pair = new Pair<>(statementRequest, null); + case SDF_13 -> pair = new Pair<>(null, statementRequest); + } + return pair; + } + + private Optional findUncompletedPairByTableName(SdfTable sdfTable) { + Optional uncompletedPair = Optional.empty(); + switch (sdfTable) { + case SDF_01 -> + uncompletedPair = pairOfSdfRequest.entrySet().stream().filter(entry -> entry.getValue().getFirst() != null && entry.getValue().getSecond() == null).findFirst().map(Map.Entry::getKey); + case SDF_57 -> + uncompletedPair = pairOfSdfRequest.entrySet().stream().filter(entry -> entry.getValue().getFirst() == null && entry.getValue().getSecond() != null).findFirst().map(Map.Entry::getKey); + case SDF_04 -> + uncompletedPair = pairOfSdfRequest.entrySet().stream().filter(entry -> entry.getValue().getFirst() != null && entry.getValue().getSecond() == null).findFirst().map(Map.Entry::getKey); + case SDF_13 -> + uncompletedPair = pairOfSdfRequest.entrySet().stream().filter(entry -> entry.getValue().getFirst() == null && entry.getValue().getSecond() != null).findFirst().map(Map.Entry::getKey); + } + return uncompletedPair; + } + private AccountSdf01Request createAccountsRequest(Long sdf01GroupingId, List accountRequests) { AccountSdf01Request r = new AccountSdf01Request(); r.setGroupingSdf01Id(sdf01GroupingId); diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilder.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilder.java new file mode 100644 index 000000000..ff1f9ecde --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilder.java @@ -0,0 +1,74 @@ +package ru.spcex.clearing.service.builder; + +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.classes.statics.data.payment.PaymentInstruction; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.enumeration.CompanySymbol; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.util.Map; + +public class PaymentInstructionBuilder { + + private Registry registry; + private ImdgProvider imdgProvider; + + public static PaymentInstructionBuilder builder(ImdgProvider imdgProvider, Registry registry) { + return new PaymentInstructionBuilder(imdgProvider, registry); + } + + private PaymentInstructionBuilder(ImdgProvider imdgProvider, Registry registry) { + this.imdgProvider = imdgProvider; + this.registry = registry; + } + + public PaymentInstruction build() { + PaymentInstruction paymentInstruction = new PaymentInstruction(); + paymentInstruction.setSenderId(registry.getCompanyId()); + paymentInstruction.setAddresseeId(registry.getCounterPartyId()); + + Imdg companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + CompanySymbols companySymbols = companySymbolsImdg.getSingleObjectByFieldValues(Map.of( + "companyId", registry.getCompanyId(), + "companySymbol", CompanySymbol.BIC.getKey()) + ); + CompanySymbols counterCompanySymbols = companySymbolsImdg.getSingleObjectByFieldValues(Map.of( + "companyId", registry.getCounterPartyId(), + "companySymbol", CompanySymbol.BIC.getKey()) + ); + + if (companySymbols != null) { + paymentInstruction.setPayeeBic(companySymbols.getCompanySymbolValue()); + } + if (counterCompanySymbols != null) { + paymentInstruction.setAdresseeBic(counterCompanySymbols.getCompanySymbolValue()); + } + + Imdg companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + Company company = companyImdg.getSingleObjectByFieldValues(Map.of("companyId", registry.getCompanyId())); + if (company != null) { + paymentInstruction.setPayeeBankName(company.getShortName()); + paymentInstruction.setAddresseeBankName(company.getShortName()); + } + paymentInstruction.setSettlementDate(registry.getSettlementDate()); + paymentInstruction.setCreditLeg_amount(registry.getBalance()); + paymentInstruction.setDebitLeg_amount(registry.getBalance()); + paymentInstruction.setCreditLeg_accountId(registry.getAccountId()); + + Imdg accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); + Account account = accountImdg.getSingleObjectByID(registry.getAccountId()); + if (account != null) { + paymentInstruction.setCreditLeg_account(account.getAccount()); + } + + paymentInstruction.setDebitLeg_accountId(registry.getAccountId()); + +// Account account = accountImdg.getSingleObjectByID(registry.get()); +// paymentInstruction.setDebitLeg_account(); + return paymentInstruction; + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/AbstractExecutor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/AbstractExecutor.java index b1bc4cddf..afead4914 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/AbstractExecutor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/AbstractExecutor.java @@ -1,6 +1,7 @@ package ru.spcex.clearing.service.executors; import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.service.model.Result; import java.util.Collection; @@ -8,5 +9,6 @@ import java.util.Collection; public abstract class AbstractExecutor { public abstract Result execute(Collection sdf, StatementRequest statementRequest); public abstract String exportTableName(); - public abstract boolean isNeedToSendCommandToExport(); + public abstract boolean isNeedToSendCommand(); + public abstract void sendCommand(KafkaSender kafkaSender, Result result); } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf01Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf01Executor.java index e2b30c58c..f10b6c73d 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf01Executor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf01Executor.java @@ -2,73 +2,107 @@ package ru.spcex.clearing.service.executors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.account.Account; -import ru.clearing.classes.statics.data.account.AccountBalance; +import ru.clearing.classes.statics.data.account.ClearingAccount; import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.misc.Currency; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.clearing.classes.statics.data.sdf.SDf01; import ru.clearing.classes.statics.data.sdf.SDf02; +import ru.clearing.classes.statics.data.security.Security; import ru.clearing.classes.statics.data.statement.Statement; import ru.spcex.clearing.error.ClearingError; +import ru.spcex.clearing.error.ClearingErrorInternal; import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.ExportToFileRequest; import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.clearing.ContinueSessionBnRequest; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.service.LoggingService; 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.enumeration.*; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder; import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumKey; import ru.spcex.platform.utils.enumeration.IMessageResolver; -import ru.spcex.platform.utils.number.BigDecimalUtil; import ru.spcex.platform.utils.validation.IValidator; +import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Collection; import java.util.Map; import java.util.Optional; +import java.util.function.Consumer; import java.util.function.Function; @Service public class Sdf01Executor extends AbstractExecutor { private final Logger log = LoggerFactory.getLogger(getClass()); - private final static DateTimeFormatter datFormatter = DateTimeFormatter.ofPattern("dd.MM.yy"); private final Imdg statementImdg; + private final Imdg registryImdg; private final Function sDf01Validator; - private final LoggingService errorLogger; - private final Imdg sdf02Imdg; private final ImdgProvider imdgProvider; - private final IMessageResolver errorResolver; - private final Imdg accountBalanceImdg; + private final Imdg clearingAccountImdg; + private final Imdg tradingClearingRegistryImdg; + private final Imdg securityImdg; + private final Imdg currencyImdg; + private final Imdg sdf02Imdg; + private final IMessageResolver messageResolver; - public Sdf01Executor(Function sDf01Validator, + public Sdf01Executor(@Qualifier("sdf01ValidatorNew") Function sDf01Validator, LoggingService errorLogger, ImdgProvider imdgProvider, - IMessageResolver errorResolver) { + IMessageResolver errorResolver, IMessageResolver messageResolver) { this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class); - this.sdf02Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class); - this.accountBalanceImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class); - ; + this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); + this.clearingAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class); + this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); + this.currencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, Currency.class); this.sDf01Validator = sDf01Validator; - this.errorLogger = errorLogger; this.imdgProvider = imdgProvider; - this.errorResolver = errorResolver; + this.messageResolver = messageResolver; + this.securityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Security, Security.class); + this.sdf02Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class); } + //todo доделать контроль sdf01 и sdf57 + @Override public String exportTableName() { - return "DF-02"; + return null; } @Override - public boolean isNeedToSendCommandToExport() { + public boolean isNeedToSendCommand() { return true; } + @Override + public void sendCommand(KafkaSender kafkaSender, Result result) { + ContinueSessionBnRequest continueSessionBn = new ContinueSessionBnRequest(); + continueSessionBn.setGenerationId(result.getGenerationId()); + kafkaSender.sendRequestToQueue(Consts.CONTINUE_SESSION_BN_FIRST_PART, continueSessionBn); + + ExportToFileRequest exportRequest = new ExportToFileRequest(); + exportRequest.setSdfGroupId(result.getGenerationId()); + exportRequest.setNameOfTable(exportTableName()); + kafkaSender.sendRequestToQueue(Consts.EXPORT_PROCESS, exportRequest); + } + public Result execute(Collection sdf, StatementRequest statementRequest) { Result result = new Result(); Long generationIdForGroup = imdgProvider.getImdgIdGenerator().nextId(); @@ -76,76 +110,85 @@ public class Sdf01Executor extends AbstractExecutor { for (SDf01 sdf01 : sdf) { IValidator validator = sDf01Validator.apply(sdf01); Optional error = validator.tillFirstError(); - Company company = validator.getStored(ValidationStored.Company); + Company company = validator.getStored(ValidationStored.Sdf01Company); + Account account = validator.getStored(ValidationStored.Sdf01Account); if (statementRequest.getAccountCreationResults().size() == 0 - && ClearingError.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { + && ClearingErrorInternal.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { //на данном шаге company существует -> getId ok //формируем пакетный запрос на добавление account //ответ придет в этот же метод, process result.getAccountRequests().add(createAccountRequestPart(sdf01.getId(), sdf01.getAccount(), company.getId())); log.info("account {} for sdf01.id={} not found - send request for creation", sdf01.getAccount(), sdf01.getId()); continue; - } else if (ClearingError.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { + } else if (ClearingErrorInternal.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { log.error("fatal error: resumed processing after generating accounts, but no account found for sdf01.id={}", sdf01.getId()); } if (error.isPresent()) { - errorLogger.logError("sdf01.id={}", error.get(), sdf01.getId()); + log.error("sdf01.id={} error: {}", sdf01.getId(), messageResolver.resolve(error.get())); + //fixme инициировать = команда для другого сервиса? sdf02Imdg.insert(createErrorSdf02(sdf01, error.get(), generationIdForGroup)); sdf02Imdg.insert(createErrorSdf02(sdf01, error.get(), generationIdForGroup)); continue; } - Statement statement = statementImdg.getSingleObjectByFieldValues(Map.of("account", sdf01.getAccount())); - if (statement == null) { - statement = createFlow(sdf01, - company, - validator.getStored(ValidationStored.Account)); - } else { - updateFlow(statement, sdf01, - validator.getStored(ValidationStored.Account)); - } - SDf02 sdf02New = createSuccessSdf02(sdf01, generationIdForGroup); + + Statement stmt = createSdf01Statement(sdf01, company, account); + + SDf02 sdf02New = createSuccessSdf02(sdf01, generationIdForGroup); //fixme тоже мб убрать sdf02Imdg.insert(sdf02New); - statement.setOutSDfId(sdf02New.getId()); -// AccountResult accountResult = accountBalanceService.createAccountBalance(statement.getAddresseeId(), statement.getAccountId(), statement.getAmount(), -// null/*statement.getCashMovementCurrencyCode()*/); -// if (accountResult.getError() != null) { -// statement.setErrorCodeId(accountResult.getError().getSubject().getId()); -// todo statement.setErrorText(errorResolver.resolve(accountResult.getError())); -// } else { -// accountBalanceImdg.insert(accountResult.getAccount()); //insert == update? -// statement.setOperationStatus(OperationStatus.Executed.getKey()); -// } - statementImdg.update(statement); + stmt.setOutSDfId(sdf02New.getId()); + statementImdg.update(stmt); + + Optional err = validateActiveness(company, account); + if (err.isEmpty()) { + Consumer update = rgs -> { + updateReg(stmt, rgs); + registryImdg.update(rgs); + }; + Consumer create = (dsgn) -> { + Registry registry = createRegistryByStatement(stmt, company, account, dsgn); + Registry registryF = registry.clone(); + registryF.setRegistryUnit(RegistryUnit.F.getKey()); + registryF.setRegistryCode(RegistryUtil.clearingCode(registryF)); + registryF.setId(imdgProvider.getImdgIdGenerator().nextId()); + Registry registryB = registry.clone(); + registryB.setRegistryUnit(RegistryUnit.B.getKey()); + registryB.setRegistryCode(RegistryUtil.clearingCode(registryB)); + registryB.setId(imdgProvider.getImdgIdGenerator().nextId()); + registryImdg.insert(registry); + registryImdg.insert(registryF); + registryImdg.insert(registryB); + }; + + findReg(stmt, RegistryInstrumentType.M).ifPresentOrElse(update, () -> create.accept(RegistryDesignation.A)); + findReg(stmt, RegistryInstrumentType.S).ifPresentOrElse(update, () -> create.accept(RegistryDesignation.D)); + stmt.setOperationStatus(OperationStatus.Executed.getKey()); + } else { + stmt.setErrorCodeId(err.get().getSubject().getId()); // fixme ErrorText insert + stmt.setOperationStatus(OperationStatus.Rejected.getKey()); + statementImdg.update(stmt); + } } return result; } - private Statement createFlow(SDf01 sdf01, Company company, Account account) { - Statement statement = new Statement(); - statement.setAddresseeId(company.getId()); - statement.setSenderId(Sender.Prc.getId()); - statement.setCreated(Instant.now()); - statement.setClearingDate(LocalDate.now()); - statement.setStatementType(StatementType.full.getKey()); - statement.setAccountId(account.getId()); - statement.setAccount(sdf01.getAccount()); - statement.setInOutDirection(InOutDirection.in.getKey()); - statement.setSettlementDate(LocalDate.parse(sdf01.getDat(), datFormatter)); - statement.setAmount(BigDecimalUtil.parse(sdf01.getRemainder())); - statement.setOperationStatus(OperationStatus.Pending.getKey()); - statement.setInSDfId(sdf01.getId()); - statement.setInOutSDfType(InOutSDfType.type1.getKey()); - statementImdg.insert(statement); - return statement; - } - - private void updateFlow(Statement statement, SDf01 sdf01, Account account) { - statement.setUpdated(Instant.now()); - statement.setAccountId(account.getId()); - statement.setAccount(sdf01.getAccount()); - statement.setInOutDirection(InOutDirection.in.getKey()); - statement.setSettlementDate(LocalDate.parse(sdf01.getDat(), datFormatter)); - statement.setAmount(BigDecimalUtil.parse(sdf01.getRemainder())); - statementImdg.update(statement); + private final static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yy"); + private Statement createSdf01Statement(SDf01 sdf01, Company company, Account account) { + Statement stmt = new Statement(); + stmt.setAddresseeId(company.getId()); + stmt.setAddresseeId(company.getId()); + stmt.setSenderId(Sender.Prc.getId()); + stmt.setStatementType(StatementType.full.getKey()); + stmt.setAccountId(account.getId()); + stmt.setAccount(account.getAccount()); + stmt.setInOutDirection(InOutDirection.in.getKey()); + stmt.setSettlementDate(LocalDate.parse(sdf01.getDat(), formatter)); + if (sdf01.getRemainder() != null) { + stmt.setAmount(new BigDecimal(sdf01.getRemainder())); + } + stmt.setOperationStatus(OperationStatus.Pending.getKey()); + stmt.setInSDfId(sdf01.getId()); + stmt.setInOutSDfType(InOutSDfType.type1.getKey()); + stmt.setCreated(Instant.now()); + return stmt; } private AccountSdfRequestPart createAccountRequestPart(Long sdf01Id, String account, Long companyId) { @@ -157,7 +200,6 @@ public class Sdf01Executor extends AbstractExecutor { return req; } - private SDf02 createErrorSdf02(SDf01 sdf01, EnumMessage error, Long generationIdForGroup) { SDf02 sDf02 = new SDf02(); sDf02.setCurr_code(sdf01.getCurr_code()); @@ -200,4 +242,100 @@ public class Sdf01Executor extends AbstractExecutor { sDf02.setResult("OK!"); return sDf02; } + + + private Optional validateActiveness(Company company, Account account) { + if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { + return Optional.of(new EnumMessage(ClearingError.CompanyNotActive, company.getId())); + } + if (!WorkflowStatus.Active.equalsByKey(account.getStatus())) { + return Optional.of(new EnumMessage(ClearingError.AccountNotActive, account.getId())); + } + return Optional.empty(); + } + + private Registry createRegistryByStatement(Statement statement, Company company, Account account, RegistryDesignation designation) { + Registry rgs = new Registry(); + rgs.setCompanyId(statement.getAddresseeId()); + rgs.setTradingCode(company.getTradingCode()); + rgs.setClearingCode(company.getClearingCode()); + rgs.setShortName(company.getShortName()); + rgs.setFullName(company.getFullName()); + rgs.setAccountId(account.getId()); + rgs.setAccountType(account.getAccountType()); + rgs.setAccount(account.getAccount()); + rgs.setRegistryDesignation(designation.getKey()); + rgs.setRegistryInstrumentType(RegistryInstrumentType.M.getKey()); + + ClearingAccount accountForStatement = clearingAccountImdg.getSingleObjectByID(statement.getAccountId()); + if (accountForStatement != null) { + rgs.setRegistryCapacity(accountForStatement.getClearingAccountType()); + } + rgs.setRegistryUnit(RegistryUnit.T.getKey()); + rgs.setRegistryCode(RegistryUtil.clearingCode(rgs)); + + Collection tcrsByAccount = tradingClearingRegistryImdg.getCollectionObjectsByFieldValues(Map.of( + "moneyAccountId", statement.getAccountId() + )); + if (!tcrsByAccount.isEmpty()) { + TradingClearingRegistry tcr = tcrsByAccount.iterator().next(); + rgs.setTradingClearingRegistryId(tcr.getId()); + rgs.setTradingClearingRegistry(tcr.getCode()); + } + + rgs.setRegistryStatus(RegistryStatus.PROC.getKey()); + rgs.setSecurityId(statement.getSecurityId()); + if (statement.getSecurityId() != null) { + Security security = securityImdg.getSingleObjectByID(statement.getSecurityId()); + if (security != null) { + rgs.setSecuritySymbol(security.getSecuritySymbol()); + } + } + InOutDirection inOutDirection = IEnumKey.getEnumByKey(InOutDirection.class, statement.getInOutDirection()); + //считаю balance при создании нулевым и исхожу из этого + //При добавлении (на базе изменения statement по sDf57): + //Если значение statement.inOutDirection=IN, то: + //= текущее значение registry.balance + statement.amount + // + //Если значение statement.inOutDirection=OUT, то: + //= текущее значение registry.balance - statement.amount + switch (inOutDirection) { + case in -> rgs.setBalance(statement.getAmount()); + case out -> rgs.setBalance(statement.getAmount().negate()); + } + rgs.setBalanceDimension(BalanceDimension.MONY.getKey()); //fixme ! смотри описание и ссылка на начало html'ки + //fixme !rgs.setSettlementCode(); + rgs.setTradingDate(statement.getSettlementDate()); //fixme ! today ? + rgs.setClearingDate(LocalDate.now()); + //fixme rgs.setRefundDate(); + //fixme rgs.setValueDate(); + rgs.setContract(statement.getContract()); + //создается на базе stmt, companyCred, accountDeb + rgs.setCounterPartyId(statement.getAddresseeId()); + rgs.setCreated(Instant.now()); + return rgs; + } + + private void updateReg(Statement s, Registry r) { + InOutDirection direction = IEnumKey.getEnumByKey(InOutDirection.class, s.getInOutDirection()); + switch (direction) { + case in -> r.setBalance(r.getBalance().add(s.getAmount())); + case out -> r.setBalance(r.getBalance().subtract(s.getAmount())); + } + r.setUpdated(Instant.now()); + } + + private Optional findReg(Statement s, RegistryInstrumentType registryInstrumentType) { + RegistryTradingParams p = new RegistryTradingParams( + RegistryDesignation.A, registryInstrumentType, RegistryCapacity.A, RegistryUnit.T + ); + String sql = RegistryCodeSqlBuilder.getInstance(p).build(); + ImdgPredicateBuilder pb = registryImdg.predicateBuilder(); + ImdgPredicate rgstrPredicate = pb.and(pb.sql(sql), + pb.sql(sql), + pb.equals("accountId", s.getAccountId()), + pb.equals("companyId", s.getAddresseeId()) + ); + return Optional.ofNullable(registryImdg.getSingleObjectByPredicate(rgstrPredicate)); + } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf04Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf04Executor.java new file mode 100644 index 000000000..a14733a95 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf04Executor.java @@ -0,0 +1,98 @@ +package ru.spcex.clearing.service.executors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.clearing.classes.statics.data.sdf.SDf04; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.clearing.service.model.Result; +import ru.spcex.platform.enumeration.RegistryDesignation; +import ru.spcex.platform.enumeration.RegistryInstrumentType; +import ru.spcex.platform.enumeration.RegistryUnit; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; + +import java.math.BigDecimal; +import java.util.Collection; +import java.util.Collections; + +@Service +public class Sdf04Executor extends AbstractExecutor { + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final ImdgProvider imdgProvider; + private final Imdg registryImdg; + + public Sdf04Executor(ImdgProvider imdgProvider) { + this.imdgProvider = imdgProvider; + this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); + } + + @Override + public String exportTableName() { + return ""; + } + + @Override + public boolean isNeedToSendCommand() { + return false; + } + + @Override + public void sendCommand(KafkaSender kafkaSender, Result result) { + } + + public Result execute(Collection sdf, StatementRequest statementRequest) { + Result result = new Result(); + Long generationIdForGroup = imdgProvider.getImdgIdGenerator().nextId(); + result.setGenerationId(generationIdForGroup); + for (SDf04 sdf04 : sdf) { + //обычно мы ищем по группу sdf04, здесь как будто всегда только одна запись, todo нужно прочекать этот момент + log.debug("Process sdf04 record; sdf04.id: {}", sdf04.getId()); + Collection fullNames = Collections.emptyList(); //fixme что значит registry.fullName=sDf04.(sbanknam1, sbanknam2 и т.д.) + Collection registries = selectRegistryForSDF04(sdf04.getC_acc_cred(), fullNames); + registries.forEach(registry -> unlockRegistry(registry, new BigDecimal(sdf04.getPay_val()))); + } + return result; + } + + protected Collection selectRegistryForSDF04(String account, Collection fullNames) { + ImdgPredicateBuilder pb = registryImdg.predicateBuilder(); + ImdgPredicate query = pb.and( + pb.and( + pb.equals("registryDesignation", RegistryDesignation.A.getKey()), + pb.equals("registryInstrumentType", RegistryInstrumentType.M.getKey()), + pb.or(pb.equals("registryUnit", RegistryUnit.F.getKey()), + pb.equals("registryUnit", RegistryUnit.B.getKey())) + ), + pb.equals("account", account) +// , +// pb.in("fullName", fullNames.toArray(new String[fullNames.size()])) + ); + + Collection result = registryImdg.getCollectionObjectsByPredicate(query); + log.trace("Selected {} registry's by sql: {}", result.size(), query); + return result; + } + + boolean unlockRegistry(Registry registry, BigDecimal value) { + if (RegistryUnit.F.equalsByKey(registry.getRegistryUnit())) { + if (registry.getBalance() == null) registry.setBalance(BigDecimal.ZERO); + registry.setBalance(registry.getBalance().add(value)); + return true; + } else if (RegistryUnit.B.equalsByKey(registry.getRegistryUnit())) { + if (registry.getBalance() == null) registry.setBalance(BigDecimal.ZERO); + registry.setBalance(registry.getBalance().subtract(value)); + return true; + } else { + log.warn("For registry {} registryUnit={} unlock operation not implemented.", + registry.getId(), registry.getRegistryUnit()); + return false; + } + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf13Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf13Executor.java new file mode 100644 index 000000000..688e17d14 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf13Executor.java @@ -0,0 +1,105 @@ +package ru.spcex.clearing.service.executors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.clearing.classes.statics.data.sdf.SDf12; +import ru.clearing.classes.statics.data.sdf.SDf13; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.clearing.service.model.Result; +import ru.spcex.platform.enumeration.RegistryDesignation; +import ru.spcex.platform.enumeration.RegistryInstrumentType; +import ru.spcex.platform.enumeration.RegistryUnit; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; + +import java.math.BigDecimal; +import java.util.Collection; + +@Service +public class Sdf13Executor extends AbstractExecutor { + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final Imdg sdf12Imdg; + private final ImdgProvider imdgProvider; + private final Imdg registryImdg; + + public Sdf13Executor(ImdgProvider imdgProvider) { + this.imdgProvider = imdgProvider; + this.sdf12Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf12, SDf12.class); + this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); + } + + @Override + public String exportTableName() { + return ""; + } + + @Override + public boolean isNeedToSendCommand() { + return false; + } + + @Override + public void sendCommand(KafkaSender kafkaSender, Result result) { + } + + public Result execute(Collection sdf, StatementRequest statementRequest) { + Result result = new Result(); + Long generationIdForGroup = imdgProvider.getImdgIdGenerator().nextId(); + result.setGenerationId(generationIdForGroup); + for (SDf13 sdf13 : sdf) { + //обычно мы ищем по группу sdf04, здесь как будто всегда только одна запись, todo нужно прочекать этот момент + SDf12 sDf12 = selectSdf12bySdf13(sdf13); + log.debug("Process sdf13 record; sdf13.id: {}", sdf13.getId()); + Collection registries = selectRegistryForSDF12(sDf12.getDepoCodeSender(), sDf12.getSecurityCode()); + registries.forEach(registry -> unlockRegistry(registry, new BigDecimal(sDf12.getQuantity()))); + } + return result; + } + + protected SDf12 selectSdf12bySdf13(SDf13 sDf13) { + SDf12 sdf12 = sdf12Imdg.getSingleObjectByID(sDf13.getId()); + log.trace("Selected sdf12 by sdf13"); + return sdf12; + } + + protected Collection selectRegistryForSDF12(String account, String securityCode) { + ImdgPredicateBuilder pb = registryImdg.predicateBuilder(); + ImdgPredicate query = pb.and( + pb.and( + pb.equals("registryDesignation", RegistryDesignation.A.getKey()), + pb.equals("registryInstrumentType", RegistryInstrumentType.M.getKey()), + pb.or(pb.equals("registryUnit", RegistryUnit.F.getKey()), + pb.equals("registryUnit", RegistryUnit.B.getKey())) + ), + pb.equals("account", account), + pb.equals("securityCode", securityCode) + ); + + Collection result = registryImdg.getCollectionObjectsByPredicate(query); + log.trace("Selected {} registry's by sql: {}", result.size(), query); + return result; + } + + boolean unlockRegistry(Registry registry, BigDecimal value) { + if (RegistryUnit.F.equalsByKey(registry.getRegistryUnit())) { + if (registry.getBalance() == null) registry.setBalance(BigDecimal.ZERO); + registry.setBalance(registry.getBalance().add(value)); + return true; + } else if (RegistryUnit.B.equalsByKey(registry.getRegistryUnit())) { + if (registry.getBalance() == null) registry.setBalance(BigDecimal.ZERO); + registry.setBalance(registry.getBalance().subtract(value)); + return true; + } else { + log.warn("For registry {} registryUnit={} unlock operation not implemented.", + registry.getId(), registry.getRegistryUnit()); + return false; + } + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java index 21fd8fa77..436d49273 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java @@ -1,20 +1,27 @@ package ru.spcex.clearing.service.executors; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.account.AccountBalance; +import ru.clearing.classes.statics.data.account.ClearingAccount; import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.misc.Currency; import ru.clearing.classes.statics.data.registry.Registry; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.clearing.classes.statics.data.sdf.SDf02; import ru.clearing.classes.statics.data.sdf.SDf57; import ru.clearing.classes.statics.data.security.Security; import ru.clearing.classes.statics.data.statement.Statement; import ru.spcex.clearing.error.ClearingError; import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.clearing.ContinueSessionBnRequest; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.service.LoggingService; import ru.spcex.clearing.service.model.Result; import ru.spcex.clearing.service.validation.ValidationStored; @@ -36,6 +43,7 @@ import java.time.Instant; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Collection; +import java.util.Map; import java.util.Optional; import java.util.function.Consumer; import java.util.function.Function; @@ -53,8 +61,12 @@ public class Sdf57Executor extends AbstractExecutor { private final ImdgProvider imdgProvider; private final IMessageResolver errorResolver; private final Imdg accountBalanceImdg; + private final Imdg clearingAccountImdg; + private final Imdg tradingClearingRegistryImdg; private final Imdg securityImdg; + private final Imdg currencyImdg; private final IMessageResolver messageResolver; +// private final Pair<> public Sdf57Executor(@Qualifier("sdf57Validator") Function sDf57Validator, LoggingService errorLogger, @@ -64,6 +76,9 @@ public class Sdf57Executor extends AbstractExecutor { this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); this.sdf02Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class); this.accountBalanceImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class); + this.clearingAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class); + this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); + this.currencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, Currency.class); this.sDf57Validator = sDf57Validator; this.errorLogger = errorLogger; this.imdgProvider = imdgProvider; @@ -72,15 +87,24 @@ public class Sdf57Executor extends AbstractExecutor { this.securityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Security, Security.class); } + //todo доделать контроль sdf01 и sdf57 + @Override public String exportTableName() { return null; } @Override - public boolean isNeedToSendCommandToExport() { - return false; - }//no need... + public boolean isNeedToSendCommand() { + return true; + } + + @Override + public void sendCommand(KafkaSender kafkaSender, Result result) { + ContinueSessionBnRequest continueSessionBn = new ContinueSessionBnRequest(); + continueSessionBn.setGenerationId(result.getGenerationId()); + kafkaSender.sendRequestToQueue(Consts.CONTINUE_SESSION_BN_FIRST_PART, continueSessionBn); + } //V - Изменение statement по sDf57 // @@ -127,9 +151,9 @@ public class Sdf57Executor extends AbstractExecutor { Account accountCred = validator.getStored(ValidationStored.Sdf57AccountCred); //адресат CREDIT / владелец DEBIT - Optional statementDeb = createStatementIfNeeded.apply(companyDeb, accountDeb, InOutDirection.in); + Optional statementDeb = createStatementIfNeeded.apply(companyDeb, accountDeb, InOutDirection.out); //адресат DEBIT / владелец CREDIT - Optional statementCred = createStatementIfNeeded.apply(companyCred, accountCred, InOutDirection.out); + Optional statementCred = createStatementIfNeeded.apply(companyCred, accountCred, InOutDirection.in); Consumer createRegistryIfNeeded = stmtCmpAcc -> { Statement stmt = stmtCmpAcc.statement(); @@ -145,12 +169,25 @@ public class Sdf57Executor extends AbstractExecutor { }; Consumer create = (dsgn) -> { Registry registry = createRegistryByStatement(stmt, company, account, dsgn); + Registry registryF = registry.clone(); + registryF.setRegistryUnit(RegistryUnit.F.getKey()); + registryF.setRegistryCode(RegistryUtil.clearingCode(registryF)); + registryF.setId(imdgProvider.getImdgIdGenerator().nextId()); + Registry registryB = registry.clone(); + registryB.setRegistryUnit(RegistryUnit.B.getKey()); + registryB.setRegistryCode(RegistryUtil.clearingCode(registryB)); + registryB.setId(imdgProvider.getImdgIdGenerator().nextId()); registryImdg.insert(registry); + registryImdg.insert(registryF); + registryImdg.insert(registryB); }; //todo понять что происходит со инициатором/контрагентом, особенно если у нас только один Statement findReg(stmt, RegistryDesignation.A).ifPresentOrElse(update, () -> create.accept(RegistryDesignation.A)); - findReg(stmt, RegistryDesignation.D).ifPresentOrElse(update, () -> create.accept(RegistryDesignation.D)); + if (!StringUtils.isEmpty(sdf57.getSpecif()) && sdf57.getSpecif().contains("№")) { + //todo доделать 11. Идентификация средств УК на клиринговом счете + findReg(stmt, RegistryDesignation.D).ifPresentOrElse(update, () -> create.accept(RegistryDesignation.D)); + } stmt.setOperationStatus(OperationStatus.Executed.getKey()); } else { stmt.setErrorCodeId(err.get().getSubject().getId()); // fixme ErrorText insert @@ -181,9 +218,14 @@ public class Sdf57Executor extends AbstractExecutor { Statement statement = new Statement(); statement.setAddresseeId(companyDeb.getId()); statement.setSenderId(Sender.Prc.getId()); - statement.setStatementType(StatementType.full.getKey()); + statement.setStatementType(StatementType.incr.getKey()); statement.setContract(getContractFromSpecif(sdf57.getSpecif())); statement.setAccountId(accountDeb.getId()); + + Currency currency = currencyImdg.getSingleObjectByFieldValues(Map.of("currencyCode", "RUB")); + if (currency != null) { + statement.setSecurityId(currency.getId()); + } statement.setAccount(accountDeb.getAccount()); statement.setInOutDirection(inOutDirection.getKey()); statement.setSettlementDate(payDate(sdf57.getPay_date())); @@ -206,11 +248,23 @@ public class Sdf57Executor extends AbstractExecutor { rgs.setAccount(account.getAccount()); rgs.setRegistryDesignation(designation.getKey()); rgs.setRegistryInstrumentType(RegistryInstrumentType.M.getKey()); - rgs.setRegistryCapacity(RegistryCapacity.A.getKey()); + + ClearingAccount accountForStatement = clearingAccountImdg.getSingleObjectByID(statement.getAccountId()); + if (accountForStatement != null) { + rgs.setRegistryCapacity(accountForStatement.getClearingAccountType()); + } rgs.setRegistryUnit(RegistryUnit.T.getKey()); rgs.setRegistryCode(RegistryUtil.clearingCode(rgs)); - //rgs.setTradingClearingRegistryId(); //todo ! - //rgs.setTradingClearingRegistry(); //todo ! + + Collection tcrsByAccount = tradingClearingRegistryImdg.getCollectionObjectsByFieldValues(Map.of( + "moneyAccountId", statement.getAccountId() + )); + if (!tcrsByAccount.isEmpty()) { + TradingClearingRegistry tcr = tcrsByAccount.iterator().next(); + rgs.setTradingClearingRegistryId(tcr.getId()); + rgs.setTradingClearingRegistry(tcr.getCode()); + } + rgs.setRegistryStatus(RegistryStatus.PROC.getKey()); rgs.setSecurityId(statement.getSecurityId()); if (statement.getSecurityId() != null) { diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/SdfLegacyExecutor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/SdfLegacyExecutor.java new file mode 100644 index 000000000..c8a5ce1a3 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/SdfLegacyExecutor.java @@ -0,0 +1,215 @@ +package ru.spcex.clearing.service.executors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.account.AccountBalance; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.sdf.SDf01; +import ru.clearing.classes.statics.data.sdf.SDf02; +import ru.clearing.classes.statics.data.statement.Statement; +import ru.spcex.clearing.error.ClearingError; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.ExportToFileRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.clearing.service.LoggingService; +import ru.spcex.clearing.service.model.Result; +import ru.spcex.clearing.service.validation.ValidationStored; +import ru.spcex.platform.enumeration.*; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.number.BigDecimalUtil; +import ru.spcex.platform.utils.validation.IValidator; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Collection; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; + +@Service +public class SdfLegacyExecutor extends AbstractExecutor { + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final static DateTimeFormatter datFormatter = DateTimeFormatter.ofPattern("dd.MM.yy"); + private final Imdg statementImdg; + private final Function sDf01Validator; + private final LoggingService errorLogger; + private final Imdg sdf02Imdg; + private final ImdgProvider imdgProvider; + private final IMessageResolver errorResolver; + private final Imdg accountBalanceImdg; + + public SdfLegacyExecutor(@Qualifier("sdf01Validator") Function sDf01Validator, + LoggingService errorLogger, + ImdgProvider imdgProvider, + IMessageResolver errorResolver) { + this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class); + this.sdf02Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class); + this.accountBalanceImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class); + ; + this.sDf01Validator = sDf01Validator; + this.errorLogger = errorLogger; + this.imdgProvider = imdgProvider; + this.errorResolver = errorResolver; + } + + @Override + public String exportTableName() { + return "DF-02"; + } + + @Override + public boolean isNeedToSendCommand() { + return true; + } + + @Override + public void sendCommand(KafkaSender kafkaSender, Result result) { + ExportToFileRequest exportRequest = new ExportToFileRequest(); + exportRequest.setSdfGroupId(result.getGenerationId()); + exportRequest.setNameOfTable(exportTableName()); + kafkaSender.sendRequestToQueue(Consts.EXPORT_PROCESS, exportRequest); + } + + public Result execute(Collection sdf, StatementRequest statementRequest) { + Result result = new Result(); + Long generationIdForGroup = imdgProvider.getImdgIdGenerator().nextId(); + result.setGenerationId(generationIdForGroup); + for (SDf01 sdf01 : sdf) { + IValidator validator = sDf01Validator.apply(sdf01); + Optional error = validator.tillFirstError(); + Company company = validator.getStored(ValidationStored.Company); + if (statementRequest.getAccountCreationResults().size() == 0 + && ClearingError.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { + //на данном шаге company существует -> getId ok + //формируем пакетный запрос на добавление account + //ответ придет в этот же метод, process + result.getAccountRequests().add(createAccountRequestPart(sdf01.getId(), sdf01.getAccount(), company.getId())); + log.info("account {} for sdf01.id={} not found - send request for creation", sdf01.getAccount(), sdf01.getId()); + continue; + } else if (ClearingError.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { + log.error("fatal error: resumed processing after generating accounts, but no account found for sdf01.id={}", sdf01.getId()); + } + if (error.isPresent()) { + errorLogger.logError("sdf01.id={}", error.get(), sdf01.getId()); + sdf02Imdg.insert(createErrorSdf02(sdf01, error.get(), generationIdForGroup)); + continue; + } + Statement statement = statementImdg.getSingleObjectByFieldValues(Map.of("account", sdf01.getAccount())); + if (statement == null) { + statement = createFlow(sdf01, + company, + validator.getStored(ValidationStored.Account)); + } else { + updateFlow(statement, sdf01, + validator.getStored(ValidationStored.Account)); + } + SDf02 sdf02New = createSuccessSdf02(sdf01, generationIdForGroup); + sdf02Imdg.insert(sdf02New); + statement.setOutSDfId(sdf02New.getId()); +// AccountResult accountResult = accountBalanceService.createAccountBalance(statement.getAddresseeId(), statement.getAccountId(), statement.getAmount(), +// null/*statement.getCashMovementCurrencyCode()*/); +// if (accountResult.getError() != null) { +// statement.setErrorCodeId(accountResult.getError().getSubject().getId()); +// todo statement.setErrorText(errorResolver.resolve(accountResult.getError())); +// } else { +// accountBalanceImdg.insert(accountResult.getAccount()); //insert == update? +// statement.setOperationStatus(OperationStatus.Executed.getKey()); +// } + statementImdg.update(statement); + } + return result; + } + + private Statement createFlow(SDf01 sdf01, Company company, Account account) { + Statement statement = new Statement(); + statement.setAddresseeId(company.getId()); + statement.setSenderId(Sender.Prc.getId()); + statement.setCreated(Instant.now()); + statement.setClearingDate(LocalDate.now()); + statement.setStatementType(StatementType.full.getKey()); + statement.setAccountId(account.getId()); + statement.setAccount(sdf01.getAccount()); + statement.setInOutDirection(InOutDirection.in.getKey()); + statement.setSettlementDate(LocalDate.parse(sdf01.getDat(), datFormatter)); + statement.setAmount(BigDecimalUtil.parse(sdf01.getRemainder())); + statement.setOperationStatus(OperationStatus.Pending.getKey()); + statement.setInSDfId(sdf01.getId()); + statement.setInOutSDfType(InOutSDfType.type1.getKey()); + statementImdg.insert(statement); + return statement; + } + + private void updateFlow(Statement statement, SDf01 sdf01, Account account) { + statement.setUpdated(Instant.now()); + statement.setAccountId(account.getId()); + statement.setAccount(sdf01.getAccount()); + statement.setInOutDirection(InOutDirection.in.getKey()); + statement.setSettlementDate(LocalDate.parse(sdf01.getDat(), datFormatter)); + statement.setAmount(BigDecimalUtil.parse(sdf01.getRemainder())); + statementImdg.update(statement); + } + + private AccountSdfRequestPart createAccountRequestPart(Long sdf01Id, String account, Long companyId) { + AccountSdfRequestPart req = new AccountSdfRequestPart(); + req.setAccount(account); + req.setCompanyId(companyId); + req.setAccountType(AccountType.Clrn.getKey()); + req.setSdfId(sdf01Id); + return req; + } + + + private SDf02 createErrorSdf02(SDf01 sdf01, EnumMessage error, Long generationIdForGroup) { + SDf02 sDf02 = new SDf02(); + sDf02.setCurr_code(sdf01.getCurr_code()); + sDf02.setAccount(sdf01.getAccount()); + sDf02.setRemainder(sdf01.getRemainder()); + sDf02.setDeal(sdf01.getDeal()); + sDf02.setAcc_code(sdf01.getAcc_code()); + sDf02.setDat(sdf01.getDat()); + sDf02.setMarket(sdf01.getMarket()); + sDf02.setAcc_name(sdf01.getAcc_name()); + sDf02.setAcc_type(sdf01.getAcc_type()); + sDf02.setSumengage(sdf01.getSumengage()); + sDf02.setSumunblock(sdf01.getSumunblock()); + sDf02.setFile_type(sdf01.getFile_type()); + sDf02.setInSDfId(sdf01.getId()); + String errorId = error.getSubject().getId().toString(); + sDf02.setResult(errorId.substring(errorId.length() - 3)); + sDf02.setGenerationId(generationIdForGroup); + sDf02.setGenerationTime(Instant.now()); + return sDf02; + } + + private SDf02 createSuccessSdf02(SDf01 sdf01, Long generationIdForGroup) { + SDf02 sDf02 = new SDf02(); + sDf02.setCurr_code(sdf01.getCurr_code()); + sDf02.setAccount(sdf01.getAccount()); + sDf02.setRemainder(sdf01.getRemainder()); + sDf02.setDeal(sdf01.getDeal()); + sDf02.setAcc_code(sdf01.getAcc_code()); + sDf02.setDat(sdf01.getDat()); + sDf02.setMarket(sdf01.getMarket()); + sDf02.setAcc_name(sdf01.getAcc_name()); + sDf02.setAcc_type(sdf01.getAcc_type()); + sDf02.setSumengage(sdf01.getSumengage()); + sDf02.setSumunblock(sdf01.getSumunblock()); + sDf02.setFile_type(sdf01.getFile_type()); + sDf02.setInSDfId(sdf01.getId()); + sDf02.setGenerationId(generationIdForGroup); + sDf02.setGenerationTime(Instant.now()); + sDf02.setResult("OK!"); + return sDf02; + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/Sdf01NewValidationRule.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/Sdf01NewValidationRule.java new file mode 100644 index 000000000..a431286dd --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/Sdf01NewValidationRule.java @@ -0,0 +1,93 @@ +package ru.spcex.clearing.service.validation; + +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.sdf.SDf01; +import ru.spcex.clearing.error.ClearingError; +import ru.spcex.clearing.error.ClearingErrorInternal; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.enumeration.AccType; +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.IEnumKey; +import ru.spcex.platform.utils.text.TextUtil; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Optional; + +public enum Sdf01NewValidationRule implements IValidationRule> { + CompanyPresent() { + @Override + public Optional validate(ImdgValidationContext context) { + SDf01 sdf01 = context.getValidatedObject(); + Imdg companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); + + if (TextUtil.isEmpty(sdf01.getDeal())) { + of(ClearingError.CompanyNotFoundB, sdf01.getDeal()); + } + + Company company = companyImdg.getSingleObjectBySQL("tradingCode = '" + sdf01.getDeal() + "'"); + if (company == null) { + of(ClearingError.CompanyNotFoundB, sdf01.getDeal()); + } + context.storeObject(ValidationStored.Sdf01Company, company); + return empty(); + } + }, AccountType() { + @Override + public Optional validate(ImdgValidationContext context) { + SDf01 sdf01 = context.getValidatedObject(); + + if (!IEnumKey.contains(sdf01.getAcc_type(), AccType.A, AccType.B)) { + of(ClearingError.AccountWrongType, sdf01.getAcc_type()); + } + return empty(); + } + }, AccountPresent() { + @Override + public Optional validate(ImdgValidationContext context) { + SDf01 sdf01 = context.getValidatedObject(); + Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); + Account acc = accountImdg.getSingleObjectBySQL("account = '" + sdf01.getAccount() + + "' and accountType='" + ru.spcex.platform.enumeration.AccountType.Clrn.getKey() + "'"); + if (acc == null) { + return of (ClearingErrorInternal.AccountNotPresent, sdf01.getAccount()); + } + context.storeObject(ValidationStored.Sdf01Account, acc); + return empty(); + } + }, CurrencyCode() { + @Override + public Optional validate(ImdgValidationContext context) { + SDf01 sdf01 = context.getValidatedObject(); + if (!ru.spcex.platform.enumeration.CurrencyCode.RUR.equalsByKey(sdf01.getCurr_code())) { + return of(ClearingError.CurrencyNotFound, sdf01.getCurr_code()); + } + return empty(); + } + }, DatIsCurrentDt() { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yy"); + @Override + public Optional validate(ImdgValidationContext context) { + SDf01 sdf01 = context.getValidatedObject(); + LocalDate parse; + try { + parse = LocalDate.parse(sdf01.getDat(), formatter); + } catch (Exception e) { + return of(ClearingError.OperationCanBeRunForTodayOnly, sdf01.getDat()); + } + if (!LocalDate.now().equals(parse)) { + return of(ClearingError.OperationCanBeRunForTodayOnly, sdf01.getDat()); + } + return empty(); + } + }; + + @Override + public String ruleName() { + return "Sdf01NewValidationRule." + name(); + } +} 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 861950ecb..aed0a13fe 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 @@ -4,5 +4,7 @@ public enum ValidationStored { STradesCompany, STradesCounterCompany, STradesSecurity, STradesTradingClearingRegistry, Account, Company, - Sdf57CompanyDeb, Sdf57CompanyCred, Sdf57AccountDeb, Sdf57AccountCred + Sdf57CompanyDeb, Sdf57CompanyCred, Sdf57AccountDeb, Sdf57AccountCred, + + Sdf01Company, Sdf01Account } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java index 7beadc73e..dd081532c 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java @@ -33,6 +33,7 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali private final ObligationAdmission obligationsAdmission; private final InclusionObligations inclusionObligations; + private final InspectionObligations inspectionObligations; private final FormingRegistersOnOS formingRegistersOnOS; private final FormingPaymentInstruction formingPaymentInstruction; private final UnlockResources unlockResources; @@ -51,7 +52,7 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali FormingRegistersOnOS formingRegistersOnOS, FormingPaymentInstruction formingPaymentInstruction, UnlockResources unlockResources, - FinishingSession finishingSession, EndStageNotification endStageNotification, IMessageResolver messageResolver) { + FinishingSession finishingSession, EndStageNotification endStageNotification, IMessageResolver messageResolver, InspectionObligations inspectionObligations) { super(imdgProvider, messageResolver); this.balanceRevise = balanceRevise; this.dealsPrepare = dealsPrepare; @@ -64,6 +65,7 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali this.finishingSession = finishingSession; this.endStageNotification = endStageNotification; this.executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class); + this.inspectionObligations = inspectionObligations; } @Override @@ -87,14 +89,14 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali } } - public void continueSession(BaseRequest req) { + public void continueSessionFirstPart(BaseRequest req) { try { if (!checkStage(TaskType.StartRevise)) { log.error("cannot continue session, current stage is {}", currStage.get()); throw new StageException(); } - //stage 0 - runStage(TaskType.ContinueRevise, balanceRevise); +// //stage 0 +// runStage(TaskType.ContinueRevise, balanceRevise); //stage 1 StageResult> dealsPreparationResult; { @@ -116,17 +118,22 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali { InspectionPoolPayload companyIdPayload = new InspectionPoolPayload(); companyIdPayload.setProcessedCompanyId(currSession.getCompanyId()); - runStage(TaskType.InspectionObligations, companyIdPayload, inclusionObligations); + runStage(TaskType.InspectionObligations, companyIdPayload, inspectionObligations); } //stage 6 runStage(TaskType.FormingRegistersOnOS, formingRegistersOnOS); //returns Collection //stage 7 runStage(TaskType.FormingPaymentInstruction, formingPaymentInstruction); - //stage 8 - { - UnlockResourcesPayload unlockResourcesPayload = new UnlockResourcesPayload(); - //todo set arguments - runStage(TaskType.UnlockResources, unlockResourcesPayload, unlockResources); //returns Collection + } catch (StageException e) { + //already logged + } + } + + public void continueSessionSecondPart(BaseRequest req) { + try { + if (!checkStage(TaskType.FormingPaymentInstruction)) { + log.error("cannot continue session, current stage is {}", currStage.get()); + throw new StageException(); } //stage 9 { diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionT0Session.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionT0Session.java new file mode 100644 index 000000000..3289b5ba0 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionT0Session.java @@ -0,0 +1,165 @@ +package ru.spcex.clearing.session.stage; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.execution.ExecutionCommon; +import ru.clearing.classes.statics.data.execution.ExecutionFond; +import ru.clearing.classes.statics.data.misc.Session; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.session.stage.impl.*; +import ru.spcex.clearing.session.stage.task.*; +import ru.spcex.platform.classes.base.interfaces.ExecutionType; +import ru.spcex.platform.enumeration.MarketType; +import ru.spcex.platform.enumeration.Section; +import ru.spcex.platform.enumeration.SessionStatus; +import ru.spcex.platform.enumeration.SessionType; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.utils.enumeration.IMessageResolver; + +import java.util.List; + +@Service +public class PrimaryAuctionT0Session extends AbstractSession implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final BalanceRevise balanceRevise; + private final DealsPrepare dealsPrepare; + private final RequirementsAndObligationCreation requirementsAndObligationCreation; + private final ObligationAdmission obligationsAdmission; + + private final InclusionObligations inclusionObligations; + private final FormingRegistersOnOS formingRegistersOnOS; + private final FormingPaymentInstruction formingPaymentInstruction; + private final UnlockResources unlockResources; + private final FinishingSession finishingSession; + private final EndStageNotification endStageNotification; + + private final Imdg executionFondImdg; + + public PrimaryAuctionT0Session( + ImdgProvider imdgProvider, + BalanceRevise balanceRevise, + DealsPrepare dealsPrepare, + RequirementsAndObligationCreation requirementsAndObligationCreation, + ObligationAdmission obligationsAdmission, + InclusionObligations inclusionObligations, + FormingRegistersOnOS formingRegistersOnOS, + FormingPaymentInstruction formingPaymentInstruction, + UnlockResources unlockResources, + FinishingSession finishingSession, EndStageNotification endStageNotification, IMessageResolver messageResolver) { + super(imdgProvider, messageResolver); + this.balanceRevise = balanceRevise; + this.dealsPrepare = dealsPrepare; + this.requirementsAndObligationCreation = requirementsAndObligationCreation; + this.obligationsAdmission = obligationsAdmission; + this.inclusionObligations = inclusionObligations; + this.formingRegistersOnOS = formingRegistersOnOS; + this.formingPaymentInstruction = formingPaymentInstruction; + this.unlockResources = unlockResources; + this.finishingSession = finishingSession; + this.endStageNotification = endStageNotification; + this.executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class); + } + + @Override + public void afterPropertiesSet() throws Exception { + dealsPrepare.searchForExecutions(ExecutionType.ExecutionFond); + ImdgPredicateBuilder execFondPb = executionFondImdg.predicateBuilder(); + dealsPrepare.addExecutionFondCondition(execFondPb.regex("settlementCode", "^T0.*$")); + dealsPrepare.addExecutionFondCondition(execFondPb.equals("marketType", MarketType.PRMR.getKey())); + } + + public void runSession(BaseRequest req) { + if (!startSession()) { + return; + } + StageResult submit = balanceRevise.submit(new Task<>(TaskType.StartRevise, null)); + if (!submit.success) { + log.error("stage {} error={}", balanceRevise.getClass().getSimpleName(), messageResolver.resolve(submit.error)); + endSession(); + } else { + log.info("stage BalanceRevise success, waiting for a response from kafka"); + } + } + + public void continueSession(BaseRequest req) { + try { + if (!checkStage(TaskType.StartRevise)) { + log.error("cannot continue session, current stage is {}", currStage.get()); + throw new StageException(); + } + //stage 0 + runStage(TaskType.ContinueRevise, balanceRevise); + //stage 1 + StageResult> dealsPreparationResult; + { + DealsPreparePayload payload = new DealsPreparePayload(); + payload.setSessionId(currSession.getId()); + dealsPreparationResult = runStage(TaskType.DealsPrepare , payload, dealsPrepare); + } + //stage 2 + runStage(TaskType.RequirementsAndObligationsCreate, dealsPreparationResult.getStageResult(), requirementsAndObligationCreation); + //stage 3 + runStage(TaskType.ObligationsAdmission, currSession.getId(), obligationsAdmission); + //stage 4 + { + InclusionToPoolPayload inclusionToPoolPayload = new InclusionToPoolPayload(); + inclusionToPoolPayload.setSessionType(currSession.getSessionType()); + runStage(TaskType.InclusionToPool, inclusionToPoolPayload, inclusionObligations); + } + //stage 5 + { + InspectionPoolPayload companyIdPayload = new InspectionPoolPayload(); + companyIdPayload.setProcessedCompanyId(currSession.getCompanyId()); + runStage(TaskType.InspectionObligations, companyIdPayload, inclusionObligations); + } + //stage 6 + runStage(TaskType.FormingRegistersOnOS, formingRegistersOnOS); //returns Collection + //stage 7 + runStage(TaskType.FormingPaymentInstruction, formingPaymentInstruction); + //stage 8 + { + UnlockResourcesPayload unlockResourcesPayload = new UnlockResourcesPayload(); + //todo set arguments + runStage(TaskType.UnlockResources, unlockResourcesPayload, unlockResources); //returns Collection + } + //stage 9 + { + FinishingSessionPayload payload = new FinishingSessionPayload(); + payload.setSessionId(currSession.getId()); + runStage(TaskType.FinishingSession, payload, finishingSession); + } + { + EndStageNotificationPayload payload = new EndStageNotificationPayload(); + payload.setSection(currSession.getSection()); + runStage(TaskType.EndStageNotification, payload, endStageNotification); + } + } catch (StageException e) { + //already logged + } + } + + private boolean startSession() { + synchronized (this.currStage) { + if (this.currStage.get() != null) { + log.info("already running session.id={}", this.currSession.getId()); + return false; + } else { + Session newSession = new Session(); + newSession.setSection(Section.FOND.getKey()); + newSession.setSessionType(SessionType.IPOT.getKey()); + newSession.setSessionStatus(SessionStatus.CLRN.getKey()); + //todo companyId/securityId/userId передается из сообщения очереди + sessionImdg.insert(newSession); + currSession = newSession; + log.info("started new session.id={}", this.currSession.getId()); + currStage.set(TaskType.StartRevise); + return true; + } + } + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/BalanceRevise.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/BalanceRevise.java index d962c1355..4f606bb1e 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/BalanceRevise.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/BalanceRevise.java @@ -19,6 +19,7 @@ import ru.spcex.platform.enumeration.*; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder; import ru.spcex.platform.imdg.api.predicate.specific.StatementRevisePredicate; import ru.spcex.platform.utils.enumeration.IEnumKey; @@ -58,7 +59,8 @@ public class BalanceRevise implements ISessionStage { return sendSdfs(); } case ContinueRevise -> { - cashFlow(); //((SdfClearingRequest) task.getData()).getGroupId() if needed + //больше не используются, удалить после проверки + cashFlow(); //((SdfClearingRequest) task.getData()).getGroupId() if needed //todo убрать это отсюда return revise(); } default -> throw new IllegalStateException("unknown task " + task.getTaskType()); @@ -93,32 +95,31 @@ public class BalanceRevise implements ISessionStage { Collection stmts = statementImdg.getCollectionObjectsBySQL(statementSQL); for (Statement stmt : stmts) { - String unformatted = "registry_designation = '%s' " + - "and registry_instrument_type = '%s' " + - "and registry_unit = '%s' " + - "and account = '%s' " + - "and securityId = %d"; + String unformatted = "%s and account = '%s' and securityId = %d"; + + RegistryTradingParams registryAMT = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.M, + null, RegistryUnit.T); + RegistryTradingParams registryAMF = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.M, + null, RegistryUnit.F); + RegistryTradingParams registryAMB = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.M, + null, RegistryUnit.B); + String registrySqlAMT = String.format(unformatted, - RegistryDesignation.A.getKey(), - RegistryInstrumentType.M.getKey(), - RegistryUnit.T.getKey(), + RegistryCodeSqlBuilder.getInstance(registryAMT).build(), stmt.getAccount(), stmt.getSecurityId() ); String registrySqlAMF = String.format(unformatted, - RegistryDesignation.A.getKey(), - RegistryInstrumentType.M.getKey(), - RegistryUnit.F.getKey(), + RegistryCodeSqlBuilder.getInstance(registryAMF).build(), stmt.getAccount(), stmt.getSecurityId() ); String registrySqlAMB = String.format(unformatted, - RegistryDesignation.A.getKey(), - RegistryInstrumentType.M.getKey(), - RegistryUnit.B.getKey(), + RegistryCodeSqlBuilder.getInstance(registryAMB).build(), stmt.getAccount(), stmt.getSecurityId() ); + Registry rgsAMT = registryImdg.getSingleObjectBySQL(registrySqlAMT); Registry rgsAMF = registryImdg.getSingleObjectBySQL(registrySqlAMF); Registry rgsAMB = registryImdg.getSingleObjectBySQL(registrySqlAMB); @@ -152,14 +153,11 @@ public class BalanceRevise implements ISessionStage { InOutSDfType.type1.getKey(), OperationStatus.Pending.getKey(), StatementType.full.getKey()); Collection stmts = statementImdg.getCollectionObjectsBySQL(statementSQL); for (Statement stmt : stmts) { - String registrySqlAMT = String.format("registry_designation = '%s' " + - "and registry_instrument_type = '%s' " + - "and registry_unit = '%s' " + - "and account = '%s' " + - "and securityId = %d", - RegistryDesignation.A.getKey(), - RegistryInstrumentType.M.getKey(), - RegistryUnit.T.getKey(), + + RegistryTradingParams registryAMT = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.M, + null, RegistryUnit.T); + String registrySqlAMT = String.format("%s and account = '%s' and securityId = %d", + RegistryCodeSqlBuilder.getInstance(registryAMT).build(), stmt.getAccount(), stmt.getSecurityId() ); @@ -175,7 +173,7 @@ public class BalanceRevise implements ISessionStage { } private void newSDf56(Statement statement) { - log.debug("GALB request received; creating sdf56"); + log.debug("creating sdf56"); SDf56 sDf56 = new SDf56(); sDf56.setNumber(idGenerator.nextId().toString()); Instant now = Instant.now(); diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/InspectionObligations.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/InspectionObligations.java index 5f60447d6..3f3291863 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/InspectionObligations.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/InspectionObligations.java @@ -12,12 +12,11 @@ import ru.spcex.clearing.session.stage.ISessionStage; import ru.spcex.clearing.session.stage.StageResult; import ru.spcex.clearing.session.stage.Task; import ru.spcex.clearing.session.stage.task.InspectionPoolPayload; -import ru.spcex.platform.enumeration.RegistryDesignation; -import ru.spcex.platform.enumeration.RegistryInstrumentType; -import ru.spcex.platform.enumeration.RegistryUnit; +import ru.spcex.platform.enumeration.*; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IEnumKey; import ru.spcex.platform.utils.enumeration.IMessageResolver; @@ -62,15 +61,18 @@ public class InspectionObligations implements ISessionStage { private StageResult inspectionPool(Long processedCompanyId) { - String sqlCondition = String.format("registryDesignation in ('%s', '%s') and " + - "registryInstrumentType in ('%s', '%s') and " + - "registryUnit = '%s' and " + - "registryStatus = '%s' and " + - "settlementDate = '%s'", - RegistryDesignation.O.getKey(), RegistryDesignation.T.getKey(), - RegistryInstrumentType.S.getKey(), RegistryInstrumentType.M.getKey(), - RegistryUnit.T.getKey(), - "POOL"); + RegistryTradingParams registryTradingParamsOST = new RegistryTradingParams(RegistryDesignation.O, + RegistryInstrumentType.S, + null, + RegistryUnit.T); + RegistryTradingParams registryTradingParamsTMT = new RegistryTradingParams(RegistryDesignation.T, + RegistryInstrumentType.M, + null, + RegistryUnit.T); + + String sqlCondition = String.format("%s and registryStatus = '%s'", + RegistryCodeSqlBuilder.getInstance(registryTradingParamsOST, registryTradingParamsTMT).build(), + RegistryStatus.POOL.getKey()); Collection obligations = registryImdg.getCollectionObjectsBySQL(sqlCondition); Map>> registryByGroupIdAndCompanyId = obligations.stream(). diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/UnlockResources.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/UnlockResources.java index c9771965d..837461e73 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/UnlockResources.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/UnlockResources.java @@ -27,6 +27,8 @@ import java.util.Collection; @Service @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +@Deprecated +//не должен использоваться как stage в сессии, данная логика перенесена в statementService public class UnlockResources implements ISessionStage { private final Logger log = LoggerFactory.getLogger(getClass()); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java index 9c8ae450e..7dd825470 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java @@ -4,22 +4,17 @@ 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.CompanySymbols; -import ru.clearing.platform.dictionary.*; +import ru.clearing.platform.dictionary.CompanySymbolDictionary; import ru.spcex.clearing.company.error.CompanyErrors; -import ru.spcex.clearing.company.validation.CompanySymbolNotExistRule; import ru.spcex.clearing.company.validation.CompanySymbolOfSymbolNewRequestNotExistRule; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyInfoUpdateRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolUpdateRequest; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; -import ru.spcex.clearing.validation.common.rules.EnumPresentRule; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.platform.classes.base.SpcexObjectBase; -import ru.spcex.platform.enumeration.CompanySymbol; -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.validation.IValidator; @@ -33,16 +28,16 @@ import java.util.function.Function; public class CompanySymbolValidationConfig { @Bean("companySymbolNewRequestValidator") - public Function companySymbolNewRequestValidator(Map> imdgForValidation) { - return companySymbolUpdateRequest -> { - ImdgValidationContext context = new ImdgValidationContext<>(); - context.setValidatedObject(companySymbolUpdateRequest); + public Function companySymbolNewRequestValidator(Map> imdgForValidation) { + return companySymbolNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(companySymbolNewRequest); Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); addImdg.accept(IMDGDistributedNames.Map_CompanySymbols); addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary); addImdg.accept(IMDGDistributedNames.Map_Company); return new ValidatorImpl<>(context, - FieldRequiredRule.instance("companyId", CompanySymbolUpdateRequest::getCompanyId, CompanyErrors.RequiredFieldEmpty), + FieldRequiredRule.instance("companyId", CompanySymbolNewRequest::getCompanyId, CompanyErrors.RequiredFieldEmpty), IdPresentRule.instance("companyId", CompanySymbolUpdateRequest::getCompanyId, IMDGDistributedNames.Map_Company, @@ -52,7 +47,7 @@ public class CompanySymbolValidationConfig { // FieldRequiredRule.instance("companySymbol", CompanySymbolUpdateRequest::getCompanySymbol, CompanyErrors.RequiredFieldEmpty), // FieldRequiredRule.instance("companySymbolValue", CompanySymbolUpdateRequest::getCompanySymbolValue, CompanyErrors.RequiredFieldEmpty), DictionaryPresentRule.instance("companySymbol", - CompanySymbolUpdateRequest::getCompanySymbol, + CompanySymbolNewRequest::getCompanySymbol, IMDGDistributedNames.Map_CompanySymbolDictionary, CompanySymbolDictionary.class, CompanyErrors.RequiredFieldEmpty, @@ -104,4 +99,35 @@ public class CompanySymbolValidationConfig { ); }; } + + + @Bean("companySymbolDeleteRequestValidator") + public Function companySymbolDeleteRequestValidator( + Map> imdgForValidation + ) { + return companySymbolDeleteRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(companySymbolDeleteRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_DocumentTypeDictionary); + addImdg.accept(IMDGDistributedNames.Map_CompanySymbols); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + CommonDeleteRequest::getId, + IMDGDistributedNames.Map_CompanySymbols, + CompanySymbols.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.RecordNotFound, + companySymbol -> { + Imdg companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); + Company company = companyImdg.getSingleObjectByID(companySymbol.getCompanyId()); + if (company == null) { + return CompanyErrors.CompanyNotFound; + } + return null; + }) + ); + }; + } } diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ContactValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ContactValidationConfig.java index a69e7731c..e051d7c14 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ContactValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ContactValidationConfig.java @@ -7,14 +7,13 @@ import ru.clearing.classes.statics.data.profile.Contact; import ru.clearing.platform.dictionary.ContactTypeDictionary; import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.ContactNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.ContactUpdateRequest; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; -import ru.spcex.clearing.validation.common.rules.EnumPresentRule; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.platform.classes.base.SpcexObjectBase; -import ru.spcex.platform.enumeration.ContactTypes; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.validation.IValidator; @@ -92,4 +91,32 @@ public class ContactValidationConfig { }; } + @Bean("contactDeleteRequestValidator") + public Function contactDeleteRequestValidator( + Map> imdgForValidation + ) { + return contactDeleteRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(contactDeleteRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_Contact); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + CommonDeleteRequest::getId, + IMDGDistributedNames.Map_Contact, + Contact.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.RecordNotFound, + contact -> { + Imdg companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); + Company company = companyImdg.getSingleObjectByID(contact.getCompanyId()); + if (company == null) { + return CompanyErrors.ContactNotFound; + } + return null; + }) + ); + }; + } } diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/RelationValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/RelationValidationConfig.java index 959f62491..1f3d7b6de 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/RelationValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/RelationValidationConfig.java @@ -5,7 +5,7 @@ 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.platform.dictionary.ClearingCategoryDictionary; -import ru.clearing.platform.dictionary.WorkflowStatusDictionary; +import ru.clearing.platform.dictionary.ServiceStatusDictionary; import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; @@ -52,8 +52,8 @@ public class RelationValidationConfig { CompanyErrors.WrongFieldValue), DictionaryPresentRule.instance("serviceStatus", RelationNewRequest::getServiceStatus, - IMDGDistributedNames.Map_WorkflowStatusDictionary, - WorkflowStatusDictionary.class, + IMDGDistributedNames.Map_ServiceStatusDictionary, + ServiceStatusDictionary.class, CompanyErrors.RequiredFieldEmpty, CompanyErrors.WrongFieldValue) ); @@ -103,8 +103,8 @@ public class RelationValidationConfig { // CompanyErrors.WrongFieldValue), DictionaryPresentRule.instance("serviceStatus", RelationUpdateRequest::getServiceStatus, - IMDGDistributedNames.Map_WorkflowStatusDictionary, - WorkflowStatusDictionary.class, + IMDGDistributedNames.Map_ServiceStatusDictionary, + ServiceStatusDictionary.class, CompanyErrors.RequiredFieldEmpty, CompanyErrors.WrongFieldValue) ); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java index 5ee1b2778..72a2fc37d 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java @@ -11,7 +11,6 @@ import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.CompanySymbols; import ru.spcex.clearing.company.error.CompanyErrors; -import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -20,6 +19,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.CompanySymbol; import ru.spcex.platform.enumeration.UserRole; @@ -46,15 +46,13 @@ public class CompanyService extends QueueConsumer implements InitializingBean { private final ImdgId idSequence; private final Imdg companyIMap; protected UserRoleVerification userRoleVerification; - - private ValidationHelper validationHelper; - private Function companyNewRequestValidator; - private Function companyUpdateRequestValidator; - private Function companyDeleteRequestValidator; - protected CompanySymbolService companySymbolService; protected AccountNotificationHelper accountNotification; protected RelationService relationService; + private final ValidationHelper validationHelper; + private final Function companyNewRequestValidator; + private final Function companyUpdateRequestValidator; + private final Function companyDeleteRequestValidator; @Autowired public CompanyService(Consumer kafkaQueue, Producer kafkaProducer, @@ -134,7 +132,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { try { if (req.getCompanySymbol() != null) { CompanySymbols newSymbol = companySymbolService.createCompanySymbol(transaction, company.getId(), req.getCompanySymbol(), req.getCompanySymbolValue()); - updateCompanyBySymbol(company, newSymbol); + updateCompanyBySymbol(company, newSymbol, false); } company.setWorkflowStatus(req.getWorkflowStatus()); @@ -215,20 +213,26 @@ public class CompanyService extends QueueConsumer implements InitializingBean { return null; } - protected void updateCompanyBySymbol(Company company, CompanySymbols companySymbol) { + protected void updateCompanyBySymbol(Company company, CompanySymbols companySymbol, boolean shouldBeDeleted) { assert company.getId().equals(companySymbol.getCompanyId()); + String companySymbolValue = companySymbol.getCompanySymbolValue(); + String setUpValue = shouldBeDeletedOrSet(companySymbolValue, shouldBeDeleted); if (CompanySymbol.TRDC.equalsByKey(companySymbol.getCompanySymbol())) { - company.setTradingCode(companySymbol.getCompanySymbolValue()); + company.setTradingCode(setUpValue); } if (CompanySymbol.CLRC.equalsByKey(companySymbol.getCompanySymbol())) { - company.setClearingCode(companySymbol.getCompanySymbolValue()); + company.setClearingCode(setUpValue); } if (CompanySymbol.RGRC.equalsByKey(companySymbol.getCompanySymbol())) { - company.setRegistrationCode(companySymbol.getCompanySymbolValue()); + company.setRegistrationCode(setUpValue); } } - public synchronized void updateCompanyBySymbol(ImdgTransaction transaction, CompanySymbols companySymbol) throws ClearingBaseException { + private String shouldBeDeletedOrSet(String companySymbol, boolean shouldBeDeleted) { + return shouldBeDeleted ? "" : companySymbol; + } + + public synchronized void updateCompanyBySymbol(ImdgTransaction transaction, CompanySymbols companySymbol, boolean shouldBeDeleted) throws ClearingBaseException { if (companySymbol.getCompanyId() == null) { throw new IllegalArgumentException("Required companySymbol.companyId"); } @@ -241,7 +245,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { if (company == null) { throw new ClearingBaseException(new EnumMessage(CompanyErrors.CompanyNotFound, companySymbol.getCompanyId())); } - updateCompanyBySymbol(company, companySymbol); + updateCompanyBySymbol(company, companySymbol, shouldBeDeleted); company.setUpdated(Instant.now()); companyMap.update(company); log.debug("Company {} updated by change CompanySymbols {} ({})", diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanySymbolService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanySymbolService.java index cf534c0ea..41addee87 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanySymbolService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanySymbolService.java @@ -10,20 +10,24 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.company.CompanySymbols; -import ru.spcex.clearing.util.services.RequestHelper; +import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolUpdateRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; +import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.error.ClearingBaseException; import ru.spcex.platform.utils.validation.IValidator; @@ -35,13 +39,13 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB private final Logger log = LoggerFactory.getLogger(getClass()); private final ImdgProvider imdgProvider; private final ImdgId idSequence; - protected CompanyService companyService; - private final RequestHelper requestHelper; + protected CompanyService companyService; protected ValidationHelper validationHelper; protected UserRoleVerification userRoleVerification; - protected Function companySymbolNewRequestValidator; + protected Function companySymbolNewRequestValidator; protected Function companySymbolUpdateRequestValidator; + protected Function companySymbolDeleteRequestValidator; @Autowired public CompanySymbolService(Consumer kafkaQueue, Producer kafkaProducer, @@ -50,7 +54,9 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB ValidationHelper validationHelper, UserRoleVerification userRoleVerification, @Qualifier("companySymbolNewRequestValidator") - Function companySymbolNewRequestValidator, + Function companySymbolNewRequestValidator, + @Qualifier("companySymbolDeleteRequestValidator") + Function companySymbolDeleteRequestValidator, @Qualifier("companySymbolUpdateRequestValidator") Function companySymbolUpdateRequestValidator ) { @@ -64,16 +70,20 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB userRoleVerification.setRoleForVerification(UserRole.Admin); this.companySymbolNewRequestValidator = companySymbolNewRequestValidator; this.companySymbolUpdateRequestValidator = companySymbolUpdateRequestValidator; + this.companySymbolDeleteRequestValidator = companySymbolDeleteRequestValidator; } @Override public void afterPropertiesSet() { - callback(CompanySymbolUpdateRequest.class) + callback(CompanySymbolNewRequest.class) .setFunction(this::companySymbolNew) .forDestination(Consts.DESTINATION_COMPANY_SYMBOL_NEW, callbacks::put); callback(CompanySymbolUpdateRequest.class) .setFunction(this::companySymbolUpdate) .forDestination(Consts.DESTINATION_COMPANY_SYMBOL_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setFunction(this::companySymbolDelete) + .forDestination(Consts.DESTINATION_COMPANY_SYMBOL_DELETE, callbacks::put); init(); } @@ -82,8 +92,8 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB } - public RequestInfoUpdate companySymbolNew(BaseRequest symbolRequest) { - CompanySymbolUpdateRequest req = symbolRequest.getRequestPayload(); + public RequestInfoUpdate companySymbolNew(BaseRequest symbolRequest) { + CompanySymbolNewRequest req = symbolRequest.getRequestPayload(); log.debug("CompanySymbolNewRequest received, id={}", symbolRequest.getId()); { // validate RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(symbolRequest); @@ -107,7 +117,7 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB Imdg companySymbolsTMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); companySymbolsTMap.update(companySymbols); try { - companyService.updateCompanyBySymbol(transaction, companySymbols); + companyService.updateCompanyBySymbol(transaction, companySymbols, false); } catch (ClearingBaseException e) { return requestHelper.makeErrorResponse(symbolRequest, e.getEnumMsg()); } @@ -141,15 +151,18 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB try { Imdg companySymbolsTMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); companySymbols = companySymbolsTMap.getSingleObjectByID(req.getId()); -// companySymbols.setCompanySymbol(req.getCompanySymbol()); по ТЗ не должен менятся при обновлении + if (companySymbols == null) { + throw new ClearingBaseException(new EnumMessage(CompanyErrors.CompanyInfoNotFound, req.getId())); + } + if (!companySymbols.getCompanySymbol().equalsIgnoreCase(req.getCompanySymbolValue())) { + throw new ClearingBaseException(new EnumMessage(CompanyErrors.EditCompanySymbols, req.getId())); + } companySymbols.setCompanySymbolValue(req.getCompanySymbolValue()); companySymbolsTMap.update(companySymbols); - try { - companyService.updateCompanyBySymbol(transaction, companySymbols); - } catch (ClearingBaseException e) { - return requestHelper.makeErrorResponse(symbolRequest, e.getEnumMsg()); - } + companyService.updateCompanyBySymbol(transaction, companySymbols, false); txOk = true; + } catch (ClearingBaseException e) { + return requestHelper.makeErrorResponse(symbolRequest, e.getEnumMsg()); } finally { if (txOk) transaction.commitTransaction(); @@ -161,6 +174,42 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB return null; } + public RequestInfoUpdate companySymbolDelete(BaseRequest symbolRequest) { + CommonDeleteRequest req = symbolRequest.getRequestPayload(); + log.debug("CommonDeleteRequest for CompanySymbol received, id={}", symbolRequest.getId()); + + { // validate + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(symbolRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(symbolRequest, companySymbolDeleteRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + CompanySymbols companySymbols; + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + Imdg companySymbolsTMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + companySymbols = companySymbolsTMap.getSingleObjectByID(req.getId()); + if (companySymbols == null) { + throw new ClearingBaseException(new EnumMessage(CompanyErrors.CompanyInfoNotFound, req.getId())); + } + companySymbolsTMap.delete(companySymbols); + companyService.updateCompanyBySymbol(transaction, companySymbols, true); + txOk = true; + } catch (ClearingBaseException e) { + return requestHelper.makeErrorResponse(symbolRequest, e.getEnumMsg()); + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); + } + + log.debug("successfully processed, id {}", companySymbols.getId()); + return null; + } public CompanySymbols createCompanySymbol(ImdgTransaction transaction, Long companyId, String companySymbol, String companySymbolValue) { Objects.requireNonNull(companyId); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ContactService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ContactService.java index 7096e823f..48d592a95 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ContactService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ContactService.java @@ -12,6 +12,7 @@ import ru.clearing.classes.statics.data.profile.Contact; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.ContactNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.ContactUpdateRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; @@ -31,6 +32,7 @@ public class ContactService extends QueueConsumer implements InitializingBean { private final ValidationHelper validationHelper; private final Function contactNewRequestValidator; private final Function contactUpdateRequestValidator; + private final Function contactDeleteRequestValidator; private final UserRoleVerification userRoleVerification; @Autowired @@ -40,6 +42,7 @@ public class ContactService extends QueueConsumer implements InitializingBean { ValidationHelper validationHelper, UserRoleVerification userRoleVerification, @Qualifier("contactNewRequestValidator") Function contactNewRequestValidator, + @Qualifier("contactDeleteRequestValidator") Function contactDeleteRequestValidator, @Qualifier("contactUpdateRequestValidator") Function contactUpdateRequestValidator) { super(kafkaQueue, kafkaProducer); this.contactMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Contact, Contact.class); @@ -47,6 +50,7 @@ public class ContactService extends QueueConsumer implements InitializingBean { this.userRoleVerification = userRoleVerification; this.contactNewRequestValidator = contactNewRequestValidator; this.contactUpdateRequestValidator = contactUpdateRequestValidator; + this.contactDeleteRequestValidator = contactDeleteRequestValidator; } @Override @@ -57,6 +61,9 @@ public class ContactService extends QueueConsumer implements InitializingBean { callback(ContactUpdateRequest.class) .setFunction(this::contactUpdate) .forDestination(Consts.DESTINATION_CONTACT_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setFunction(this::companySymbolDelete) + .forDestination(Consts.DESTINATION_CONTACT_DELETE, callbacks::put); init(); } @@ -98,4 +105,22 @@ public class ContactService extends QueueConsumer implements InitializingBean { log.debug("successfully processed, id {}", contact.getId()); return null; } + + public RequestInfoUpdate companySymbolDelete(BaseRequest userRequest) { + log.debug("CommonDeleteRequest received for contact service."); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, contactDeleteRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + + CommonDeleteRequest req = userRequest.getRequestPayload(); + + Contact contact = contactMap.getSingleObjectByID(req.getId()); + + contactMap.delete(contact); + log.debug("successfully deleted, id {}", contact.getId()); + return null; + } } \ No newline at end of file diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java index b9fd8f5ad..69e18e241 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java @@ -9,11 +9,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; -import ru.clearing.classes.statics.data.company.ClearingMemberCategory; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.profile.ProfileDocument; import ru.spcex.clearing.company.error.CompanyErrors; -import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -23,6 +21,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentUp import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.DocumentTypes; import ru.spcex.platform.enumeration.WorkflowStatus; @@ -38,11 +37,6 @@ import java.util.function.Function; @Service public class ProfileDocumentService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); - private Imdg profileDocumentMap; - private Imdg companyMap; - private ImdgProvider imdgProvider; - private AccountNotificationHelper accountNotificationHelper; - private final CompanyService companyService; private final Function profileDocumentNewRequestValidator; private final Function profileDocumentUpdateRequestValidator; @@ -51,6 +45,10 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin private final UserRoleVerification userRoleVerification; protected IMessageResolver messageResolver; protected RequestHelper requestHelper; + private Imdg profileDocumentMap; + private Imdg companyMap; + private final ImdgProvider imdgProvider; + private final AccountNotificationHelper accountNotificationHelper; @Autowired public ProfileDocumentService(Consumer kafkaQueue, @@ -140,26 +138,25 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin deleteRequest, profileDocumentDeleteRequestValidator ); if (requestInfoUpdate != null) return requestInfoUpdate; - CommonDeleteRequest profileDocumentDeleteRequest = deleteRequest.getRequestPayload(); ProfileDocument profileDocument = profileDocumentMap.getSingleObjectByID(profileDocumentDeleteRequest.getId()); - - Company existCompany = profileDocument.getCompanyId() == null ? null : companyMap.getSingleObjectByID(profileDocument.getCompanyId()); - if (existCompany == null) { - log.warn("Company {} not found by profileDocument {}", profileDocument.getCompanyId(), profileDocument.getId()); - return requestHelper.makeErrorResponse(deleteRequest, CompanyErrors.CompanyNotFound, profileDocument.getCompanyId()); - } - if (!WorkflowStatus.Active.equalsByKey(existCompany.getWorkflowStatus())) { - log.debug("Company {} not active", profileDocument.getCompanyId()); - return requestHelper.makeErrorResponse(deleteRequest, CompanyErrors.CompanyNotFound, profileDocument.getCompanyId()); - } synchronized (companyService) { + Company existCompany = profileDocument.getCompanyId() == null ? null : companyMap.getSingleObjectByID(profileDocument.getCompanyId()); + if (existCompany == null) { + log.warn("Company {} not found by profileDocument {}", profileDocument.getCompanyId(), profileDocument.getId()); + return requestHelper.makeErrorResponse(deleteRequest, CompanyErrors.CompanyNotFound, profileDocument.getCompanyId()); + } + if (!WorkflowStatus.Active.equalsByKey(existCompany.getWorkflowStatus())) { + log.debug("Company {} not active", profileDocument.getCompanyId()); + return requestHelper.makeErrorResponse(deleteRequest, CompanyErrors.CompanyNotFound, profileDocument.getCompanyId()); + } + ImdgTransaction transaction = imdgProvider.newTransaction(); transaction.beginTransaction(); boolean txOk = false; try { - companyService.relationService.cancelingOfAgreementUpdateRelation(transaction, profileDocument.getCompanyId()); - Imdg txProfileDocumentMap= transaction.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); + companyService.relationService.cancelingOfAgreementUpdateRelation(transaction, profileDocument.getCompanyId()); + Imdg txProfileDocumentMap = transaction.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); txProfileDocumentMap.delete(profileDocument); txOk = true; } finally { diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java index 0fbd00f46..1e206c19f 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java @@ -12,15 +12,16 @@ import ru.clearing.classes.statics.data.company.ClearingMemberCategory; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.relation.Relation; import ru.spcex.clearing.company.error.CompanyErrors; -import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.company.*; +import ru.spcex.clearing.platform.messaging.domain.cud.company.RelationNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.RelationUpdateRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.ClearingCategory; import ru.spcex.platform.enumeration.ServiceProduct; @@ -30,7 +31,6 @@ import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; -import ru.spcex.platform.utils.enumeration.IEnumKey; import ru.spcex.platform.utils.error.ValidationException; import ru.spcex.platform.utils.validation.IValidator; @@ -42,7 +42,7 @@ import java.util.function.Function; import static ru.spcex.platform.enumeration.Service.FOND; import static ru.spcex.platform.enumeration.Service.MKR; -import static ru.spcex.platform.enumeration.SessionStatus.CLOS; +import static ru.spcex.platform.enumeration.ServiceStatus.Closed; import static ru.spcex.platform.utils.enumeration.IEnumKey.getEnumByKey; @Service @@ -59,9 +59,9 @@ public class RelationService extends QueueConsumer implements InitializingBean { protected RequestHelper requestHelper; protected ValidationHelper validationHelper; - private Function relationNewRequestValidator; - private Function relationUpdateRequestValidator; - private Function relationDeleteRequestValidator; + private final Function relationNewRequestValidator; + private final Function relationUpdateRequestValidator; + private final Function relationDeleteRequestValidator; @Autowired public RelationService(Consumer kafkaQueue, @@ -117,7 +117,7 @@ public class RelationService extends QueueConsumer implements InitializingBean { { //проверка заполнен ли serviceStatus String serviceStatus = req.getServiceStatus(); if (serviceStatus == null || serviceStatus.isEmpty()) { - Company company = companyMap.getSingleObjectByFieldValues(Map.of("id", req.getCompanyId())); + Company company = companyMap.getSingleObjectByID(req.getCompanyId()); req.setServiceStatus(company.getWorkflowStatus()); } } @@ -168,7 +168,7 @@ public class RelationService extends QueueConsumer implements InitializingBean { log.debug("Request has no status. Set status by resume: {}", relation.getServiceStatus()); } else { String toStatus = WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? ServiceStatus.Active.getKey() : - WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus()) ? ServiceStatus.Closed.getKey() : + WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus()) ? Closed.getKey() : null; log.debug("Request has no status. Set status by company[{}].status={}. Relation[{}].serviceSStatus={}", company.getId(), company.getWorkflowStatus(), toStatus); @@ -231,9 +231,9 @@ public class RelationService extends QueueConsumer implements InitializingBean { } Company company = companyMap.getSingleObjectByID(relation.getConsumerId()); String toStatus = WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? ServiceStatus.Active.getKey() : - WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus()) ? ServiceStatus.Closed.getKey() : + WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus()) ? Closed.getKey() : null; - if (ServiceStatus.Active.equalsByKey(toStatus) && ServiceStatus.Closed.equalsByKey(relation.getServiceStatus())) { + if (ServiceStatus.Active.equalsByKey(toStatus) && Closed.equalsByKey(relation.getServiceStatus())) { relation.setServiceStatus(ServiceStatus.Reopened.getKey()); log.debug("Set status by resume: {}", relation.getServiceStatus()); } else { @@ -287,9 +287,9 @@ public class RelationService extends QueueConsumer implements InitializingBean { ClearingMemberCategory clearingMemberCategory = transaction.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class).getSingleObjectByFieldValues(Map.of("companyId", companyId)); WorkflowStatus workflowStatus = getEnumByKey(WorkflowStatus.class, company.getWorkflowStatus()); - ClearingCategory clearingCategory = getEnumByKey(ClearingCategory.class, clearingMemberCategory.getClearingMemberCategory()); + ClearingCategory clearingCategory = getEnumByKey(ClearingCategory.class, clearingMemberCategory.getClearingMemberCategory()); String serviceStatus; - switch (Objects.requireNonNull(clearingCategory)){ + switch (Objects.requireNonNull(clearingCategory)) { case B: case I: case V: @@ -313,10 +313,11 @@ public class RelationService extends QueueConsumer implements InitializingBean { log.debug("New Relation[{}] created.", relation.getId()); relationMap.insert(relation); } + protected void cancelingOfAgreementUpdateRelation(ImdgTransaction transaction, Long companyId) { Imdg relationMap = transaction.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); Relation relation = relationMap.getSingleObjectByFieldValues(Map.of("consumerId", companyId)); - relation.setServiceStatus(CLOS.getKey()); + relation.setServiceStatus(Closed.getKey()); relationMap.update(relation); log.debug("New Relation[{}] updated.", relation.getId()); } @@ -356,8 +357,8 @@ public class RelationService extends QueueConsumer implements InitializingBean { modified = true; } } else if (WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus())) { - if (!ServiceStatus.Closed.equalsByKey(relation.getServiceStatus())) { - relation.setServiceStatus(ServiceStatus.Closed.getKey()); + if (!Closed.equalsByKey(relation.getServiceStatus())) { + relation.setServiceStatus(Closed.getKey()); modified = true; } } diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolOfSymbolNewRequestNotExistRule.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolOfSymbolNewRequestNotExistRule.java index 1e15c4986..f8dba7678 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolOfSymbolNewRequestNotExistRule.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolOfSymbolNewRequestNotExistRule.java @@ -3,17 +3,12 @@ package ru.spcex.clearing.company.validation; import ru.clearing.classes.statics.data.company.CompanySymbols; import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.imdg.IMDGDistributedNames; -import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolUpdateRequest; -import ru.spcex.platform.enumeration.CompanySymbol; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolNewRequest; import ru.spcex.platform.imdg.api.Imdg; -import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; -import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.validation.IValidationRule; -import java.util.Arrays; import java.util.Collection; import java.util.Map; import java.util.Optional; @@ -21,10 +16,10 @@ import java.util.Optional; /** * Проверка наличия CompanySymbols с переданными в запросе companySymbol и companyId */ -public class CompanySymbolOfSymbolNewRequestNotExistRule implements IValidationRule> { +public class CompanySymbolOfSymbolNewRequestNotExistRule implements IValidationRule> { @Override - public Optional validate(ImdgValidationContext context) { - CompanySymbolUpdateRequest request = context.getValidatedObject(); + public Optional validate(ImdgValidationContext context) { + CompanySymbolNewRequest request = context.getValidatedObject(); Imdg companySymbolsImdg = context.obtainMap(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccType.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccType.java new file mode 100644 index 000000000..d9a2b851b --- /dev/null +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccType.java @@ -0,0 +1,18 @@ +package ru.spcex.platform.enumeration; + +import ru.spcex.platform.utils.enumeration.IEnumKey; + +public enum AccType implements IEnumKey { + A("A"), B("B"); + + private final String key; + + AccType(String key) { + this.key = key; + } + + @Override + public String getKey() { + return key; + } +} diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/MarketType.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/MarketType.java index 930e40a2c..cc338474d 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/MarketType.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/MarketType.java @@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; public enum MarketType implements IEnumKey { - PRMR("PRMR"); + PRMR("PRMR"), SCND("SCND"); private final String key; diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryStatus.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryStatus.java index 6c6536495..381da2f07 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryStatus.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryStatus.java @@ -6,7 +6,8 @@ public enum RegistryStatus implements IEnumKey { OK("OK"), PROC("PROC"), NACK("NACK"), - FAIL("FAIL") + FAIL("FAIL"), + POOL("POOL") ; private final String key; diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SdfTable.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SdfTable.java index 0d885df19..6a920d430 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SdfTable.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SdfTable.java @@ -3,7 +3,9 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; public enum SdfTable implements IEnumKey { - SDF_01("SDF_01"), SDF_57("SDF_57"), SDF_09("SDF_09"), SDF_16("SDF_16"); + SDF_01("SDF_01"), SDF_04("SDF_04"), SDF_08("SDF_08"), + SDF_13("SDF_13"), SDF_57("SDF_57"), SDF_09("SDF_09"), + SDF_16("SDF_16"); SdfTable(String key) { this.key = key; diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SessionType.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SessionType.java index 43ea888fb..b299f910f 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SessionType.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SessionType.java @@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; public enum SessionType implements IEnumKey { - IPOB("IPOB"), IPO0("IPO0"), + IPOB("IPOB"), IPO0("IPO0"), IPOT("IPOT"), ; SessionType(String key) { diff --git a/platform-parent/platform-imdg-api/pom.xml b/platform-parent/platform-imdg-api/pom.xml index 1c6e12c22..69d60ff13 100644 --- a/platform-parent/platform-imdg-api/pom.xml +++ b/platform-parent/platform-imdg-api/pom.xml @@ -33,5 +33,25 @@ ru.spcex.platform platform-utils + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core + test + + + org.mockito + mockito-core + + + org.springframework.boot + spring-boot-starter-test + test + \ No newline at end of file diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilder.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilder.java index 1d4d23329..376b4cdde 100644 --- a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilder.java +++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilder.java @@ -52,6 +52,10 @@ public class RegistryCodeSqlBuilder { } if (tradingParams.registryUnit() != null) { condition.append(String.format("registryUnit = '%s'", tradingParams.registryUnit().getKey())); + wasAddedCondition = true; + } + if (!wasAddedCondition) { + condition.delete(condition.length() - " and ".length(), condition.length()); } conditions.add(condition); } diff --git a/platform-parent/platform-imdg-api/src/test/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilderTest.java b/platform-parent/platform-imdg-api/src/test/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilderTest.java new file mode 100644 index 000000000..0410b7c4f --- /dev/null +++ b/platform-parent/platform-imdg-api/src/test/java/ru/spcex/platform/imdg/api/predicate/specific/RegistryCodeSqlBuilderTest.java @@ -0,0 +1,61 @@ +package ru.spcex.platform.imdg.api.predicate.specific; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import ru.spcex.platform.enumeration.*; + +public class RegistryCodeSqlBuilderTest { + + @Test + public void testBuildByOneObject() { + RegistryTradingParams registryTradingParams = new RegistryTradingParams(RegistryDesignation.C, RegistryInstrumentType.M, RegistryCapacity.B, RegistryUnit.R); + RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParams); + String sql = registryCodeSqlBuilder.build(); + Assertions.assertEquals("(registryDesignation = 'C' and registryInstrumentType = 'M' and registryCapacity = 'B' and registryUnit = 'R')", sql); + + registryTradingParams = new RegistryTradingParams(null, RegistryInstrumentType.M, RegistryCapacity.B, RegistryUnit.R); + registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParams); + sql = registryCodeSqlBuilder.build(); + Assertions.assertEquals("(registryInstrumentType = 'M' and registryCapacity = 'B' and registryUnit = 'R')", sql); + + registryTradingParams = new RegistryTradingParams(RegistryDesignation.C, null, null, RegistryUnit.R); + registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParams); + sql = registryCodeSqlBuilder.build(); + Assertions.assertEquals("(registryDesignation = 'C' and registryUnit = 'R')", sql); + } + + @Test + public void testBuildByFewObjects() { + RegistryTradingParams registryTradingParams_first = new RegistryTradingParams(RegistryDesignation.C, RegistryInstrumentType.M, RegistryCapacity.B, RegistryUnit.R); + RegistryTradingParams registryTradingParams_second = new RegistryTradingParams(RegistryDesignation.O, RegistryInstrumentType.S, RegistryCapacity.A, RegistryUnit.F); + RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParams_first, registryTradingParams_second); + String sql = registryCodeSqlBuilder.build(); + Assertions.assertEquals("(registryDesignation = 'C' and registryInstrumentType = 'M' and registryCapacity = 'B' and registryUnit = 'R')" + + " or (registryDesignation = 'O' and registryInstrumentType = 'S' and registryCapacity = 'A' and registryUnit = 'F')", sql); + + registryTradingParams_first = new RegistryTradingParams(null, RegistryInstrumentType.M, RegistryCapacity.B, RegistryUnit.R); + registryTradingParams_second = new RegistryTradingParams(null, RegistryInstrumentType.S, RegistryCapacity.A, RegistryUnit.F); + registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParams_first, registryTradingParams_second); + sql = registryCodeSqlBuilder.build(); + Assertions.assertEquals("(registryInstrumentType = 'M' and registryCapacity = 'B' and registryUnit = 'R') or " + + "(registryInstrumentType = 'S' and registryCapacity = 'A' and registryUnit = 'F')", sql); + + registryTradingParams_first = new RegistryTradingParams(RegistryDesignation.C, null, null, RegistryUnit.R); + registryTradingParams_second = new RegistryTradingParams(null, RegistryInstrumentType.S, RegistryCapacity.A, RegistryUnit.F); + registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParams_first, registryTradingParams_second); + sql = registryCodeSqlBuilder.build(); + Assertions.assertEquals("(registryDesignation = 'C' and registryUnit = 'R') or " + + "(registryInstrumentType = 'S' and registryCapacity = 'A' and registryUnit = 'F')", sql); + } + + @Test + public void test(){ + RegistryTradingParams registryTradingParamsL = new RegistryTradingParams(RegistryDesignation.L, + RegistryInstrumentType.S, null, RegistryUnit.T); + RegistryTradingParams registryTradingParamsC = new RegistryTradingParams(RegistryDesignation.C, + RegistryInstrumentType.M, null, null); + RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(registryTradingParamsL, registryTradingParamsC); + Assertions.assertEquals("(registryDesignation = 'L' and registryInstrumentType = 'S' and registryUnit = 'T') or (registryDesignation = 'C' and registryInstrumentType = 'M')", + registryCodeSqlBuilder.build()); + } +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java index e0197d92c..2c8a7c4aa 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java @@ -121,7 +121,8 @@ public interface Consts { String SDF53_PROCESS = "sdf53-process"; String SDF54_PROCESS = "sdf54-process"; String SDF56_PROCESS = "sdf56-process"; - String SDF57_PROCESS = "sdf57-process"; + String CONTINUE_SESSION_BN_FIRST_PART = "sdf57-process"; + String CONTINUE_SESSION_BN_SECOND_PART = "sdf13-process"; String REVISE_PROCESS = "revise-process"; String EXPORT_PROCESS = "export-process"; String EXPORT_COMPLETED = "export_completed"; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/clearing/ContinueSessionBnRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/clearing/ContinueSessionBnRequest.java new file mode 100644 index 000000000..e02afec3c --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/clearing/ContinueSessionBnRequest.java @@ -0,0 +1,16 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.clearing; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ContinueSessionBnRequest { + @JsonProperty + private Long generationId; + + public Long getGenerationId() { + return generationId; + } + + public void setGenerationId(Long generationId) { + this.generationId = generationId; + } +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanySymbolNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanySymbolNewRequest.java new file mode 100644 index 000000000..610fd1f6a --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanySymbolNewRequest.java @@ -0,0 +1,37 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.company; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class CompanySymbolNewRequest { + @JsonProperty + public Long companyId; + + @JsonProperty + private String companySymbol; + + @JsonProperty + private String companySymbolValue; + + public Long getCompanyId() { + return companyId; + } + + public void setCompanyId(Long companyId) { + this.companyId = companyId; + } + + public String getCompanySymbol() { + return companySymbol; + } + + public void setCompanySymbol(String companySymbol) { + this.companySymbol = companySymbol; + } + + public String getCompanySymbolValue() { + return companySymbolValue; + } + public void setCompanySymbolValue(String companySymbolValue) { + this.companySymbolValue = companySymbolValue; + } +}