Merge branch 'dev' into session-PREP-PAYM

This commit is contained in:
ialbert 2024-10-02 15:31:54 +03:00
commit c4390848c5
34 changed files with 11657 additions and 10109 deletions

View file

@ -0,0 +1,74 @@
package ru.spcex.clearing.backendapi.controller.queue.misc;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import ru.clearing.classes.statics.data.security.Rates;
import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController;
import ru.spcex.clearing.backendapi.controller.request.cud.securities.RatesNewAction;
import ru.spcex.clearing.backendapi.controller.request.cud.securities.RatesUpdateAction;
import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.backendapi.service.IOperator;
import ru.spcex.clearing.backendapi.service.IStateLoader;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
@Controller
@RequestMapping("/rates")
public class RatesController extends AbstractQueueController {
private final IStateLoader stateLoader;
@Autowired
public RatesController(IOperator operator, IStateLoader stateLoader) {
super(operator);
this.stateLoader = stateLoader;
}
@ApiOperation(value = "get all rates.")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAll() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(IMDGDistributedNames.Map_Rates, Rates.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "create rates.")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public CudResponse create(
@ApiParam(value = "Значения полей нового объекта.", required = true)
@RequestBody RatesNewAction ratesNewAction) throws ExecutionException, InterruptedException {
return processRequest(Consts.DESTINATION_RATES_NEW, ratesNewAction);
}
@ApiOperation(value = "update risk_parameter.")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
@RequestMapping(value = "/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public CudResponse update(
@ApiParam(value = "Идентификатор изменяемого объекта.", required = true, example = "1234")
@PathVariable("id") Long id,
@ApiParam(value = "Новые значения полей объекта.", required = true)
@RequestBody RatesUpdateAction ratesUpdateAction) throws ExecutionException, InterruptedException {
ratesUpdateAction.setId(id);
return processRequest(Consts.DESTINATION_RATES_UPDATE, ratesUpdateAction);
}
}

View file

@ -0,0 +1,74 @@
package ru.spcex.clearing.backendapi.controller.queue.misc;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import ru.clearing.classes.statics.data.security.RiskParameter;
import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController;
import ru.spcex.clearing.backendapi.controller.request.cud.securities.RiskParameterNewAction;
import ru.spcex.clearing.backendapi.controller.request.cud.securities.RiskParameterUpdateAction;
import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.backendapi.service.IOperator;
import ru.spcex.clearing.backendapi.service.IStateLoader;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.Consts;
@Controller
@RequestMapping("/risk-parameter")
public class RiskParameterController extends AbstractQueueController {
private final IStateLoader stateLoader;
@Autowired
public RiskParameterController(IOperator operator, IStateLoader stateLoader) {
super(operator);
this.stateLoader = stateLoader;
}
@ApiOperation(value = "get all risk_parameter.")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)})
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public CommonGetAllResponse getAll() {
Collection<Map<String, Object>> all = stateLoader.getAllMetaTransform(IMDGDistributedNames.Map_RiskParameter, RiskParameter.class);
CommonGetAllResponse response = new CommonGetAllResponse();
response.fromEntity(all);
return response;
}
@ApiOperation(value = "create risk_parameter.")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public CudResponse create(
@ApiParam(value = "Значения полей нового объекта.", required = true)
@RequestBody RiskParameterNewAction riskParameterNewAction) throws ExecutionException, InterruptedException {
return processRequest(Consts.DESTINATION_RISK_PARAMETER_NEW, riskParameterNewAction);
}
@ApiOperation(value = "update risk_parameter.")
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
@RequestMapping(value = "/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public CudResponse update(
@ApiParam(value = "Идентификатор изменяемого объекта.", required = true, example = "1234")
@PathVariable("id") Long id,
@ApiParam(value = "Новые значения полей объекта.", required = true)
@RequestBody RiskParameterUpdateAction riskParameterUpdateAction) throws ExecutionException, InterruptedException {
riskParameterUpdateAction.setId(id);
return processRequest(Consts.DESTINATION_RISK_PARAMETER_UPDATE, riskParameterUpdateAction);
}
}

View file

@ -0,0 +1,73 @@
package ru.spcex.clearing.backendapi.controller.request.cud.securities;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import java.time.LocalDate;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesNewRequest;
public class RatesNewAction implements IAction<RatesNewRequest> {
@ApiModelProperty(value = "Курс.", example = "1234")
@JsonProperty
private BigDecimal value;
@ApiModelProperty(value = "Дата.", example = "1234")
@JsonProperty
private LocalDate valueDate;
@ApiModelProperty(value = "Валюта.", example = "1234")
@JsonProperty
private Long currencyPairId;
@ApiModelProperty(value = "Статус.", example = "1234")
@JsonProperty
private String status;
@Override
public RatesNewRequest toRequest() {
RatesNewRequest request = new RatesNewRequest();
request.setValue(this.value);
request.setValueDate(this.valueDate);
request.setCurrencyId(this.currencyPairId);
request.setStatus(this.status);
return request;
}
@ApiModelProperty(hidden = true)
@Override
public ActionType getActionType() {
return ActionType.NEW;
}
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public LocalDate getValueDate() {
return valueDate;
}
public void setValueDate(LocalDate valueDate) {
this.valueDate = valueDate;
}
public Long getCurrencyPairId() {
return currencyPairId;
}
public void setCurrencyPairId(Long currencyPairId) {
this.currencyPairId = currencyPairId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}

View file

@ -0,0 +1,60 @@
package ru.spcex.clearing.backendapi.controller.request.cud.securities;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesUpdateRequest;
public class RatesUpdateAction implements IAction<RatesUpdateRequest> {
@ApiModelProperty(hidden = true)
@JsonProperty
public Long id;
@ApiModelProperty(value = "Курс.", example = "1234")
@JsonProperty
private BigDecimal value;
@ApiModelProperty(value = "Статус.", example = "1234")
@JsonProperty
private String status;
@Override
public RatesUpdateRequest toRequest() {
RatesUpdateRequest request = new RatesUpdateRequest();
request.setId(this.id);
request.setValue(this.value);
request.setStatus(this.status);
return request;
}
@ApiModelProperty(hidden = true)
@Override
public ActionType getActionType() {
return ActionType.NEW;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}

View file

@ -0,0 +1,72 @@
package ru.spcex.clearing.backendapi.controller.request.cud.securities;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterNewRequest;
public class RiskParameterNewAction implements IAction<RiskParameterNewRequest> {
@ApiModelProperty(value = "Курс.", example = "1234")
@JsonProperty
private BigDecimal value;
@ApiModelProperty(value = "Код расчёта.", example = "1234")
@JsonProperty
private String settlementType;
@ApiModelProperty(value = "Валютная пара.", example = "1234")
@JsonProperty
private Long currencyPairId;
@ApiModelProperty(value = "Статус.", example = "1234")
@JsonProperty
private String status;
@Override
public RiskParameterNewRequest toRequest() {
RiskParameterNewRequest request = new RiskParameterNewRequest();
request.setValue(this.value);
request.setSettlementType(this.settlementType);
request.setCurrencyPairId(this.currencyPairId);
request.setStatus(this.status);
return request;
}
@ApiModelProperty(hidden = true)
@Override
public ActionType getActionType() {
return ActionType.NEW;
}
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public String getSettlementType() {
return settlementType;
}
public void setSettlementType(String settlementType) {
this.settlementType = settlementType;
}
public Long getCurrencyPairId() {
return currencyPairId;
}
public void setCurrencyPairId(Long currencyPairId) {
this.currencyPairId = currencyPairId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}

View file

@ -0,0 +1,60 @@
package ru.spcex.clearing.backendapi.controller.request.cud.securities;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterUpdateRequest;
public class RiskParameterUpdateAction implements IAction<RiskParameterUpdateRequest> {
@ApiModelProperty(hidden = true)
@JsonProperty
public Long id;
@ApiModelProperty(value = "Курс.", example = "1234")
@JsonProperty
private BigDecimal value;
@ApiModelProperty(value = "Статус.", example = "1234")
@JsonProperty
private String status;
@Override
public RiskParameterUpdateRequest toRequest() {
RiskParameterUpdateRequest request = new RiskParameterUpdateRequest();
request.setId(this.id);
request.setValue(this.value);
request.setStatus(this.status);
return request;
}
@ApiModelProperty(hidden = true)
@Override
public ActionType getActionType() {
return ActionType.NEW;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--?xml-stylesheet type="text/xsl" href="\..\corp-reports\src\data\meta\meta.server.xslt"?-->
<meta version="3.14.105.104">
<meta version="3.15.206.105">
<!-- _xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _xsi:noNamespaceSchemaLocation="file:///E:/d/projects/meta/from/meta.xsd" -->
<!--Здесь словари-->
<enums>
@ -2442,6 +2442,22 @@
<code name="Код рынка" shortname="Код рынка" type="2" length="12"/>
<section name="Секция" shortname="Секция" type="12"/>
</blacklistMarket>
<riskParameter name="Параметры риска" destination="risk-parameter" class="ru.clearing.classes.statics.data.security.RiskParameter" table="risk-parameter">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" visible="true"/>
<value name="Ставка" shortname="Ставка" type="10"/>
<settlementType name="Код расчета" shortname="Код расчета" type="2" length="4"/>
<currencyPair name="Код валютной пары" shortname="Код валютной пары" type="2" length="12"/>
<currencyPairId name="Идентификатор валютной пары" shortname="Валютная пара" type="1"/>
<workflowStatus name="Статус" shortname="Секция" type="2" length="4"/>
</riskParameter>
<rates name="Расчетные курсы" destination="rates" class="ru.clearing.classes.statics.data.security.Rates" table="rates">
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" visible="true"/>
<value name="Расчетный курс" shortname="Расчетный курс" type="10"/>
<valueDate name="Дата, на которую расчетный курс" shortname="Дата" type="6"/>
<currency name="Код валюты" shortname="Код валюты" type="2" length="4"/>
<currencyId name="Идентификатор валюты" shortname="Валюта" type="1"/>
<workflowStatus name="Статус" shortname="Секция" type="2" length="4"/>
</rates>
</objects>
<views>
<AccountUnion>

View file

@ -0,0 +1,53 @@
package ru.clearing.classes.statics.data.security;
import java.math.BigDecimal;
import java.time.LocalDate;
import ru.clearing.classes.objects.BusinessObject;
public class Rates extends BusinessObject {
private BigDecimal value;
private LocalDate valueDate;
private String currency;
private Long currencyId;
private String workflowStatus;
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public LocalDate getValueDate() {
return valueDate;
}
public void setValueDate(LocalDate valueDate) {
this.valueDate = valueDate;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public Long getCurrencyId() {
return currencyId;
}
public void setCurrencyId(Long currencyId) {
this.currencyId = currencyId;
}
public String getWorkflowStatus() {
return workflowStatus;
}
public void setWorkflowStatus(String workflowStatus) {
this.workflowStatus = workflowStatus;
}
}

View file

@ -0,0 +1,52 @@
package ru.clearing.classes.statics.data.security;
import java.math.BigDecimal;
import ru.clearing.classes.objects.BusinessObject;
public class RiskParameter extends BusinessObject {
private BigDecimal value;
private String settlementType;
private String currencyPair;
private Long currencyPairId;
private String workflowStatus;
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public String getSettlementType() {
return settlementType;
}
public void setSettlementType(String settlementType) {
this.settlementType = settlementType;
}
public String getCurrencyPair() {
return currencyPair;
}
public void setCurrencyPair(String currencyPair) {
this.currencyPair = currencyPair;
}
public Long getCurrencyPairId() {
return currencyPairId;
}
public void setCurrencyPairId(Long currencyPairId) {
this.currencyPairId = currencyPairId;
}
public String getWorkflowStatus() {
return workflowStatus;
}
public void setWorkflowStatus(String workflowStatus) {
this.workflowStatus = workflowStatus;
}
}

View file

@ -5177,6 +5177,49 @@ COMMENT ON COLUMN BLACKLIST_MARKET.SECTION IS 'Секция';
GRANT ALL PRIVILEGES ON TABLE BLACKLIST_MARKET TO clearing;
CREATE TABLE RISK_PARAMETER
(
ID BIGINT,
VALUE numeric(72,18),
SETTLEMENT_TYPE VARCHAR(4),
CURRENCY_PAIR VARCHAR(12),
CURRENCY_PAIR_ID BIGINT,
CREATED_AT timestamp,
UPDATED_AT timestamp,
WORKFLOW_STATUS VARCHAR(4)
);
COMMENT ON TABLE RISK_PARAMETER IS 'Риск-параметры';
COMMENT ON COLUMN RISK_PARAMETER.ID IS 'Идентификатор записи';
COMMENT ON COLUMN RISK_PARAMETER.VALUE IS 'Ставка ';
COMMENT ON COLUMN RISK_PARAMETER.SETTLEMENT_TYPE IS 'Код расчета';
COMMENT ON COLUMN RISK_PARAMETER.CURRENCY_PAIR IS 'Код валютной пары';
COMMENT ON COLUMN RISK_PARAMETER.CURRENCY_PAIR_ID IS 'Идентификатор валютной пары';
COMMENT ON COLUMN RISK_PARAMETER.CREATED_AT IS 'Время создания записи';
COMMENT ON COLUMN RISK_PARAMETER.UPDATED_AT IS 'Время изменения записи';
COMMENT ON COLUMN RISK_PARAMETER.WORKFLOW_STATUS IS 'Статус';
GRANT ALL PRIVILEGES ON TABLE RISK_PARAMETER TO clearing;
CREATE TABLE RATES
(
ID BIGINT,
VALUE numeric(72, 18),
VALUE_DATE date,
CURRENCY VARCHAR(4),
CURRENCY_ID BIGINT,
CREATED_AT timestamp,
UPDATED_AT timestamp,
WORKFLOW_STATUS VARCHAR(4)
);
COMMENT ON TABLE RATES IS 'Расчетные курсы';
COMMENT ON COLUMN RATES.ID IS 'Идентификатор записи';
COMMENT ON COLUMN RATES.VALUE IS 'Расчетный курс';
COMMENT ON COLUMN RATES.VALUE_DATE IS 'Дата, на которую расчетный курс';
COMMENT ON COLUMN RATES.CURRENCY IS 'Код валюты';
COMMENT ON COLUMN RATES.CURRENCY_ID IS 'Идентификатор валюты';
COMMENT ON COLUMN RATES.CREATED_AT IS 'Время создания записи';
COMMENT ON COLUMN RATES.UPDATED_AT IS 'Время изменения записи';
COMMENT ON COLUMN RATES.WORKFLOW_STATUS IS 'Статус';
GRANT ALL PRIVILEGES ON TABLE RATES TO clearing;
/* views */
-- Data types

View file

@ -502,9 +502,9 @@ INSERT INTO PARENT_DICTIONARY(ID, CODE, NAME) values (2, 'PLNR', 'Расписа
INSERT INTO PARENT_DICTIONARY(ID, CODE, NAME) values (3, 'CLND', 'Календарь') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO CURRENCY_SETTLEMENT_TYPE_DICTIONARY(ID, CODE, NAME) values (1, 'TOD', 'Поставка сегодня') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO CURRENCY_SETTLEMENT_TYPE_DICTIONARY(ID, CODE, NAME) values (1, 'T0', 'Сегодня') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO CURRENCY_SETTLEMENT_TYPE_DICTIONARY(ID, CODE, NAME) values (2, 'TOM', 'Завтра') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO CURRENCY_SETTLEMENT_TYPE_DICTIONARY(ID, CODE, NAME) values (2, 'T1', 'Завтра') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO MAJOR_SIGN_DICTIONARY(ID, CODE, NAME) values (1, 'CONV', 'Конвертируемая валюта') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
@ -727,6 +727,8 @@ INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (1021, 'SECR', 'Инф
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (1022, 'SECR', 'Информация об инструментах Денежного рынка на режимах изменяется автоматически.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (1023, 'SECR', 'Информация об инструментах Денежного рынка на режимах блокируется автоматически.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (1024, 'SECR', 'Параметр для инструмента %s на дату уже существует.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (1025, 'SECR', 'Расчетный курс для валюты %s на дату уже существует.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (2000, 'UTIL', 'Общая ошибка модуля utility-service.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;

View file

@ -33,5 +33,50 @@ COMMENT ON COLUMN BANK_ACCOUNT.PERSONAL_ACCOUNT IS '
COMMENT ON COLUMN BANK_ACCOUNT.BUDGET_CLASSIFICATION_CODE IS 'ÊÁÊ';
COMMENT ON COLUMN BANK_ACCOUNT.OKTMO IS 'ÎÊÒÌÎ ïîëó÷àòåëÿ ñðåäñòâ';
DROP TABLE IF EXISTS RISK_PARAMETER;
CREATE TABLE RISK_PARAMETER
(
ID BIGINT,
VALUE numeric(72,18),
SETTLEMENT_TYPE VARCHAR(4),
CURRENCY_PAIR VARCHAR(12),
CURRENCY_PAIR_ID BIGINT,
CREATED_AT timestamp,
UPDATED_AT timestamp,
WORKFLOW_STATUS VARCHAR(4)
);
COMMENT ON TABLE RISK_PARAMETER IS 'Ðèñê-ïàðàìåòðû';
COMMENT ON COLUMN RISK_PARAMETER.ID IS 'Èäåíòèôèêàòîð çàïèñè';
COMMENT ON COLUMN RISK_PARAMETER.VALUE IS 'Ñòàâêà';
COMMENT ON COLUMN RISK_PARAMETER.SETTLEMENT_TYPE IS 'Êîä ðàñ÷åòà';
COMMENT ON COLUMN RISK_PARAMETER.CURRENCY_PAIR IS 'Êîä âàëþòíîé ïàðû';
COMMENT ON COLUMN RISK_PARAMETER.CURRENCY_PAIR_ID IS 'Èäåíòèôèêàòîð âàëþòíîé ïàðû';
COMMENT ON COLUMN RISK_PARAMETER.CREATED_AT IS 'Âðåìÿ ñîçäàíèÿ çàïèñè';
COMMENT ON COLUMN RISK_PARAMETER.UPDATED_AT IS 'Âðåìÿ èçìåíåíèÿ çàïèñè';
COMMENT ON COLUMN RISK_PARAMETER.WORKFLOW_STATUS IS 'Ñòàòóñ';
GRANT ALL PRIVILEGES ON TABLE RISK_PARAMETER TO clearing;
DROP TABLE IF EXISTS RATES;
CREATE TABLE RATES
(
ID BIGINT,
VALUE numeric(72, 18),
VALUE_DATE date,
CURRENCY VARCHAR(4),
CURRENCY_ID BIGINT,
CREATED_AT timestamp,
UPDATED_AT timestamp,
WORKFLOW_STATUS VARCHAR(4)
);
COMMENT ON TABLE RATES IS 'Ðàñ÷åòíûå êóðñû';
COMMENT ON COLUMN RATES.ID IS 'Èäåíòèôèêàòîð çàïèñè';
COMMENT ON COLUMN RATES.VALUE IS 'Ðàñ÷åòíûé êóðñ';
COMMENT ON COLUMN RATES.VALUE_DATE IS 'Äàòà, íà êîòîðóþ ðàñ÷åòíûé êóðñ';
COMMENT ON COLUMN RATES.CURRENCY IS 'Êîä âàëþòû';
COMMENT ON COLUMN RATES.CURRENCY_ID IS 'Èäåíòèôèêàòîð âàëþòû';
COMMENT ON COLUMN RATES.CREATED_AT IS 'Âðåìÿ ñîçäàíèÿ çàïèñè';
COMMENT ON COLUMN RATES.UPDATED_AT IS 'Âðåìÿ èçìåíåíèÿ çàïèñè';
COMMENT ON COLUMN RATES.WORKFLOW_STATUS IS 'Ñòàòóñ';
GRANT ALL PRIVILEGES ON TABLE RATES TO clearing;
INSERT INTO DB_VERSION(ID, VERSION) values (1, '3.15') ON CONFLICT (ID) DO UPDATE SET VERSION = EXCLUDED.VERSION

View file

@ -144,8 +144,8 @@ public abstract class SimpleObjectMapStore<T extends SpcexObjectBase> implements
List<Long> keys;
try {
keys = jdbcTemplate.query("select id from " + getTableName() + " where " + dateField + (canBeGreat ? " >= ?" : " = ?"),
(resultSet, i) -> resultSet.getLong("id"),
new Object[]{today});
(resultSet, i) -> resultSet.getLong("id"),
new Object[]{today});
} catch (Throwable e) {
log.error("At load keys from {} (by field {}): {}", getTableName(), dateField, ExceptionUtils.getStackTrace(e));
throw e;
@ -158,12 +158,16 @@ public abstract class SimpleObjectMapStore<T extends SpcexObjectBase> implements
}
protected void batchInsertUpdate(@NonNull String insertStatement, @NonNull List<Object[]> args) {
readMetaData();
batchInsertUpdate(insertStatement, args, getTableName(), getFields());
}
protected void batchInsertUpdate(@NonNull String insertStatement, @NonNull List<Object[]> args, String tableName, String[] fields) {
readMetaData(tableName);
try {
int[][] ret = jdbcTemplate.batchUpdate(insertStatement, args, BATCH_SIZE, (ps, params) -> {
for (int i = 0; i < params.length; i++) {
Object value = params[i];
value = normalizeValue(value, ps.getParameterMetaData(), columnMetaDataMap, i, insertStatement, params);
value = normalizeValue(value, ps.getParameterMetaData(), columnMetaDataMap, i, insertStatement, params, tableName, fields);
try {
StatementCreatorUtils.setParameterValue(ps, i + 1, SqlTypeValue.TYPE_UNKNOWN, value);
} catch (SQLException e) {
@ -172,23 +176,23 @@ public abstract class SimpleObjectMapStore<T extends SpcexObjectBase> implements
}
});
int batchSize = ret.length > 0 ? ret[0].length : ret.length;
log.debug("{} {} rows stored", getTableName(), batchSize);
log.debug("{} {} rows stored", tableName, batchSize);
} catch (Exception e) {
log.error("SQL error at batch UPDATE OR INSERT INTO {}\n{}", getTableName(), ExceptionUtils.getStackTrace(e));
log.error("SQL error at batch UPDATE OR INSERT INTO {}\n{}", tableName, ExceptionUtils.getStackTrace(e));
throw e;
}
}
Object normalizeValue(Object value, ParameterMetaData metaData, Map<String, ColumnMetaData> columnMetaDataMap, int i,
String insertStatement, Object[] params) throws SQLException {
if (getFields().length <= i || value == null)
String insertStatement, Object[] params, String tableName, String[] fields) throws SQLException {
if (value == null)
return null;
i++; // нумерация в ParameterMetaData начинается с 1
final int type = metaData.getParameterType(i);
final String fieldName = getFields()[i - 1].toLowerCase();
final String fieldName = fields[i - 1].toLowerCase();
if (columnMetaDataMap == null) {
log.trace("Column metadata was empty, can not verify {}.{}", getTableName(), fieldName);
log.trace("Column metadata was empty, can not verify {}.{}", tableName, fieldName);
}
if ((type == Types.VARCHAR || type == Types.CHAR) && value instanceof String stringValue) {
int length;
@ -310,9 +314,9 @@ public abstract class SimpleObjectMapStore<T extends SpcexObjectBase> implements
return TextUtil.format(INSERT_TEMPLATE, params);
}
private void readMetaData() {
if (columnMetaDataMap == null) synchronized (this) {
columnMetaDataMap = PostgresColumnTypeUtil.extractTableMetadata(jdbcTemplate, getTableName());
private void readMetaData(String tableName) {
synchronized (this) {
columnMetaDataMap = PostgresColumnTypeUtil.extractTableMetadata(jdbcTemplate, tableName);
}
}

View file

@ -79,6 +79,6 @@ public abstract class ASecurityHistoryMapStore<STH extends BusinessEvent<? exten
securityArgs.add(securityItemArgs);
}
batchInsertUpdate(insertStatement, tableArgs);
batchInsertUpdate(insertToSecurityStatement, securityArgs);
batchInsertUpdate(insertToSecurityStatement, securityArgs, "SECURITY_HISTORY", this.getFieldsSecurity());
}
}

View file

@ -100,7 +100,7 @@ public abstract class ASecurityMapStore <S extends Security> extends TemplateMap
securityArgs.add(argsSecurityItem);
}
batchInsertUpdate(insertStatement, childTableArgs);
batchInsertUpdate(insertToSecurityStatement, securityArgs);
batchInsertUpdate(insertToSecurityStatement, securityArgs, "SECURITY", this.getFieldsSecurity());
}

View file

@ -0,0 +1,66 @@
package ru.spcex.clearing.imdg.object;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.security.Rates;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.imdg.base.TemplateMapStore;
import ru.spcex.platform.utils.time.TimeUtil;
@Component
public class RatesMapStore extends TemplateMapStore<Rates> {
public RatesMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_Rates;
}
@Override
public String getTableName() {
return "RATES";
}
@Override
public String[] getFields() {
return new String[]{
"ID", "VALUE", "VALUE_DATE", "CURRENCY", "CURRENCY_ID", "CREATED_AT", "UPDATED_AT", "WORKFLOW_STATUS"
};
}
@Override
public Rates objectReader(ResultSet resultSet) throws SQLException {
Rates object = new Rates();
object.setId(resultSet.getObject("ID", Long.class));
object.setValue(resultSet.getObject("VALUE", BigDecimal.class));
object.setValueDate(getLocalDateFromSqlDate(resultSet,"VALUE_DATE"));
object.setCurrency(resultSet.getObject("CURRENCY", String.class));
object.setCurrencyId(resultSet.getObject("CURRENCY_ID", Long.class));
object.setCreated(getInstantFromTimestamp(resultSet, "CREATED_AT"));
object.setUpdated(getInstantFromTimestamp(resultSet, "UPDATED_AT"));
object.setWorkflowStatus(resultSet.getObject("WORKFLOW_STATUS", String.class));
return object;
}
@Override
public Object[] objectToField(Rates object) {
Object[] args = new Object[]{
object.getId(),
object.getValue(),
TimeUtil.toDateFromLocalDate(object.getValueDate()),
object.getCurrency(),
object.getCurrencyId(),
TimeUtil.toDateFromInstant(object.getCreated()),
TimeUtil.toDateFromInstant(object.getUpdated()),
object.getWorkflowStatus()
};
return args;
}
}

View file

@ -0,0 +1,66 @@
package ru.spcex.clearing.imdg.object;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.security.RiskParameter;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.imdg.base.TemplateMapStore;
import ru.spcex.platform.utils.time.TimeUtil;
@Component
public class RiskParameterMapStore extends TemplateMapStore<RiskParameter> {
public RiskParameterMapStore(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public String getMapName() {
return IMDGDistributedNames.Map_RiskParameter;
}
@Override
public String getTableName() {
return "RISK_PARAMETER";
}
@Override
public String[] getFields() {
return new String[]{
"ID", "VALUE", "SETTLEMENT_TYPE", "CURRENCY_PAIR", "CURRENCY_PAIR_ID", "CREATED_AT", "UPDATED_AT", "WORKFLOW_STATUS"
};
}
@Override
public RiskParameter objectReader(ResultSet resultSet) throws SQLException {
RiskParameter object = new RiskParameter();
object.setId(resultSet.getObject("ID", Long.class));
object.setValue(resultSet.getObject("VALUE", BigDecimal.class));
object.setSettlementType(resultSet.getObject("SETTLEMENT_TYPE", String.class));
object.setCurrencyPair(resultSet.getObject("CURRENCY_PAIR", String.class));
object.setCurrencyPairId(resultSet.getObject("CURRENCY_PAIR_ID", Long.class));
object.setCreated(getInstantFromTimestamp(resultSet, "CREATED_AT"));
object.setUpdated(getInstantFromTimestamp(resultSet, "UPDATED_AT"));
object.setWorkflowStatus(resultSet.getObject("WORKFLOW_STATUS", String.class));
return object;
}
@Override
public Object[] objectToField(RiskParameter object) {
Object[] args = new Object[]{
object.getId(),
object.getValue(),
object.getSettlementType(),
object.getCurrencyPair(),
object.getCurrencyPairId(),
TimeUtil.toDateFromInstant(object.getCreated()),
TimeUtil.toDateFromInstant(object.getUpdated()),
object.getWorkflowStatus()
};
return args;
}
}

View file

@ -0,0 +1,58 @@
package ru.spcex.clearing.securities.config.validation;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.security.RiskParameter;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesUpdateRequest;
import ru.spcex.clearing.securities.errors.SecuritiesError;
import ru.spcex.clearing.securities.validation.rule.RatesValidationRule;
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.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
@Configuration
public class RatesValidationConfig {
@Bean("ratesNewValidator")
public Function<RatesNewRequest, IValidator> ratesNewValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return ratesRequest -> {
ImdgValidationContext<RatesNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(ratesRequest);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_Rates);
return new ValidatorImpl<>(context,
FieldRequiredRule.instance("currencyPairUd", RatesNewRequest::getCurrencyId, SecuritiesError.RequiredFieldIsEmpty),
FieldRequiredRule.instance("value", RatesNewRequest::getValue, SecuritiesError.RequiredFieldIsEmpty),
FieldRequiredRule.instance("settlementType", RatesNewRequest::getValueDate, SecuritiesError.RequiredFieldIsEmpty),
RatesValidationRule.CHECK_ON_EXIST
);
};
}
@Bean("ratesUpdateValidator")
public Function<RatesUpdateRequest, IValidator> ratesUpdateValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return ratesUpdateRequest -> {
ImdgValidationContext<RatesUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(ratesUpdateRequest);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_Rates);
return new ValidatorImpl<>(context,
IdPresentRule.instance("id",
RatesUpdateRequest::getId,
IMDGDistributedNames.Map_Rates,
RiskParameter.class,
SecuritiesError.RequiredFieldIsEmpty,
SecuritiesError.RequiredFieldIsEmpty)
);
};
}
}

View file

@ -0,0 +1,58 @@
package ru.spcex.clearing.securities.config.validation;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.security.RiskParameter;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterUpdateRequest;
import ru.spcex.clearing.securities.errors.SecuritiesError;
import ru.spcex.clearing.securities.validation.rule.RiskParameterValidationRule;
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.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
@Configuration
public class RiskParameterValidationConfig {
@Bean("riskParameterNewValidator")
public Function<RiskParameterNewRequest, IValidator> riskParameterNewValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return riskParameter -> {
ImdgValidationContext<RiskParameterNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(riskParameter);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_RiskParameter);
return new ValidatorImpl<>(context,
FieldRequiredRule.instance("currencyPairUd", RiskParameterNewRequest::getCurrencyPairId, SecuritiesError.RequiredFieldIsEmpty),
FieldRequiredRule.instance("value", RiskParameterNewRequest::getValue, SecuritiesError.RequiredFieldIsEmpty),
FieldRequiredRule.instance("settlementType", RiskParameterNewRequest::getSettlementType, SecuritiesError.RequiredFieldIsEmpty),
RiskParameterValidationRule.CHECK_ON_EXIST
);
};
}
@Bean("riskParameterUpdateValidator")
public Function<RiskParameterUpdateRequest, IValidator> riskParameterUpdateValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return riskParameter -> {
ImdgValidationContext<RiskParameterUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(riskParameter);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_RiskParameter);
return new ValidatorImpl<>(context,
IdPresentRule.instance("id",
RiskParameterUpdateRequest::getId,
IMDGDistributedNames.Map_RiskParameter,
RiskParameter.class,
SecuritiesError.RequiredFieldIsEmpty,
SecuritiesError.RequiredFieldIsEmpty)
);
};
}
}

View file

@ -21,6 +21,8 @@ public enum SecuritiesError implements IErrorEnumId {
ListingOnMMSCreatedBySystem(1021L), // Информиция об инструментах Денежного рынка на режимах добавляется автоматически.
ListingOnMMSUpdatedBySystem(1022L), // Информиция об инструментах Денежного рынка на режимах изменяется автоматически.
ListingOnMMSDeletedBySystem(1023L), // Информиция об инструментах Денежного рынка на режимах блокируется автоматически.
RiskParameterAlreadyExist(1024L),
RatesAlreadyExist(1025L)
;
private final Long id;

View file

@ -0,0 +1,65 @@
package ru.spcex.clearing.securities.service.facade;
import java.time.Instant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.security.Rates;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesUpdateRequest;
import ru.spcex.platform.classes.base.interfaces.IClearingFacade;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
@Service
public class RatesFacade implements IClearingFacade {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ImdgId idGenerator;
private final ImdgProvider imdgProvider;
private final Imdg<Rates> ratesImdg;
public RatesFacade(ImdgProvider imdgProvider) {
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.imdgProvider = imdgProvider;
this.ratesImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Rates, Rates.class);
}
/**
* Создает clientCode, TCR и опционально TCRList, если указаны валюты.
*/
public void createRates(RatesNewRequest request) {
log.trace("Start process creating new rates");
Rates rates = new Rates();
rates.setCurrencyId(request.getCurrencyId());
rates.setValue(request.getValue());
rates.setValueDate(request.getValueDate());
rates.setWorkflowStatus(request.getStatus());
rates.setCreated(Instant.now());
ratesImdg.insert(rates);
log.debug("successfully processed, new rates id {}", rates.getId());
}
public void updateRates(RatesUpdateRequest request) {
log.trace("Start process update rates");
Rates ratesForUpdate = ratesImdg.getSingleObjectByID(request.getId());
ratesForUpdate.setValue(request.getValue());
ratesForUpdate.setWorkflowStatus(request.getStatus());
ratesImdg.update(ratesForUpdate);
log.debug("successfully processed, updated rates id {}", ratesForUpdate.getId());
}
@Override
public void lock() {
}
@Override
public void unlock() {
}
}

View file

@ -0,0 +1,65 @@
package ru.spcex.clearing.securities.service.facade;
import java.time.Instant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.security.RiskParameter;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterUpdateRequest;
import ru.spcex.platform.classes.base.interfaces.IClearingFacade;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
@Service
public class RiskParameterFacade implements IClearingFacade {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ImdgId idGenerator;
private final ImdgProvider imdgProvider;
private final Imdg<RiskParameter> riskParameterImdg;
public RiskParameterFacade(ImdgProvider imdgProvider) {
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.imdgProvider = imdgProvider;
this.riskParameterImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RiskParameter, RiskParameter.class);
}
/**
* Создает clientCode, TCR и опционально TCRList, если указаны валюты.
*/
public void createRiskParameter(RiskParameterNewRequest request) {
log.trace("Start process creating new risk_parameter");
RiskParameter riskParameter = new RiskParameter();
riskParameter.setCurrencyPairId(request.getCurrencyPairId());
riskParameter.setSettlementType(request.getSettlementType());
riskParameter.setValue(request.getValue());
riskParameter.setWorkflowStatus(request.getStatus());
riskParameter.setCreated(Instant.now());
riskParameterImdg.insert(riskParameter);
log.debug("successfully processed, new risk_parameter id {}", riskParameter.getId());
}
public void updateRiskParameter(RiskParameterUpdateRequest request) {
log.trace("Start process update risk_parameter");
RiskParameter riskParameterForUpdate = riskParameterImdg.getSingleObjectByID(request.getId());
riskParameterForUpdate.setValue(request.getValue());
riskParameterForUpdate.setWorkflowStatus(request.getStatus());
riskParameterImdg.update(riskParameterForUpdate);
log.debug("successfully processed, updated risk_parameter id {}", riskParameterForUpdate.getId());
}
@Override
public void lock() {
}
@Override
public void unlock() {
}
}

View file

@ -0,0 +1,100 @@
package ru.spcex.clearing.securities.service.listeners;
import java.util.Optional;
import java.util.function.Function;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesUpdateRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.securities.service.facade.RatesFacade;
import ru.spcex.clearing.util.security.UserRoleVerification;
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.validation.IValidator;
@Service
public class RatesMessageListener extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ImdgProvider imdgProvider;
private final RatesFacade ratesFacade;
private final Function<RatesNewRequest, IValidator> ratesNewValidator;
private final Function<RatesUpdateRequest, IValidator> ratesUpdateValidator;
private final UserRoleVerification userRoleVerification;
private final IMessageResolver messageResolver;
public RatesMessageListener(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider,
RatesFacade ratesFacade,
Function<RatesNewRequest, IValidator> ratesNewValidator,
Function<RatesUpdateRequest, IValidator> ratesUpdateValidator,
UserRoleVerification userRoleVerification,
IMessageResolver messageResolver) {
super(kafkaQueue, kafkaProducer);
this.imdgProvider = imdgProvider;
this.ratesFacade = ratesFacade;
this.ratesNewValidator = ratesNewValidator;
this.ratesUpdateValidator = ratesUpdateValidator;
this.userRoleVerification = userRoleVerification;
this.messageResolver = messageResolver;
}
@Override
public void afterPropertiesSet() {
imdgProvider.waitAvailable();
//from backend-api requests
callback(RatesNewRequest.class)
.setFunction(this::ratesNew)
.forDestination(Consts.DESTINATION_RATES_NEW, callbacks::put);
callback(RatesUpdateRequest.class)
.setFunction(this::ratesUpdate)
.forDestination(Consts.DESTINATION_RATES_UPDATE, callbacks::put);
init();
}
private RequestInfoUpdate ratesNew(BaseRequest<RatesNewRequest> ratesNewRequest) {
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(ratesNewRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
RatesNewRequest request = ratesNewRequest.getRequestPayload();
IValidator validator = ratesNewValidator.apply(request);
Optional<EnumMessage> error = validator.tillFirstError();
if (error.isPresent()) {
String errMsg = messageResolver.resolve(error.get());
return new RequestInfoUpdate()
.setId(ratesNewRequest.getId())
.setStatus(ru.spcex.clearing.platform.messaging.service.Status.Error)
.setMessage(errMsg);
}
ratesFacade.createRates(request);
return null;
}
private RequestInfoUpdate ratesUpdate(BaseRequest<RatesUpdateRequest> ratesUpdateRequest) {
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(ratesUpdateRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
RatesUpdateRequest request = ratesUpdateRequest.getRequestPayload();
IValidator validator = ratesUpdateValidator.apply(request);
Optional<EnumMessage> error = validator.tillFirstError();
if (error.isPresent()) {
String errMsg = messageResolver.resolve(error.get());
return new RequestInfoUpdate()
.setId(ratesUpdateRequest.getId())
.setStatus(ru.spcex.clearing.platform.messaging.service.Status.Error)
.setMessage(errMsg);
}
ratesFacade.updateRates(request);
return null;
}
}

View file

@ -0,0 +1,100 @@
package ru.spcex.clearing.securities.service.listeners;
import java.util.Optional;
import java.util.function.Function;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterUpdateRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.securities.service.facade.RiskParameterFacade;
import ru.spcex.clearing.util.security.UserRoleVerification;
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.validation.IValidator;
@Service
public class RiskParameterMessageListener extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ImdgProvider imdgProvider;
private final RiskParameterFacade riskParameterFacade;
private final Function<RiskParameterNewRequest, IValidator> riskParameterNewValidator;
private final Function<RiskParameterUpdateRequest, IValidator> riskParameterUpdateValidator;
private final UserRoleVerification userRoleVerification;
private final IMessageResolver messageResolver;
public RiskParameterMessageListener(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider,
RiskParameterFacade riskParameterFacade,
Function<RiskParameterNewRequest, IValidator> riskParameterNewValidator,
Function<RiskParameterUpdateRequest, IValidator> riskParameterUpdateValidator,
UserRoleVerification userRoleVerification,
IMessageResolver messageResolver) {
super(kafkaQueue, kafkaProducer);
this.imdgProvider = imdgProvider;
this.riskParameterFacade = riskParameterFacade;
this.riskParameterNewValidator = riskParameterNewValidator;
this.riskParameterUpdateValidator = riskParameterUpdateValidator;
this.userRoleVerification = userRoleVerification;
this.messageResolver = messageResolver;
}
@Override
public void afterPropertiesSet() {
imdgProvider.waitAvailable();
//from backend-api requests
callback(RiskParameterNewRequest.class)
.setFunction(this::riskParameterNew)
.forDestination(Consts.DESTINATION_RISK_PARAMETER_NEW, callbacks::put);
callback(RiskParameterUpdateRequest.class)
.setFunction(this::riskParameterUpdate)
.forDestination(Consts.DESTINATION_RISK_PARAMETER_UPDATE, callbacks::put);
init();
}
private RequestInfoUpdate riskParameterNew(BaseRequest<RiskParameterNewRequest> riskParameterRequest) {
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(riskParameterRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
RiskParameterNewRequest request = riskParameterRequest.getRequestPayload();
IValidator validator = riskParameterNewValidator.apply(request);
Optional<EnumMessage> error = validator.tillFirstError();
if (error.isPresent()) {
String errMsg = messageResolver.resolve(error.get());
return new RequestInfoUpdate()
.setId(riskParameterRequest.getId())
.setStatus(ru.spcex.clearing.platform.messaging.service.Status.Error)
.setMessage(errMsg);
}
riskParameterFacade.createRiskParameter(request);
return null;
}
private RequestInfoUpdate riskParameterUpdate(BaseRequest<RiskParameterUpdateRequest> riskParameterUpdateRequest) {
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(riskParameterUpdateRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
RiskParameterUpdateRequest request = riskParameterUpdateRequest.getRequestPayload();
IValidator validator = riskParameterUpdateValidator.apply(request);
Optional<EnumMessage> error = validator.tillFirstError();
if (error.isPresent()) {
String errMsg = messageResolver.resolve(error.get());
return new RequestInfoUpdate()
.setId(riskParameterUpdateRequest.getId())
.setStatus(ru.spcex.clearing.platform.messaging.service.Status.Error)
.setMessage(errMsg);
}
riskParameterFacade.updateRiskParameter(request);
return null;
}
}

View file

@ -0,0 +1,41 @@
package ru.spcex.clearing.securities.validation.rule;
import java.util.Optional;
import ru.clearing.classes.statics.data.security.Rates;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesNewRequest;
import ru.spcex.clearing.securities.errors.SecuritiesError;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.imdg.api.Imdg;
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;
public enum RatesValidationRule implements IValidationRule<ImdgValidationContext<RatesNewRequest>> {
CHECK_ON_EXIST() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<RatesNewRequest> context) {
RatesNewRequest action = context.getValidatedObject();
Imdg<Rates> imdgDictionary = context.obtainMap(IMDGDistributedNames.Map_Rates, Rates.class);
ImdgPredicateBuilder predicateBuilder = imdgDictionary.predicateBuilder();
Rates rates = imdgDictionary.getFirstObjectByPredicate(
predicateBuilder.and(
predicateBuilder.equals("currencyPairId", action.getCurrencyId()),
predicateBuilder.equals("valueDate", action.getValueDate()),
predicateBuilder.equals("workflowStatus", Status.Active.getKey())
)
);
if (rates != null) {
return of(SecuritiesError.RatesAlreadyExist, action.getCurrencyId());
}
return empty();
}
};
@Override
public String ruleName() {
return "MmsNewValidationRule." + name();
}
}

View file

@ -0,0 +1,42 @@
package ru.spcex.clearing.securities.validation.rule;
import java.util.Optional;
import ru.clearing.classes.statics.data.security.RiskParameter;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterNewRequest;
import ru.spcex.clearing.securities.errors.SecuritiesError;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.imdg.api.Imdg;
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;
public enum RiskParameterValidationRule implements IValidationRule<ImdgValidationContext<RiskParameterNewRequest>> {
CHECK_ON_EXIST() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<RiskParameterNewRequest> context) {
RiskParameterNewRequest action = context.getValidatedObject();
Imdg<RiskParameter> imdgDictionary = context.obtainMap(IMDGDistributedNames.Map_RiskParameter, RiskParameter.class);
ImdgPredicateBuilder predicateBuilder = imdgDictionary.predicateBuilder();
RiskParameter riskParameter = imdgDictionary.getFirstObjectByPredicate(
predicateBuilder.and(
predicateBuilder.equals("currencyPairId", action.getCurrencyPairId()),
predicateBuilder.equals("settlementType", action.getSettlementType()),
predicateBuilder.equals("workflowStatus", Status.Active.getKey())
)
);
if (riskParameter != null) {
return of(SecuritiesError.RiskParameterAlreadyExist, action.getCurrencyPairId());
}
return empty();
}
};
@Override
public String ruleName() {
return "RiskParameterValidationRule." + name();
}
}

View file

@ -21,6 +21,7 @@ public enum Task implements IEnumKey {
createReport_GREP("GREP"), // Создание отчёта (report-service) RPRT нескольких видов, этот GREP
createDealsReport_GRET("GRET"), // Формирование отчетности по сделкам
createDealsReport_GREF("GREF"), // Формирование финальной отчетности по сделкам
createReport_GREC("GREC"), // Формирование отчетности в ЛЦК
unloadingSession_LIMM("LIMM"),//Выгрузка в торговую систему остатков по деньгам
unloadingSession_LIMS("LIMS"),//Выгрузка в торговую систему остатков по бумагам
unloadingSession_LIMC("LIMC"),//Выгрузка в торговую систему остатков по валютам

View file

@ -216,6 +216,8 @@ public final class IMDGDistributedNames {
public static final String Map_PairSdf = "Map_PairSdf";
public static final String Map_GatewayResult = "Map_GatewayResult";
public static final String Map_BlacklistMarket = "Map_BlacklistMarket";
public static final String Map_RiskParameter = "Map_RiskParameter";
public static final String Map_Rates = "Map_Rates";
public static final String Map_DbVersion = "Map_DbVersion";
//-------------------history and search tables

View file

@ -120,6 +120,11 @@ public interface Consts {
String NOTIFICATION_UPDATE = "notification-update";
String PAIR_SDF = "pair-sdf";
String DESTINATION_RISK_PARAMETER_NEW = "risk-parameter-new";
String DESTINATION_RISK_PARAMETER_UPDATE = "risk-parameter-update";
String DESTINATION_RATES_NEW = "rates-new";
String DESTINATION_RATES_UPDATE = "rates-update";
String DESTINATION_SDF08_NEW = "s-df-08-new";
String DESTINATION_SDF02_NEW = "s-df-02-new";

View file

@ -0,0 +1,49 @@
package ru.spcex.clearing.platform.messaging.domain.cud.security;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
import java.time.LocalDate;
public class RatesNewRequest {
@JsonProperty
private BigDecimal value;
@JsonProperty
private LocalDate valueDate;
@JsonProperty
private Long currencyId;
@JsonProperty
private String status;
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public LocalDate getValueDate() {
return valueDate;
}
public void setValueDate(LocalDate valueDate) {
this.valueDate = valueDate;
}
public Long getCurrencyId() {
return currencyId;
}
public void setCurrencyId(Long currencyId) {
this.currencyId = currencyId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}

View file

@ -0,0 +1,38 @@
package ru.spcex.clearing.platform.messaging.domain.cud.security;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
public class RatesUpdateRequest {
@JsonProperty
private Long id;
@JsonProperty
private BigDecimal value;
@JsonProperty
private String status;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}

View file

@ -0,0 +1,48 @@
package ru.spcex.clearing.platform.messaging.domain.cud.security;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
public class RiskParameterNewRequest {
@JsonProperty
private BigDecimal value;
@JsonProperty
private String settlementType;
@JsonProperty
private Long currencyPairId;
@JsonProperty
private String status;
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public String getSettlementType() {
return settlementType;
}
public void setSettlementType(String settlementType) {
this.settlementType = settlementType;
}
public Long getCurrencyPairId() {
return currencyPairId;
}
public void setCurrencyPairId(Long currencyPairId) {
this.currencyPairId = currencyPairId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}

View file

@ -0,0 +1,38 @@
package ru.spcex.clearing.platform.messaging.domain.cud.security;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
public class RiskParameterUpdateRequest {
@JsonProperty
private Long id;
@JsonProperty
private BigDecimal value;
@JsonProperty
private String status;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}