company-service: CompanyInfoService добавил валидацию

This commit is contained in:
AKurakin 2023-04-05 21:43:21 +03:00
parent 1adc5db487
commit 8c43a6e4ae
7 changed files with 153 additions and 22 deletions

View file

@ -3,12 +3,11 @@ package ru.spcex.clearing.company.config.validation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.platform.dictionary.CompanySymbolDictionary;
import ru.clearing.platform.dictionary.WorkflowStatusDictionary;
import ru.clearing.platform.dictionary.*;
import ru.spcex.clearing.company.error.CompanyErrors;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyInfoUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
@ -55,11 +54,11 @@ public class CompanyValidationConfig {
CompanySymbolDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue)
);
);
};
}
@Bean("companyUpdateRequestValidator")//todo type of request
@Bean("companyUpdateRequestValidator")
public Function<CompanyNewRequest, IValidator> companyUpdateRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return companyNewRequest -> {
ImdgValidationContext<CompanyNewRequest> context = new ImdgValidationContext<>();
@ -113,4 +112,67 @@ public class CompanyValidationConfig {
};
}
@Bean("CompanyInfoUpdateRequestValidator")
public Function<CompanyInfoUpdateRequest, IValidator> companyInfoUpdateRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return companyDeleteRequest -> {
ImdgValidationContext<CompanyInfoUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(companyDeleteRequest);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_Company);
return new ValidatorImpl<>(context,
// FieldRequiredRule.instance("id", CommonDeleteRequest::getId, CompanyErrors.RequiredFieldEmpty),
IdPresentRule.instance("id",
CompanyInfoUpdateRequest::getId,
IMDGDistributedNames.Map_Company,
Company.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.CompanyNotFound,
company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : CompanyErrors.CompanyDisabled),
DictionaryPresentRule.instance("CorporationSoleType",
CompanyInfoUpdateRequest::getCorporationSoleType,
IMDGDistributedNames.Map_CorporationSoleTypeDictionary,
CorporationSoleTypeDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue, false),
DictionaryPresentRule.instance("CountryCode",
CompanyInfoUpdateRequest::getCountryCode,
IMDGDistributedNames.Map_CountryCodeDictionary,
CountryCodeDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
false),
DictionaryPresentRule.instance("ProfessionalSign",
CompanyInfoUpdateRequest::getProfessionalSign,
IMDGDistributedNames.Map_AllowedDictionary,
AllowedDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
false),
DictionaryPresentRule.instance("legalKind",
CompanyInfoUpdateRequest::getLegalKind,
IMDGDistributedNames.Map_LegalKindDictionary,
LegalKindDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
false),
DictionaryPresentRule.instance("organizationType",
CompanyInfoUpdateRequest::getOrganizationType,
IMDGDistributedNames.Map_OrganizationTypeDictionary,
OrganizationTypeDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
false),
DictionaryPresentRule.instance("residence",
CompanyInfoUpdateRequest::getResidence,
IMDGDistributedNames.Map_CountryCodeDictionary,
CountryCodeDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
false)
);
};
}
}

View file

@ -6,9 +6,7 @@ import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.generated.ClearingMemberCategory;
import ru.clearing.classes.statics.data.profile.Contact;
import ru.clearing.classes.statics.data.profile.ProfileDocument;
import ru.clearing.platform.dictionary.ClearingCategoryDictionary;
import ru.clearing.platform.dictionary.ContactTypeDictionary;
import ru.clearing.platform.dictionary.DocumentTypeDictionary;
import ru.clearing.platform.dictionary.*;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.classes.base.SpcexObjectBase;
@ -38,6 +36,12 @@ public class ValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary, DocumentTypeDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary, DocumentTypeDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_CorporationSoleTypeDictionary, CorporationSoleTypeDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_AllowedDictionary, AllowedDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_LegalKindDictionary, LegalKindDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_OrganizationTypeDictionary, OrganizationTypeDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class);
return imdg;

View file

@ -6,48 +6,98 @@ 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.clearing.classes.statics.data.profile.CompanyInfo;
import ru.spcex.clearing.company.error.CompanyErrors;
import ru.spcex.clearing.company.util.RequestHelper;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyInfoUpdateRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.UserRole;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
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.function.Function;
@Service
public class CompanyInfoService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
// private final Imdg<CompanyInfo> companyInfoMap;
private final Imdg<Company> companyMap;
protected final CompanyService companyService;
private final RequestHelper requestHelper;
private final ValidationHelper validationHelper;
final Function<CompanyInfoUpdateRequest, IValidator> companyInfoUpdateRequestValidator;
final UserRoleVerification userRoleVerification;
@Autowired
public CompanyInfoService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider, CompanyService companyService) {
ImdgProvider imdgProvider, CompanyService companyService,
IMessageResolver messageResolver, ValidationHelper validationHelper,
UserRoleVerification userRoleVerification,
@Qualifier("CompanyInfoUpdateRequestValidator")
Function<CompanyInfoUpdateRequest, IValidator> companyInfoUpdateRequestValidator) {
super(kafkaQueue, kafkaProducer);
this.companyService = companyService;
// this.companyInfoMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyInfo, CompanyInfo.class);
this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.validationHelper = validationHelper;
this.userRoleVerification = userRoleVerification;
this.requestHelper = new RequestHelper(log, messageResolver);
this.companyInfoUpdateRequestValidator = companyInfoUpdateRequestValidator;
}
@Override
public void afterPropertiesSet() {
callback(CompanyInfoUpdateRequest.class)
.setConsumer(this::companyInfoUpdate)
.setFunction(this::companyInfoUpdate)
.forDestination(Consts.DESTINATION_COMPANY_INFO_UPDATE, callbacks::put);
callback(CompanyInfoUpdateRequest.class)
.setFunction(this::companyInfoUpdate)
.forDestination(Consts.DESTINATION_COMPANY_INFO_NEW, callbacks::put); // логика заполнения одинакова с companyInfoUpdate
init();
}
public void companyInfoUpdate(BaseRequest<CompanyInfoUpdateRequest> userRequest) {
CompanyInfoUpdateRequest req = userRequest.getRequestPayload();
log.debug("CompanyInfoUpdateRequest received");
protected void validateRole(BaseRequest<?> req) throws ValidationException {
Long requestor = req.getUserId();
if (requestor != null && !userRoleVerification.userHasRole(requestor, UserRole.Admin)) {
log.trace("User {} has no role to allow this action", requestor);
throw new ValidationException(CompanyErrors.UserVerifyDenial);
} else {
log.trace("Request without userId");
}
}
public RequestInfoUpdate companyInfoUpdate(BaseRequest<CompanyInfoUpdateRequest> companyInfoReq) {
CompanyInfoUpdateRequest req = companyInfoReq.getRequestPayload();
log.debug("{} received", req.getClass().getSimpleName());
{ // Валидация, ValidationException
try {
validateRole(companyInfoReq);
} catch (ValidationException e) {
return requestHelper.makeErrorResponse(companyInfoReq, e.getEnumMsg());
}
RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyInfoReq, companyInfoUpdateRequestValidator);
if (requestInfoUpdate != null)
return requestInfoUpdate;
}
synchronized (companyService) {
// CompanyInfo companyInfo = companyInfoMap.getSingleObjectByID(req.getId());
Company company = companyMap.getSingleObjectByID(req.getId());
CompanyInfo companyInfo = company == null ? null : company.getProfile();
if (company == null) {
log.trace("Company {} not found", req.getId());
return requestHelper.makeErrorResponse(companyInfoReq, CompanyErrors.CompanyNotFound, companyInfoReq.getId());
}
CompanyInfo companyInfo = company.getProfile();
companyInfo.setCorporationSoleType(req.getCorporationSoleType());
companyInfo.setCountryCode(req.getCountryCode());
@ -60,9 +110,11 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea
companyInfo.setFullNameEng(req.getFullNameEng());
companyInfo.setShortName(req.getShortName());
companyInfo.setFullName(req.getFullName());
// companyInfoMap.update(companyInfo);
company.setUpdated(Instant.now());
companyMap.update(company);
log.debug("successfully processed, id {}", companyInfo.getId());
log.debug("successfully CompanyInfo processed, id {}", companyInfo.getId());
}
return null;
}
}

View file

@ -169,7 +169,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean {
}
private synchronized RequestInfoUpdate updateCompany(BaseRequest<CompanyNewRequest /* todo type CompanyUpdateRequest*/> companyUpdateRequestBaseRequest) throws ValidationException {
private synchronized RequestInfoUpdate updateCompany(BaseRequest<CompanyNewRequest> companyUpdateRequestBaseRequest) throws ValidationException {
CompanyNewRequest updateRequest = companyUpdateRequestBaseRequest.getRequestPayload();
{ // Валидация, ValidationException
validateRole(companyUpdateRequestBaseRequest);

View file

@ -7,6 +7,7 @@ import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumId;
import ru.spcex.platform.utils.enumeration.IErrorEnumId;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.error.ClearingBaseException;
import ru.spcex.platform.utils.log.ExceptionUtils;
@ -75,8 +76,7 @@ public class RequestHelper {
}
public RequestInfoUpdate makeErrorResponse(BaseRequest<?> request, IEnumId error, Object ... args) {
//todo должны уточнить интерфейс IEnumId в CompanyErrors, вечером проверить код.
public RequestInfoUpdate makeErrorResponse(BaseRequest<?> request, IErrorEnumId error, Object ... args) {
return makeErrorResponse(request, new EnumMessage(error, args));
}

View file

@ -56,6 +56,17 @@ class CompanyInfoServiceTest {
private void init() {
hazelcastServiceTest.waitAvailable();
companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class);
/* todo залить тестовые словари:
IMDGDistributedNames.Map_WorkflowStatusDictionary, DocumentTypeDictionary.class);
IMDGDistributedNames.Map_CompanySymbolDictionary, DocumentTypeDictionary.class);
IMDGDistributedNames.Map_CorporationSoleTypeDictionary, CorporationSoleTypeDictionary.class);
IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class);
IMDGDistributedNames.Map_AllowedDictionary, AllowedDictionary.class);
IMDGDistributedNames.Map_LegalKindDictionary, LegalKindDictionary.class);
IMDGDistributedNames.Map_OrganizationTypeDictionary, OrganizationTypeDictionary.class);
IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class);
*/
}
/**

View file

@ -38,6 +38,7 @@ public interface Consts {
String DESTINATION_COMPANY_DELETE = "company-delete";
String DESTINATION_COMPANY_UPDATE = "company-update";
String DESTINATION_COMPANY_BLOCK = "company-block";
String DESTINATION_COMPANY_INFO_NEW = "company-info-new";
String DESTINATION_COMPANY_INFO_UPDATE = "company-info-update";
String DESTINATION_COMPANY_SYMBOL_UPDATE = "company-symbol-update";
String DESTINATION_CONTACT_NEW = "contact-new";
@ -67,6 +68,7 @@ public interface Consts {
String SDF11_PROCESS = "sdf11-process";
String EXPORT_PROCESS = "export-process";
String ACCOUNT_NEW = "account-new";
String ACCOUNT_TERMINATION = "account-termination";
String BALANCE_ACCOUNT_NEW = "balance-account-new";
String BALANCE_ACCOUNT_UPDATE = "balance-account-update";
String CONTINUE_CLEARING = "continue-clearing";