http://jira.mfd.msk:8088/browse/CLS-445 backend-api/clearing-service return deposit request
This commit is contained in:
parent
dac9c80c6f
commit
f7cb4855aa
12 changed files with 264 additions and 7 deletions
|
|
@ -7,13 +7,11 @@ import io.swagger.annotations.ApiResponses;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
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 org.springframework.web.bind.annotation.*;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController;
|
||||
import ru.spcex.clearing.backendapi.controller.request.cud.registry.RSplitDepositActionNew;
|
||||
import ru.spcex.clearing.backendapi.controller.request.cud.registry.ReturnDepositActionNew;
|
||||
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;
|
||||
|
|
@ -57,4 +55,17 @@ public class RegistryController extends AbstractQueueController {
|
|||
@RequestBody RSplitDepositActionNew rSplitDepositActionNew) throws ExecutionException, InterruptedException {
|
||||
return processRequest(Consts.REGISTRY_SPLIT_DEPOSIT_ACTION, rSplitDepositActionNew);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "Отметить средства на возврат депозита")
|
||||
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
|
||||
@RequestMapping(value = "/returnDeposit/{id}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public CudResponse returnDepositAction(
|
||||
@ApiParam(value = "Идентификатор изменяемого объекта.", required = true, example = "1234")
|
||||
@PathVariable("id") Long id,
|
||||
@ApiParam(value = "Параметры команды в JSON формате.", required = true)
|
||||
@RequestBody ReturnDepositActionNew returnDepositAction) throws ExecutionException, InterruptedException {
|
||||
returnDepositAction.setId(id);
|
||||
return processRequest(Consts.REGISTRY_RETURN_DEPOSIT_ACTION, returnDepositAction);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
package ru.spcex.clearing.backendapi.controller.request.cud.registry;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import ru.spcex.clearing.backendapi.domain.actions.IAction;
|
||||
import ru.spcex.clearing.backendapi.errors.BackEndError;
|
||||
import ru.spcex.clearing.platform.messaging.domain.ActionType;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
|
||||
import ru.spcex.platform.classes.base.interfaces.WithId;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class ReturnDepositActionNew implements IAction<RegistryReturnDepositRequest>, WithId {
|
||||
|
||||
@JsonIgnore
|
||||
public Long id;
|
||||
@ApiModelProperty(value = "Сумма", example = "1600.20")
|
||||
@JsonProperty
|
||||
public BigDecimal balance;
|
||||
|
||||
@Override
|
||||
public RegistryReturnDepositRequest toRequest() {
|
||||
var req = new RegistryReturnDepositRequest();
|
||||
req.setId(id);
|
||||
req.setBalance(balance);
|
||||
return req;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<EnumMessage> validate() {
|
||||
List<EnumMessage> errors = new ArrayList<>();
|
||||
if (id == null) {
|
||||
errors.add(new EnumMessage(BackEndError.ValidationError, "url parameter 'id'"));
|
||||
}
|
||||
if (balance == null) {
|
||||
errors.add(new EnumMessage(BackEndError.ValidationError, "balance"));
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
@ApiModelProperty(hidden = true)
|
||||
@Override
|
||||
public ActionType getActionType() {
|
||||
return ActionType.NEW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public BigDecimal getBalance() {
|
||||
return balance;
|
||||
}
|
||||
|
||||
public void setBalance(BigDecimal balance) {
|
||||
this.balance = balance;
|
||||
}
|
||||
}
|
||||
|
|
@ -38,6 +38,7 @@ public class ActionValidationProvider implements InitializingBean {
|
|||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
validators.put(Consts.LAUNCHER_NEW, taskRunnerNew());
|
||||
validators.put(Consts.REGISTRY_RETURN_DEPOSIT_ACTION, idPresent(IMDGDistributedNames.Map_Registry));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
|||
|
|
@ -21,13 +21,16 @@ import ru.clearing.classes.statics.data.sdf.SDf57;
|
|||
import ru.clearing.classes.statics.data.security.MoneyMarketSecurity;
|
||||
import ru.clearing.classes.statics.data.security.Security;
|
||||
import ru.clearing.platform.dictionary.SectionDictionary;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
|
||||
import ru.spcex.clearing.service.validation.*;
|
||||
import ru.spcex.platform.enumeration.ClearingCategory;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||
import ru.spcex.platform.imdg.validation.LogPrefixId;
|
||||
import ru.spcex.platform.imdg.validation.rule.PresentById;
|
||||
import ru.spcex.platform.utils.validation.IValidator;
|
||||
import ru.spcex.platform.utils.validation.ValidatorImpl;
|
||||
|
||||
|
|
@ -239,4 +242,20 @@ public class ValidationConfig {
|
|||
);
|
||||
};
|
||||
}
|
||||
|
||||
@Bean("returnDepositValidator")
|
||||
public Function<RegistryReturnDepositRequest, IValidator> returnDepositValidator() {
|
||||
return returnDepositRequest -> {
|
||||
ImdgValidationContext<RegistryReturnDepositRequest> context = new ImdgValidationContext<>();
|
||||
context.setValidatedObject(returnDepositRequest);
|
||||
context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
|
||||
context.setLogPrefix(LogPrefixId.INSTANCE);
|
||||
return new ValidatorImpl<>(context,
|
||||
new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true),
|
||||
ReturnDepositValidationRule.RegistryCodeCheck,
|
||||
ReturnDepositValidationRule.BalanceCheck,
|
||||
ReturnDepositValidationRule.DmxCheck
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import ru.spcex.platform.utils.enumeration.IErrorEnumId;
|
|||
|
||||
public enum ClearingError implements IErrorEnumId {
|
||||
GeneralError(5400L),
|
||||
RecordNotFoundInDictionary(5423L),
|
||||
IncorrectValue(5404L),
|
||||
RecordNotFound(5406L),
|
||||
CompanyNotFound(5410L),
|
||||
|
|
@ -19,7 +20,9 @@ public enum ClearingError implements IErrorEnumId {
|
|||
ClearingUnavailableForCompany(5421L),
|
||||
InsecurityObligation(5422L),
|
||||
NewDealsNotFound(5423L),
|
||||
//ошибки "перенесенные" из balance-service
|
||||
IdentifiedFundsExceedObligations(5424L),
|
||||
ObligationsAlreadyCalculated(5425L),
|
||||
//ошибки "перенесенные" из balance-service,
|
||||
CompanyNotFoundB(5211L),
|
||||
CurrencyNotFound(5213L),
|
||||
OperationCanBeRunForTodayOnly(5214L),
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.clearing.CreateRegistryRe
|
|||
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.Sdf04Request;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.AssetOperationApprovalRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.STradesImportedRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||
|
|
@ -113,6 +114,9 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean {
|
|||
callback(CreateRegistryRequest.class)
|
||||
.setConsumer(event -> registryService.updateRegistryIfNeeded(event.getRequestPayload()))
|
||||
.forDestination(Consts.REGISTRY_NEW, callbacks::put);
|
||||
callback(RegistryReturnDepositRequest.class)
|
||||
.setFunction(registryService::returnDeposit)
|
||||
.forDestination(Consts.REGISTRY_RETURN_DEPOSIT_ACTION, callbacks::put);
|
||||
callback(LauncherCommandRequest.class)
|
||||
.setConsumer(event -> registryService.resetBalances())
|
||||
.forDestination(Task.createRegistry_GRYT.topic(), callbacks::put);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ public class RegistryManager {
|
|||
this.rgsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
}
|
||||
|
||||
public RegistryManager(Imdg<Registry> rgsImdg) {
|
||||
this.rgsImdg = rgsImdg;
|
||||
}
|
||||
|
||||
public Optional<Registry> searchDmx(Registry rgs) {
|
||||
if (TextUtil.isEmpty(rgs.getContract())) return Optional.empty();
|
||||
String sqlCondition = String.format("(%s) and companyId = %d and contract = '%s'",
|
||||
|
|
|
|||
|
|
@ -2,18 +2,29 @@ package ru.spcex.clearing.service;
|
|||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.CreateRegistryRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
|
||||
import ru.spcex.clearing.platform.messaging.service.Status;
|
||||
import ru.spcex.clearing.service.validation.ValidationStored;
|
||||
import ru.spcex.clearing.session.stage.util.RegistryUtil;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
|
||||
import ru.spcex.platform.imdg.validation.Stored;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
import ru.spcex.platform.utils.validation.IValidator;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
|
|
@ -29,11 +40,17 @@ public class RegistryService {
|
|||
private final ImdgProvider imdgProvider;
|
||||
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
|
||||
private final Imdg<Registry> registryImdg;
|
||||
private final Function<RegistryReturnDepositRequest, IValidator> returnDepositVal;
|
||||
private final IMessageResolver msgResolver;
|
||||
|
||||
public RegistryService(ImdgProvider imdgProvider) {
|
||||
public RegistryService(ImdgProvider imdgProvider,
|
||||
@Qualifier("returnDepositValidator") Function<RegistryReturnDepositRequest, IValidator> returnDepositVal,
|
||||
IMessageResolver msgResolver) {
|
||||
this.imdgProvider = imdgProvider;
|
||||
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
|
||||
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
this.returnDepositVal = returnDepositVal;
|
||||
this.msgResolver = msgResolver;
|
||||
}
|
||||
|
||||
public void createRegistry(CreateRegistryRequest createRegistryRequest) {
|
||||
|
|
@ -87,6 +104,43 @@ public class RegistryService {
|
|||
});
|
||||
}
|
||||
|
||||
public RequestInfoUpdate returnDeposit(BaseRequest<RegistryReturnDepositRequest> req) {
|
||||
RegistryReturnDepositRequest requestPayload = req.getRequestPayload();
|
||||
IValidator validator = returnDepositVal.apply(requestPayload);
|
||||
Optional<EnumMessage> err = validator.tillFirstError();
|
||||
if (err.isPresent()) {
|
||||
log.info("RegistryReturnDepositRequest.id={} validation error: {}",
|
||||
requestPayload.getId(),
|
||||
msgResolver.resolve(err.get()));
|
||||
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get()));
|
||||
}
|
||||
Registry tm_t = validator.getStored(Stored.PresentById);
|
||||
Registry dm_x = validator.getStored(ValidationStored.ReturnDepositDmx);
|
||||
if (dm_x != null) {
|
||||
dm_x.setSessionId(null);
|
||||
dm_x.setSessionType(null);
|
||||
dm_x.setBalance(requestPayload.getBalance());
|
||||
dm_x.setUpdated(Instant.now());
|
||||
registryImdg.update(dm_x);
|
||||
log.debug("updated dm*x.id={} by RegistryReturnDepositRequest.id={}",
|
||||
dm_x.getId(),
|
||||
req.getId());
|
||||
} else {
|
||||
dm_x = tm_t.clone();
|
||||
dm_x.setRegistryDesignation(RegistryDesignation.D.getKey());
|
||||
dm_x.setRegistryUnit(RegistryUnit.X.getKey());
|
||||
dm_x.setRegistryCode(RegistryUtil.clearingCode(dm_x));
|
||||
dm_x.setBalance(requestPayload.getBalance());
|
||||
dm_x.setSessionId(null);
|
||||
dm_x.setSessionType(null);
|
||||
registryImdg.insert(dm_x);
|
||||
log.debug("created dm*x.id={} by RegistryReturnDepositRequest.id={}",
|
||||
dm_x.getId(),
|
||||
req.getId());
|
||||
}
|
||||
return new RequestInfoUpdate(req.getId(), Status.Success, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* находим все регистры AM__/AS__ по пришедшему ТКР
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
package ru.spcex.clearing.service.validation;
|
||||
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
|
||||
import ru.spcex.clearing.service.RegistryManager;
|
||||
import ru.spcex.platform.enumeration.RegistryDesignation;
|
||||
import ru.spcex.platform.enumeration.RegistryInstrumentType;
|
||||
import ru.spcex.platform.enumeration.RegistryStatus;
|
||||
import ru.spcex.platform.enumeration.RegistryUnit;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||
import ru.spcex.platform.imdg.validation.Stored;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.validation.IValidationRule;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public enum ReturnDepositValidationRule implements IValidationRule<ImdgValidationContext<RegistryReturnDepositRequest>> {
|
||||
RegistryCodeCheck() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryReturnDepositRequest> context) {
|
||||
Registry rgs = context.getStoredObject(Stored.PresentById);
|
||||
if (!RegistryDesignation.T.equalsByKey(rgs.getRegistryDesignation())
|
||||
|| !RegistryInstrumentType.M.equalsByKey(rgs.getRegistryInstrumentType())
|
||||
|| !RegistryUnit.T.equalsByKey(rgs.getRegistryUnit())) {
|
||||
return of(ClearingError.RecordNotFoundInDictionary, "TM*T", "Registry");
|
||||
}
|
||||
return empty();
|
||||
}
|
||||
}, BalanceCheck() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryReturnDepositRequest> context) {
|
||||
Registry rgs = context.getStoredObject(Stored.PresentById);
|
||||
RegistryReturnDepositRequest request = context.getValidatedObject();
|
||||
if (request.getBalance() == null || request.getBalance().compareTo(rgs.getBalance()) > 0) {
|
||||
return of(ClearingError.IdentifiedFundsExceedObligations);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}, DmxCheck() {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryReturnDepositRequest> context) {
|
||||
Registry rgs = context.getStoredObject(Stored.PresentById);
|
||||
Imdg<Registry> rgsImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
RegistryManager rgsMng = new RegistryManager(rgsImdg);
|
||||
Optional<Registry> dmx = rgsMng.searchDmx(rgs);
|
||||
if (dmx.isPresent() && RegistryStatus.OK.equalsByKey(dmx.get().getRegistryStatus()) ) {
|
||||
return of(ClearingError.ObligationsAlreadyCalculated);
|
||||
}
|
||||
dmx.ifPresent(dmxRgs -> context.storeObject(ValidationStored.ReturnDepositDmx, dmxRgs));
|
||||
return Optional.empty();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String ruleName() {
|
||||
return "ReturnDepositValidationRule." + name();
|
||||
}
|
||||
}
|
||||
|
|
@ -10,5 +10,7 @@ public enum ValidationStored {
|
|||
|
||||
Sdf08Company, Sdf08Account,
|
||||
|
||||
Sdf06Company, Sdf06Account
|
||||
Sdf06Company, Sdf06Account,
|
||||
|
||||
ReturnDepositDmx
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@ public interface Consts {
|
|||
String PAYMENT_INSTRUCTION_CLEARING_OUTBOUND_ACTION = "clearing-outbound-action";
|
||||
|
||||
String REGISTRY_SPLIT_DEPOSIT_ACTION = "registry-split-deposit-action";
|
||||
String REGISTRY_RETURN_DEPOSIT_ACTION = "registry-return-deposit-action";
|
||||
String REGISTRY_COVERED_DEAL_REGISTER_NEW = "registry-covered-deal-register-new";
|
||||
String REGISTRY_ADMITTED_DEAL_REGISTER_NEW = "registry-admitted-deal-register-new";
|
||||
String REGISTRY_DEAL_REGISTER_NEW = "registry-deal-register-new";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package ru.spcex.clearing.platform.messaging.domain.cud.registry;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import ru.spcex.platform.classes.base.interfaces.WithId;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class RegistryReturnDepositRequest implements WithId {
|
||||
@JsonProperty
|
||||
private Long id;
|
||||
@JsonProperty
|
||||
private BigDecimal balance;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public BigDecimal getBalance() {
|
||||
return balance;
|
||||
}
|
||||
|
||||
public void setBalance(BigDecimal balance) {
|
||||
this.balance = balance;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue