This commit is contained in:
parent
2f27d41972
commit
5f2cc2577d
12 changed files with 418 additions and 6 deletions
|
|
@ -1,22 +1,31 @@
|
||||||
package ru.spcex.clearing.backendapi.controller.queue.misc;
|
package ru.spcex.clearing.backendapi.controller.queue.misc;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import io.swagger.annotations.ApiParam;
|
||||||
import io.swagger.annotations.ApiResponse;
|
import io.swagger.annotations.ApiResponse;
|
||||||
import io.swagger.annotations.ApiResponses;
|
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.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Controller;
|
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.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import ru.clearing.classes.statics.data.misc.SCrossRate;
|
import ru.clearing.classes.statics.data.misc.SCrossRate;
|
||||||
import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController;
|
import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController;
|
||||||
|
import ru.spcex.clearing.backendapi.controller.request.cud.securities.SCrossRateNewAction;
|
||||||
|
import ru.spcex.clearing.backendapi.controller.request.cud.securities.SCrossRateUpdateAction;
|
||||||
|
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.controller.response.entity.CommonGetAllResponse;
|
||||||
import ru.spcex.clearing.backendapi.service.IOperator;
|
import ru.spcex.clearing.backendapi.service.IOperator;
|
||||||
import ru.spcex.clearing.backendapi.service.IStateLoader;
|
import ru.spcex.clearing.backendapi.service.IStateLoader;
|
||||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/cross-rate")
|
@RequestMapping("/cross-rate")
|
||||||
|
|
@ -40,4 +49,27 @@ public class SCrossRateController extends AbstractQueueController {
|
||||||
response.fromEntity(all);
|
response.fromEntity(all);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "create sCrossRates.")
|
||||||
|
@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 SCrossRateNewAction ratesNewAction) throws ExecutionException, InterruptedException {
|
||||||
|
return processRequest(Consts.DESTINATION_S_CROSS_RATES_NEW, ratesNewAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "update sCrossRates.")
|
||||||
|
@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 SCrossRateUpdateAction ratesUpdateAction) throws ExecutionException, InterruptedException {
|
||||||
|
ratesUpdateAction.setId(id);
|
||||||
|
return processRequest(Consts.DESTINATION_S_CROSS_RATES_UPDATE, ratesUpdateAction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package ru.spcex.clearing.backendapi.controller.request.cud.securities;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
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.securitites.SCrossRateNewRequest;
|
||||||
|
|
||||||
|
public class SCrossRateNewAction implements IAction<SCrossRateNewRequest> {
|
||||||
|
@JsonProperty
|
||||||
|
private LocalDate date;
|
||||||
|
@JsonProperty
|
||||||
|
private String currency;
|
||||||
|
@JsonProperty
|
||||||
|
private BigDecimal unitRate;
|
||||||
|
@JsonProperty
|
||||||
|
private BigDecimal faceValue;
|
||||||
|
@JsonProperty
|
||||||
|
private BigDecimal rate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SCrossRateNewRequest toRequest() {
|
||||||
|
SCrossRateNewRequest sCrossRateNewRequest = new SCrossRateNewRequest();
|
||||||
|
sCrossRateNewRequest.setDate(date);
|
||||||
|
sCrossRateNewRequest.setCurrency(currency);
|
||||||
|
sCrossRateNewRequest.setUnitRate(unitRate);
|
||||||
|
sCrossRateNewRequest.setFaceValue(faceValue);
|
||||||
|
sCrossRateNewRequest.setRate(rate);
|
||||||
|
return sCrossRateNewRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionType getActionType() {
|
||||||
|
return ActionType.NEW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
package ru.spcex.clearing.backendapi.controller.request.cud.securities;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
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.securitites.SCrossRateUpdateRequest;
|
||||||
|
|
||||||
|
public class SCrossRateUpdateAction implements IAction<SCrossRateUpdateRequest> {
|
||||||
|
@JsonProperty
|
||||||
|
private Long id;
|
||||||
|
@JsonProperty
|
||||||
|
private LocalDate date;
|
||||||
|
@JsonProperty
|
||||||
|
private String currency;
|
||||||
|
@JsonProperty
|
||||||
|
private BigDecimal unitRate;
|
||||||
|
@JsonProperty
|
||||||
|
private BigDecimal faceValue;
|
||||||
|
@JsonProperty
|
||||||
|
private BigDecimal rate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SCrossRateUpdateRequest toRequest() {
|
||||||
|
SCrossRateUpdateRequest sCrossRateUpdateRequest = new SCrossRateUpdateRequest();
|
||||||
|
sCrossRateUpdateRequest.setId(id);
|
||||||
|
sCrossRateUpdateRequest.setDate(date);
|
||||||
|
sCrossRateUpdateRequest.setCurrency(currency);
|
||||||
|
sCrossRateUpdateRequest.setUnitRate(unitRate);
|
||||||
|
sCrossRateUpdateRequest.setFaceValue(faceValue);
|
||||||
|
sCrossRateUpdateRequest.setRate(rate);
|
||||||
|
return sCrossRateUpdateRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionType getActionType() {
|
||||||
|
return ActionType.UPDATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(LocalDate date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrency() {
|
||||||
|
return currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrency(String currency) {
|
||||||
|
this.currency = currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getUnitRate() {
|
||||||
|
return unitRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnitRate(BigDecimal unitRate) {
|
||||||
|
this.unitRate = unitRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getFaceValue() {
|
||||||
|
return faceValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFaceValue(BigDecimal faceValue) {
|
||||||
|
this.faceValue = faceValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getRate() {
|
||||||
|
return rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRate(BigDecimal rate) {
|
||||||
|
this.rate = rate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
"version": "3.23.295.153",
|
"version": "3.23.295.154",
|
||||||
|
|
||||||
"enums": {
|
"enums": {
|
||||||
|
|
||||||
|
|
@ -10901,7 +10901,69 @@
|
||||||
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true,"ignore": true
|
"field": "updated","type": 4,"webtype": "5","dbname": "Дата-время изменения записи","name": "Время изменения записи","shortname": "Изменено","searchable": true,"sortable": true,"ignore": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
,"actions":[
|
||||||
|
{"method":"post",
|
||||||
|
|
||||||
|
"name": "Добавление центрального курса",
|
||||||
|
|
||||||
|
"class": "ru.spcex.clearing.platform.messaging.domain.cud.securitites.SCrossRateNewRequest",
|
||||||
|
|
||||||
|
"fields": [
|
||||||
|
{"code": "date",
|
||||||
|
"name": "Дата торгов","shortname": "Дата","type": 6,"required": true
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{"code": "currency",
|
||||||
|
"name": "Наименование валюты","shortname": "Валюта","type": 2,"length": 50,"link": "currencyCode","linkCode": "code","required": true
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{"code": "faceValue",
|
||||||
|
"name": "Единица базовой валюты","shortname": "Единица базовой валюты","type": 10
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{"code": "rate",
|
||||||
|
"type": 10,"name": "Курс валюты с учетом размера лота","shortname": "Курс валюты"
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{"code": "unitRate",
|
||||||
|
"type": 10,"name": "Курс за единицу иностранной валюты","shortname": "Курс за единицу валюты","required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{"method":"put",
|
||||||
|
|
||||||
|
"name": "Изменение центрального курса",
|
||||||
|
|
||||||
|
"class": "ru.spcex.clearing.platform.messaging.domain.cud.securitites.SCrossRateUpdateRequest",
|
||||||
|
|
||||||
|
"fields": [
|
||||||
|
{"code": "id",
|
||||||
|
"type": 1,"name": "Идентификатор записи","shortname": "ID","link": "sCrossRate","linkCode": "id","required": true
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{"code": "date",
|
||||||
|
"name": "Дата торгов","shortname": "Дата","type": 6,"required": true
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{"code": "currency",
|
||||||
|
"name": "Наименование валюты","shortname": "Валюта","type": 2,"length": 50,"link": "currencyCode","linkCode": "code","required": true
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{"code": "faceValue",
|
||||||
|
"name": "Единица базовой валюты","shortname": "Единица базовой валюты","type": 10
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{"code": "rate",
|
||||||
|
"type": 10,"name": "Курс валюты с учетом размера лота","shortname": "Курс валюты"
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{"code": "unitRate",
|
||||||
|
"type": 10,"name": "Курс за единицу базовой валюты","shortname": "Курс за единицу валюты","required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
"blacklistMarket": {
|
"blacklistMarket": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--?xml-stylesheet type="text/xsl" href="\..\corp-reports\src\data\meta\meta.server.xslt"?-->
|
<!--?xml-stylesheet type="text/xsl" href="\..\corp-reports\src\data\meta\meta.server.xslt"?-->
|
||||||
<meta version="3.23.295.153">
|
<meta version="3.23.295.154">
|
||||||
<!-- _xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _xsi:noNamespaceSchemaLocation="file:///E:/d/projects/meta/from/meta.xsd" -->
|
<!-- _xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _xsi:noNamespaceSchemaLocation="file:///E:/d/projects/meta/from/meta.xsd" -->
|
||||||
<!--Здесь словари-->
|
<!--Здесь словари-->
|
||||||
<enums>
|
<enums>
|
||||||
|
|
@ -2525,6 +2525,23 @@
|
||||||
<generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true" visible="true"/>
|
<generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true" visible="true"/>
|
||||||
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="true"/>
|
<createdAt field="created" type="4" webtype="5" dbname="Дата-время создания записи" name="Время создания записи" shortname="Создано" searchable="true" sortable="true" ignore="true"/>
|
||||||
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
|
<updatedAt field="updated" type="4" webtype="5" dbname="Дата-время изменения записи" name="Время изменения записи" shortname="Изменено" searchable="true" sortable="true" ignore="true"/>
|
||||||
|
<actions>
|
||||||
|
<post name="Добавление центрального курса" class="ru.spcex.clearing.platform.messaging.domain.cud.securitites.SCrossRateNewRequest">
|
||||||
|
<date name="Дата торгов" shortname="Дата" type="6" required="true"/>
|
||||||
|
<currency name="Наименование валюты" shortname="Валюта" type="2" length="50" link="currencyCode" linkCode="code" required="true"/>
|
||||||
|
<faceValue name="Единица базовой валюты" shortname="Единица базовой валюты" type="10"/>
|
||||||
|
<rate type="10" name="Курс валюты с учетом размера лота" shortname="Курс валюты"/>
|
||||||
|
<unitRate type="10" name="Курс за единицу иностранной валюты" shortname="Курс за единицу валюты" required="true"/>
|
||||||
|
</post>
|
||||||
|
<put name="Изменение центрального курса" class="ru.spcex.clearing.platform.messaging.domain.cud.securitites.SCrossRateUpdateRequest">
|
||||||
|
<id type="1" name="Идентификатор записи" shortname="ID" link="sCrossRate" linkCode="id" required="true"/>
|
||||||
|
<date name="Дата торгов" shortname="Дата" type="6" required="true"/>
|
||||||
|
<currency name="Наименование валюты" shortname="Валюта" type="2" length="50" link="currencyCode" linkCode="code" required="true"/>
|
||||||
|
<faceValue name="Единица базовой валюты" shortname="Единица базовой валюты" type="10"/>
|
||||||
|
<rate type="10" name="Курс валюты с учетом размера лота" shortname="Курс валюты"/>
|
||||||
|
<unitRate type="10" name="Курс за единицу базовой валюты" shortname="Курс за единицу валюты" required="true"/>
|
||||||
|
</put>
|
||||||
|
</actions>
|
||||||
</sCrossRate>
|
</sCrossRate>
|
||||||
<blacklistMarket name="blacklist площадок" destination="blacklist-market" class="ru.clearing.classes.statics.data.misc.BlacklistMarket" table="blacklist_market">
|
<blacklistMarket name="blacklist площадок" destination="blacklist-market" class="ru.clearing.classes.statics.data.misc.BlacklistMarket" table="blacklist_market">
|
||||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" visible="true"/>
|
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true" visible="true"/>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import ru.clearing.classes.statics.data.misc.SCrossRate;
|
||||||
import ru.clearing.classes.statics.data.security.Rates;
|
import ru.clearing.classes.statics.data.security.Rates;
|
||||||
import ru.clearing.classes.statics.data.security.RiskParameter;
|
import ru.clearing.classes.statics.data.security.RiskParameter;
|
||||||
import ru.clearing.platform.dictionary.CountryCodeDictionary;
|
import ru.clearing.platform.dictionary.CountryCodeDictionary;
|
||||||
|
|
@ -33,6 +34,7 @@ public class ValidationConfig {
|
||||||
addImdg.accept(IMDGDistributedNames.Map_FixedIncomeCashFlow, CountryCodeDictionary.class);
|
addImdg.accept(IMDGDistributedNames.Map_FixedIncomeCashFlow, CountryCodeDictionary.class);
|
||||||
addImdg.accept(IMDGDistributedNames.Map_Rates, Rates.class);
|
addImdg.accept(IMDGDistributedNames.Map_Rates, Rates.class);
|
||||||
addImdg.accept(IMDGDistributedNames.Map_RiskParameter, RiskParameter.class);
|
addImdg.accept(IMDGDistributedNames.Map_RiskParameter, RiskParameter.class);
|
||||||
|
addImdg.accept(IMDGDistributedNames.Map_SCrossRate, SCrossRate.class);
|
||||||
|
|
||||||
return imdg;
|
return imdg;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
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.misc.SCrossRate;
|
||||||
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.SCrossRateNewRequest;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.SCrossRateUpdateRequest;
|
||||||
|
import ru.spcex.clearing.securities.errors.SecuritiesError;
|
||||||
|
import ru.spcex.clearing.securities.validation.rule.SCrossRatesValidationRule;
|
||||||
|
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 SCrossRatesValidationConfig {
|
||||||
|
|
||||||
|
@Bean("sCrossRatesNewValidator")
|
||||||
|
public Function<SCrossRateNewRequest, IValidator> sCrossRatesNewValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
|
||||||
|
return ratesRequest -> {
|
||||||
|
ImdgValidationContext<SCrossRateNewRequest> context = new ImdgValidationContext<>();
|
||||||
|
context.setValidatedObject(ratesRequest);
|
||||||
|
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
|
||||||
|
addImdg.accept(IMDGDistributedNames.Map_SCrossRate);
|
||||||
|
return new ValidatorImpl<>(context,
|
||||||
|
FieldRequiredRule.instance("currency", SCrossRateNewRequest::getCurrency, SecuritiesError.RequiredFieldIsEmpty),
|
||||||
|
FieldRequiredRule.instance("date", SCrossRateNewRequest::getDate, SecuritiesError.RequiredFieldIsEmpty),
|
||||||
|
SCrossRatesValidationRule.CHECK_ON_EXIST
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean("sCrossRatesUpdateValidator")
|
||||||
|
public Function<SCrossRateUpdateRequest, IValidator> sCrossRatesUpdateValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
|
||||||
|
return ratesUpdateRequest -> {
|
||||||
|
ImdgValidationContext<SCrossRateUpdateRequest> context = new ImdgValidationContext<>();
|
||||||
|
context.setValidatedObject(ratesUpdateRequest);
|
||||||
|
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
|
||||||
|
addImdg.accept(IMDGDistributedNames.Map_SCrossRate);
|
||||||
|
return new ValidatorImpl<>(context,
|
||||||
|
IdPresentRule.instance("id",
|
||||||
|
SCrossRateUpdateRequest::getId,
|
||||||
|
IMDGDistributedNames.Map_SCrossRate,
|
||||||
|
SCrossRate.class,
|
||||||
|
SecuritiesError.RequiredFieldIsEmpty,
|
||||||
|
SecuritiesError.RequiredFieldIsEmpty)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -38,6 +38,9 @@ public class SCrossRateFacade {
|
||||||
|
|
||||||
public void update(SCrossRateUpdateRequest req) {
|
public void update(SCrossRateUpdateRequest req) {
|
||||||
SCrossRate sCrossRate = sCrossRateImdg.getSingleObjectByID(req.getId());
|
SCrossRate sCrossRate = sCrossRateImdg.getSingleObjectByID(req.getId());
|
||||||
|
if (req.getDate() != null) {
|
||||||
|
sCrossRate.setDate(req.getDate());
|
||||||
|
}
|
||||||
sCrossRate.setUnitRate(req.getUnitRate());
|
sCrossRate.setUnitRate(req.getUnitRate());
|
||||||
sCrossRate.setFaceValue(req.getFaceValue());
|
sCrossRate.setFaceValue(req.getFaceValue());
|
||||||
sCrossRate.setRate(req.getRate());
|
sCrossRate.setRate(req.getRate());
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package ru.spcex.clearing.securities.service.listeners;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
import org.apache.kafka.clients.consumer.Consumer;
|
import org.apache.kafka.clients.consumer.Consumer;
|
||||||
import org.apache.kafka.clients.producer.Producer;
|
import org.apache.kafka.clients.producer.Producer;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
@ -18,18 +20,23 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.SCrossRateUpd
|
||||||
import ru.spcex.clearing.platform.messaging.domain.gateway.rate.CurrencyRateGatewayElem;
|
import ru.spcex.clearing.platform.messaging.domain.gateway.rate.CurrencyRateGatewayElem;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.gateway.rate.SCrossRateGatewayRequest;
|
import ru.spcex.clearing.platform.messaging.domain.gateway.rate.SCrossRateGatewayRequest;
|
||||||
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||||
|
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
|
||||||
import ru.spcex.clearing.securities.service.facade.SCrossRateFacade;
|
import ru.spcex.clearing.securities.service.facade.SCrossRateFacade;
|
||||||
import ru.spcex.clearing.util.security.UserRoleVerification;
|
import ru.spcex.clearing.util.security.UserRoleVerification;
|
||||||
import ru.spcex.platform.imdg.api.Imdg;
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||||
|
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||||
|
import ru.spcex.platform.utils.validation.IValidator;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class SCrossRatesMessageListener extends QueueConsumer implements InitializingBean {
|
public class SCrossRatesMessageListener extends QueueConsumer implements InitializingBean {
|
||||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
private final ImdgProvider imdgProvider;
|
private final ImdgProvider imdgProvider;
|
||||||
private final UserRoleVerification userRoleVerification;
|
private final UserRoleVerification userRoleVerification;
|
||||||
|
private final Function<SCrossRateNewRequest, IValidator> sCrossRatesNewValidator;
|
||||||
|
private final Function<SCrossRateUpdateRequest, IValidator> sCrossRatesUpdateValidator;
|
||||||
private final IMessageResolver messageResolver;
|
private final IMessageResolver messageResolver;
|
||||||
private final Imdg<SCrossRate> sCrossRateImdg;
|
private final Imdg<SCrossRate> sCrossRateImdg;
|
||||||
private final Imdg<CurrencyCodeDictionary> currencyCodeDictionaryImdg;
|
private final Imdg<CurrencyCodeDictionary> currencyCodeDictionaryImdg;
|
||||||
|
|
@ -38,6 +45,8 @@ public class SCrossRatesMessageListener extends QueueConsumer implements Initial
|
||||||
public SCrossRatesMessageListener(Consumer<String, Object> kafkaQueue,
|
public SCrossRatesMessageListener(Consumer<String, Object> kafkaQueue,
|
||||||
Producer<String, Object> kafkaProducer,
|
Producer<String, Object> kafkaProducer,
|
||||||
ImdgProvider imdgProvider,
|
ImdgProvider imdgProvider,
|
||||||
|
Function<SCrossRateNewRequest, IValidator> sCrossRatesNewValidator,
|
||||||
|
Function<SCrossRateUpdateRequest, IValidator> sCrossRatesUpdateValidator,
|
||||||
UserRoleVerification userRoleVerification,
|
UserRoleVerification userRoleVerification,
|
||||||
IMessageResolver messageResolver,
|
IMessageResolver messageResolver,
|
||||||
SCrossRateFacade sCrossRateFacade) {
|
SCrossRateFacade sCrossRateFacade) {
|
||||||
|
|
@ -45,6 +54,8 @@ public class SCrossRatesMessageListener extends QueueConsumer implements Initial
|
||||||
this.imdgProvider = imdgProvider;
|
this.imdgProvider = imdgProvider;
|
||||||
this.userRoleVerification = userRoleVerification;
|
this.userRoleVerification = userRoleVerification;
|
||||||
this.messageResolver = messageResolver;
|
this.messageResolver = messageResolver;
|
||||||
|
this.sCrossRatesNewValidator = sCrossRatesNewValidator;
|
||||||
|
this.sCrossRatesUpdateValidator = sCrossRatesUpdateValidator;
|
||||||
this.sCrossRateImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SCrossRate, SCrossRate.class);
|
this.sCrossRateImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SCrossRate, SCrossRate.class);
|
||||||
this.sCrossRateFacade = sCrossRateFacade;
|
this.sCrossRateFacade = sCrossRateFacade;
|
||||||
this.currencyCodeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CurrencyCodeDictionary, CurrencyCodeDictionary.class);
|
this.currencyCodeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CurrencyCodeDictionary, CurrencyCodeDictionary.class);
|
||||||
|
|
@ -53,13 +64,54 @@ public class SCrossRatesMessageListener extends QueueConsumer implements Initial
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
imdgProvider.waitAvailable();
|
imdgProvider.waitAvailable();
|
||||||
|
callback(SCrossRateNewRequest.class)
|
||||||
|
.setFunction(this::sCrossRatesNew)
|
||||||
|
.forDestination(Consts.DESTINATION_S_CROSS_RATES_NEW, callbacks::put);
|
||||||
|
callback(SCrossRateUpdateRequest.class)
|
||||||
|
.setFunction(this::sCrossRatesUpdate)
|
||||||
|
.forDestination(Consts.DESTINATION_S_CROSS_RATES_UPDATE, callbacks::put);
|
||||||
callback(SCrossRateGatewayRequest.class)
|
callback(SCrossRateGatewayRequest.class)
|
||||||
.setConsumer(this::sCrossRatesProcess)
|
.setConsumer(this::sCrossRatesProcess)
|
||||||
.forDestination(Consts.DESTINATION_S_CROSS_RATES_GATEWAY, callbacks::put);
|
.forDestination(Consts.DESTINATION_S_CROSS_RATES_GATEWAY, callbacks::put);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RequestInfoUpdate sCrossRatesNew(BaseRequest<SCrossRateNewRequest> ratesNewRequest) {
|
||||||
|
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(ratesNewRequest);
|
||||||
|
if (requestInfoUpdate != null) return requestInfoUpdate;
|
||||||
|
SCrossRateNewRequest request = ratesNewRequest.getRequestPayload();
|
||||||
|
IValidator validator = sCrossRatesNewValidator.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
sCrossRateFacade.create(request);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RequestInfoUpdate sCrossRatesUpdate(BaseRequest<SCrossRateUpdateRequest> ratesUpdateRequest) {
|
||||||
|
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(ratesUpdateRequest);
|
||||||
|
if (requestInfoUpdate != null) return requestInfoUpdate;
|
||||||
|
SCrossRateUpdateRequest request = ratesUpdateRequest.getRequestPayload();
|
||||||
|
IValidator validator = sCrossRatesUpdateValidator.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
sCrossRateFacade.update(request);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private void sCrossRatesProcess(BaseRequest<SCrossRateGatewayRequest> sCrossRatesReq) {
|
private void sCrossRatesProcess(BaseRequest<SCrossRateGatewayRequest> sCrossRatesReq) {
|
||||||
SCrossRateGatewayRequest payload = sCrossRatesReq.getRequestPayload();
|
SCrossRateGatewayRequest payload = sCrossRatesReq.getRequestPayload();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package ru.spcex.clearing.securities.validation.rule;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import ru.clearing.classes.statics.data.misc.SCrossRate;
|
||||||
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.SCrossRateNewRequest;
|
||||||
|
import ru.spcex.clearing.securities.errors.SecuritiesError;
|
||||||
|
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 SCrossRatesValidationRule implements IValidationRule<ImdgValidationContext<SCrossRateNewRequest>> {
|
||||||
|
CHECK_ON_EXIST() {
|
||||||
|
@Override
|
||||||
|
public Optional<EnumMessage> validate(ImdgValidationContext<SCrossRateNewRequest> context) {
|
||||||
|
SCrossRateNewRequest action = context.getValidatedObject();
|
||||||
|
Imdg<SCrossRate> imdgDictionary = context.obtainMap(IMDGDistributedNames.Map_SCrossRate, SCrossRate.class);
|
||||||
|
|
||||||
|
ImdgPredicateBuilder predicateBuilder = imdgDictionary.predicateBuilder();
|
||||||
|
SCrossRate rates = imdgDictionary.getFirstObjectByPredicate(
|
||||||
|
predicateBuilder.and(
|
||||||
|
predicateBuilder.equals("currency", action.getCurrency()),
|
||||||
|
predicateBuilder.equals("date", action.getDate())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (rates != null) {
|
||||||
|
return of(SecuritiesError.RatesAlreadyExist, action.getCurrency());
|
||||||
|
}
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String ruleName() {
|
||||||
|
return "SCrossRateNewValidationRule." + name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -133,6 +133,8 @@ public interface Consts {
|
||||||
|
|
||||||
String DESTINATION_RATES_NEW = "rates-new";
|
String DESTINATION_RATES_NEW = "rates-new";
|
||||||
String DESTINATION_RATES_UPDATE = "rates-update";
|
String DESTINATION_RATES_UPDATE = "rates-update";
|
||||||
|
String DESTINATION_S_CROSS_RATES_NEW = "s-cross-rates-new";
|
||||||
|
String DESTINATION_S_CROSS_RATES_UPDATE = "s-cross-rates-update";
|
||||||
String DESTINATION_RATES_GATEWAY = "rates-gateway";
|
String DESTINATION_RATES_GATEWAY = "rates-gateway";
|
||||||
String DESTINATION_S_CROSS_RATES_GATEWAY = "sCross-rates-gateway";
|
String DESTINATION_S_CROSS_RATES_GATEWAY = "sCross-rates-gateway";
|
||||||
String DESTINATION_VALIDATE_SYMBOLS_NEW = "validate-symbols-new";
|
String DESTINATION_VALIDATE_SYMBOLS_NEW = "validate-symbols-new";
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,16 @@ package ru.spcex.clearing.platform.messaging.domain.cud.securitites;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
public class SCrossRateUpdateRequest {
|
public class SCrossRateUpdateRequest {
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private Long id;
|
private Long id;
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
|
private LocalDate date;
|
||||||
|
@JsonProperty
|
||||||
|
private String currency;
|
||||||
|
@JsonProperty
|
||||||
private BigDecimal unitRate;
|
private BigDecimal unitRate;
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private BigDecimal faceValue;
|
private BigDecimal faceValue;
|
||||||
|
|
@ -43,4 +48,20 @@ public class SCrossRateUpdateRequest {
|
||||||
public void setRate(BigDecimal rate) {
|
public void setRate(BigDecimal rate) {
|
||||||
this.rate = rate;
|
this.rate = rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LocalDate getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(LocalDate date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrency() {
|
||||||
|
return currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrency(String currency) {
|
||||||
|
this.currency = currency;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue