This commit is contained in:
parent
f99989145c
commit
ee86ba8340
10 changed files with 354 additions and 2 deletions
|
|
@ -92,7 +92,7 @@ import static ru.spcex.clearing.backendapi.controller.utils.MatcherFactory.using
|
|||
BankAccountController.class,
|
||||
//company
|
||||
CompanyRoleSetController.class,
|
||||
//fixme на 31.03.2023 нет такого класса DeleteCompanyController.class,
|
||||
CompanyController.class,
|
||||
EditClearingMemberCategoryController.class,
|
||||
EditCompanyInfoController.class,
|
||||
EditCompanySymbolController.class,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
package ru.spcex.clearing.validation.common;
|
||||
|
||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumId;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
import ru.spcex.platform.utils.validation.IValidationRule;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Проверка поля со значением из множества (enum)
|
||||
* @param <R> Класс проверяемого объекта
|
||||
* @param <E> Enum
|
||||
*/
|
||||
public record EnumPresentRule<R, E extends IEnumKey>(String fieldName,
|
||||
Function<R, String> getter,
|
||||
E[] enumValues,
|
||||
boolean required,
|
||||
IEnumId errorWrongEnumValue,
|
||||
IEnumId errorEmptyRequiredValue) implements IValidationRule<ImdgValidationContext<R>> {
|
||||
|
||||
/**
|
||||
* @param fieldName Название поля
|
||||
* @param getter Метод получения проверяемого значения
|
||||
* @param enumValues Значения из проверяемого множества (Enum.values())
|
||||
* @param required Флаг обязательности
|
||||
* @param <R> Класс проверяемого объекта
|
||||
* @param <E> Enum
|
||||
*/
|
||||
public static <R, E extends IEnumKey> EnumPresentRule<R, E> instance(String fieldName,
|
||||
Function<R, String> getter,
|
||||
E[] enumValues,
|
||||
boolean required,
|
||||
IEnumId errorWrongEnumValue,
|
||||
IEnumId errorEmptyRequiredValue) {
|
||||
if (errorWrongEnumValue == null) throw new IllegalArgumentException("Empty errorWrongEnumValue");
|
||||
if (required && errorEmptyRequiredValue == null) throw new IllegalArgumentException("Empty errorEmptyRequiredValue");
|
||||
return new EnumPresentRule<>(fieldName, getter, enumValues, required, errorWrongEnumValue, errorEmptyRequiredValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fieldName Название поля
|
||||
* @param getter Метод получения проверяемого значения
|
||||
* @param enumValues Значения из проверяемого множества (Enum.values())
|
||||
* @param <R> Класс проверяемого объекта
|
||||
* @param <E> Enum
|
||||
*/
|
||||
public static <R, E extends IEnumKey> EnumPresentRule<R, E> instance(String fieldName,
|
||||
Function<R, String> getter,
|
||||
E[] enumValues,
|
||||
IEnumId errorWrongEnumValue,
|
||||
IEnumId errorEmptyRequiredValue) {
|
||||
return new EnumPresentRule<>(fieldName, getter, enumValues, true, errorWrongEnumValue, errorEmptyRequiredValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
|
||||
R validatedObject = context.getValidatedObject();
|
||||
String enumCode = getter.apply(validatedObject);
|
||||
if (enumCode == null) return required ? of(errorEmptyRequiredValue, fieldName) : empty();
|
||||
for (E enumValue : enumValues) {
|
||||
if (enumValue.getKey().equals(enumCode)) return empty();
|
||||
}
|
||||
return of(errorWrongEnumValue, fieldName);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package ru.spcex.clearing.validation.common;
|
||||
|
||||
|
||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumId;
|
||||
import ru.spcex.platform.utils.validation.IValidationRule;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Проверка обязательности поля (not null)
|
||||
* @param <R> Класс проверяемого объекта
|
||||
* @param <V> Класс проверяемого значения
|
||||
*/
|
||||
public record FieldRequiredRule<R, V>(String fieldName, Function<R, V> getter, IEnumId errorEmptyRequiredValue) implements IValidationRule<ImdgValidationContext<R>> {
|
||||
|
||||
/**
|
||||
* @param fieldName Название поля
|
||||
* @param getter Метод получения значения
|
||||
* @param <R> Класс проверяемого объекта
|
||||
* @param <V> Класс проверяемого значения
|
||||
*/
|
||||
public static <R, V> FieldRequiredRule<R, V> instance(String fieldName, Function<R, V> getter, IEnumId errorEmptyRequiredValue) {
|
||||
if (errorEmptyRequiredValue == null) throw new IllegalArgumentException("Empty errorEmptyRequiredValue");
|
||||
return new FieldRequiredRule<>(fieldName, getter, errorEmptyRequiredValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
|
||||
R validatedObject = context.getValidatedObject();
|
||||
V value = getter.apply(validatedObject);
|
||||
if (value == null) return of(errorEmptyRequiredValue, fieldName);
|
||||
return empty();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package ru.spcex.clearing.company.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
import ru.spcex.platform.utils.enumeration.SimpleMessageResolver;
|
||||
|
||||
@Configuration
|
||||
public class BeanConfiguration {
|
||||
@Bean
|
||||
public IMessageResolver messageResolver() {
|
||||
return new SimpleMessageResolver();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package ru.spcex.clearing.company.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import ru.spcex.clearing.company.error.CompanyErrors;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest;
|
||||
//import ru.spcex.clearing.validation.common.FieldRequiredRule;
|
||||
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;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Configuration
|
||||
public class CompanyValidationConfig {
|
||||
|
||||
@Bean("companyNewRequestValidator")
|
||||
public Function<CompanyNewRequest, IValidator> companyNewRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
|
||||
return companyNewRequest -> {
|
||||
ImdgValidationContext<CompanyNewRequest> context = new ImdgValidationContext<>();
|
||||
context.setValidatedObject(companyNewRequest);
|
||||
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
|
||||
// addImdg.accept(IMDGDistributedNames.Map_TaskDictionary);
|
||||
// addImdg.accept(IMDGDistributedNames.Map_TaskStatusDictionary);
|
||||
addImdg.accept(IMDGDistributedNames.Map_Company);
|
||||
// addImdg.accept(IMDGDistributedNames.Map_Security);
|
||||
return new ValidatorImpl<>(context
|
||||
// ,
|
||||
// FieldRequiredRule.instance("shortName", CompanyNewRequest::getShortName, CompanyErrors.RequiredFieldEmpty),
|
||||
// FieldRequiredRule.instance("companySymbol", CompanyNewRequest::getCompanySymbol, CompanyErrors.RequiredFieldEmpty),
|
||||
// FieldRequiredRule.instance("companySymbolValue", CompanyNewRequest::getCompanySymbolValue, CompanyErrors.RequiredFieldEmpty),
|
||||
// FieldRequiredRule.instance("workflowStatus", CompanyNewRequest::getWorkflowStatus, CompanyErrors.RequiredFieldEmpty),
|
||||
|
||||
// DictionaryPresentRule.instance("workflowStatus",
|
||||
// CompanyNewRequest::getWorkflowStatus,
|
||||
// IMDGDistributedNames.Map_WorkflowStatus,
|
||||
// WorkflowStatusDictionary.class),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package ru.spcex.clearing.company.error;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.IEnumId;
|
||||
|
||||
public enum CompanyErrors implements IEnumId {
|
||||
GeneralError(3000L), // Общая ошибка модуля company-service
|
||||
UserVerifyDenial(3001L), // 'Нет прав на проведение данной операции
|
||||
|
||||
RequiredFieldEmpty(3002L), // Не заданы обязательные поля %s.
|
||||
DictionaryNotFound(3003L), // Запись с идентификатором %s в справочнике %s не найдена.
|
||||
VrongFieldValue(3004L), // Неверное значение поля %s.
|
||||
RecordAlreadyExist(3005L), // Запись с идентификатором %s уже существует.
|
||||
RecordNotFound(3006L), // Запись с идентификатором %s не найдена.
|
||||
CompanyALreadyExist(3010L), // Компания %s уже существует
|
||||
CompanyNotFound(3011L), // Компания %s не найдена.
|
||||
CompanyDisabled(3012L), // Компания %s неактивна.
|
||||
ProfileNotFound(3013L), // Профиль компании %s не найден.
|
||||
CompanyInfoNotFound(3014L), // Реквизит компании %s не найден.
|
||||
ContactNotFound(3015L), // Контакт компании %s не найден.
|
||||
CategoryNotFound(3016L), // Категория компании %s не найдена.
|
||||
CategoryAlreadySet(3017L), // Компании %s уже присвоена категория %s.
|
||||
CompanyAlreadyHas_(3018L), // У компании %s присутствуют обязательства.
|
||||
|
||||
;
|
||||
private final Long id;
|
||||
|
||||
CompanyErrors(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
|
|
@ -14,19 +15,44 @@ import ru.spcex.clearing.platform.messaging.domain.Consts;
|
|||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||
//import ru.spcex.clearing.util.security.UserRoleVerification;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgId;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
import ru.spcex.platform.utils.error.ValidationException;
|
||||
import ru.spcex.platform.utils.validation.IValidator;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Service
|
||||
public class CompanyService extends QueueConsumer implements InitializingBean {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Imdg<Company> companyMap;
|
||||
private final ImdgId idSequence;
|
||||
// protected UserRoleVerification userRoleVerification;
|
||||
protected IMessageResolver messageResolver;
|
||||
|
||||
private Function<CompanyNewRequest, IValidator> companyNewRequestValidator;
|
||||
|
||||
@Autowired
|
||||
public CompanyService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
|
||||
ImdgProvider imdgProvider) {
|
||||
ImdgProvider imdgProvider,
|
||||
IMessageResolver messageResolver,
|
||||
// , UserRoleVerification userRoleVerification
|
||||
@Qualifier("companyNewRequestValidator")
|
||||
Function<CompanyNewRequest, IValidator> companyNewRequestValidator
|
||||
) {
|
||||
super(kafkaQueue, kafkaProducer);
|
||||
this.messageResolver = messageResolver;
|
||||
this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
this.idSequence = imdgProvider.getImdgIdGenerator();
|
||||
// this.userRoleVerification = userRoleVerification;
|
||||
this.companyNewRequestValidator = companyNewRequestValidator;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -37,23 +63,87 @@ public class CompanyService extends QueueConsumer implements InitializingBean {
|
|||
callback(CompanyNewRequest.class)
|
||||
.setConsumer(this::createCompany)
|
||||
.forDestination(Consts.DESTINATION_COMPANY_NEW, callbacks::put);
|
||||
callback(CompanyNewRequest.class)
|
||||
.setConsumer(this::updateCompany)
|
||||
.forDestination(Consts.DESTINATION_COMPANY_UPDATE, callbacks::put);
|
||||
//todo IV - сообщения на добавления документа расторжения договора - см. Документ расторжения договора. profileDocument): необходимо обновить запись в company согласно описанию с тэгом "При обработке расторжения".
|
||||
// callback(CompanyNewRequest.class)
|
||||
// .setConsumer(this::updateCompany)
|
||||
// .forDestination(Consts.DESTINATION_COMPANY_UPDATE, callbacks::put);
|
||||
init();
|
||||
}
|
||||
|
||||
protected void validateRole(BaseRequest<CompanyNewRequest> req) throws ValidationException {
|
||||
Long requestor = null; // todo требуется передавать это значение из frontendapi! req.getUserId();
|
||||
// if (!userRoleVerification.userHasRole(requestor, UserRole.Admin)) {
|
||||
//
|
||||
// };
|
||||
}
|
||||
|
||||
void validate(CompanyNewRequest object) throws ValidationException {
|
||||
IValidator validator = companyNewRequestValidator.apply(object);
|
||||
Optional<EnumMessage> error = validator.tillFirstError();
|
||||
if (error.isPresent()) {
|
||||
log.warn("CompanyNewRequest validation error: {}", error.get());
|
||||
String errorMsg = messageResolver.resolve(error.get());
|
||||
// return new RequestInfoUpdate() // todo reply message
|
||||
// .setId(userRequest.getId())
|
||||
// .setStatus(Status.Error)
|
||||
// .setMessage(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
private void createCompany(BaseRequest<CompanyNewRequest> companyNewRequestBaseRequest) {
|
||||
CompanyNewRequest req = companyNewRequestBaseRequest.getRequestPayload();
|
||||
log.debug("company-new request received, BaseRequest.id = {}", companyNewRequestBaseRequest.getId());
|
||||
try {
|
||||
validateRole(companyNewRequestBaseRequest);
|
||||
validate(req);
|
||||
} catch (ValidationException e) {
|
||||
throw new RuntimeException(e); // todo true return error
|
||||
}
|
||||
Company company = new Company();
|
||||
company.setId(idSequence.nextId());
|
||||
Instant now = Instant.now();
|
||||
company.setCreated(now);
|
||||
company.setUpdated(now);
|
||||
|
||||
company.setShortName(req.getShortName());
|
||||
company.setFullName(req.getFullName());
|
||||
company.setTradingCode(req.getTradingCode());
|
||||
company.setClearingCode(req.getClearingCode());
|
||||
company.setRegistrationCode(req.getRegistrationCode());
|
||||
|
||||
company.setWorkflowStatus(WorkflowStatus.Active.getKey());
|
||||
// if (WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) {
|
||||
//
|
||||
// } else if (WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus())) {
|
||||
//
|
||||
// }
|
||||
|
||||
companyMap.insert(company);
|
||||
log.debug("company-new request processed, BaseRequest.id = {}, company.id={}",
|
||||
companyNewRequestBaseRequest.getId(), company.getId());
|
||||
}
|
||||
|
||||
|
||||
private void updateCompany(BaseRequest<? /* todo type CompanyUpdateRequest*/> companyNewRequestBaseRequest) {
|
||||
//todo update
|
||||
// CompanyUpdateRequest req = companyUpdateRequestBaseRequest.getRequestPayload();
|
||||
// log.debug("company-update request received, BaseRequest.id = {}", companyNewRequestBaseRequest.getId());
|
||||
// Company company = new Company();
|
||||
// company.setShortName(req.getShortName());
|
||||
// company.setFullName(req.getFullName());
|
||||
// company.setTradingCode(req.getTradingCode());
|
||||
// company.setClearingCode(req.getClearingCode());
|
||||
// company.setRegistrationCode(req.getRegistrationCode());
|
||||
// companyMap.insert(company);
|
||||
// log.debug("company-update request processed, BaseRequest.id = {}, company.id={}",
|
||||
// companyNewRequestBaseRequest.getId(), company.getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void deleteCompany(BaseRequest<CommonDeleteRequest> userRequest) {
|
||||
CommonDeleteRequest req = userRequest.getRequestPayload();
|
||||
log.debug("CommonDeleteRequest received id = {}", req.getId());
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ public interface Consts {
|
|||
|
||||
String DESTINATION_COMPANY_NEW = "company-new";
|
||||
String DESTINATION_COMPANY_DELETE = "company-delete";
|
||||
String DESTINATION_COMPANY_UPDATE = "company-update";
|
||||
String DESTINATION_COMPANY_INFO_UPDATE = "company-info-update";
|
||||
String DESTINATION_COMPANY_SYMBOL_UPDATE = "company-symbol-update";
|
||||
String DESTINATION_CONTACT_UPDATE = "contact-update";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
package ru.spcex.platform.utils.error;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumId;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ClearingBaseException extends Exception {
|
||||
final EnumMessage enumMsg;
|
||||
|
||||
public ClearingBaseException(EnumMessage msg) {
|
||||
super(msg == null ? "" : msg.getSubject().getId() + " " + (msg.getArgs() == null ? "" : Arrays.toString(msg.getArgs())));
|
||||
this.enumMsg = msg;
|
||||
}
|
||||
|
||||
public <ErrorEnum extends IEnumId> ClearingBaseException(ErrorEnum code) {
|
||||
this(new EnumMessage(code));
|
||||
}
|
||||
|
||||
public <ErrorEnum extends IEnumId> ClearingBaseException(ErrorEnum code, String message) {
|
||||
super(code == null ? message : code.getId() + " " + message);
|
||||
this.enumMsg = new EnumMessage(code);
|
||||
}
|
||||
|
||||
public <ErrorEnum extends IEnumId> ClearingBaseException(ErrorEnum code, String message, Throwable cause) {
|
||||
super(code == null ? message : code.getId() + " " + message, cause);
|
||||
this.enumMsg = new EnumMessage(code);
|
||||
}
|
||||
|
||||
// public <ErrorEnum extends IEnumId> ClearingBaseException(String message, Throwable cause) {
|
||||
// super(message, cause);
|
||||
// this.enumMsg = new EnumMessage(ClearingError.GeneralError);
|
||||
// }
|
||||
|
||||
public EnumMessage getEnumMsg() {
|
||||
return enumMsg;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package ru.spcex.platform.utils.error;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumId;
|
||||
|
||||
public class ValidationException extends ClearingBaseException {
|
||||
|
||||
public ValidationException(EnumMessage msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public <ErrorEnum extends IEnumId> ValidationException(ErrorEnum code, String... args) {
|
||||
super(new EnumMessage(code, args));
|
||||
}
|
||||
|
||||
public <ErrorEnum extends IEnumId> ValidationException(ErrorEnum code, String message) {
|
||||
super(code, message);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue