This commit is contained in:
AKurakin 2023-06-02 17:16:57 +03:00
parent 3310559df6
commit e5dc6d4487
4 changed files with 245 additions and 40 deletions

View file

@ -40,6 +40,7 @@ public class ValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_Contact, Contact.class);
addImdg.accept(IMDGDistributedNames.Map_Relation, Relation.class);
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary, ServiceStatusDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary, CompanySymbolDictionary.class);

View file

@ -69,7 +69,7 @@ public class AccountNotificationHelper {
public CompanyErrors accountTerminationByDocumentNotification(Long companyId) {
Collection<Account> accounts = accountMap.getCollectionObjectsBySQL("companyId=" + companyId);
log.trace("Found {} accounts by company {}", accounts.size(), companyId);
log.trace("Found {} accounts (will be terminated) by company {}", accounts.size(), companyId);
// for (Account account : accounts) {
// Collection<LiabilitiesClaimsAssets> liabilities = liabilitiesClaimsAssetsMap.getCollectionObjectsBySQL("accountId=" + account.getId());
// for (LiabilitiesClaimsAssets liability : liabilities) {
@ -83,6 +83,7 @@ public class AccountNotificationHelper {
Long reqId = kafkaSender.sendRequestToQueue(Consts.ACCOUNT_TERMINATION, createAccountsRequest(companyId, account));
log.debug("For account[{}] send termination by document request id={}", account.getId(), reqId);
}
//todo group!
// ответ должен послаться в DESTINATION_COMPANY_BLOCK = "company-block";
return null;
}

View file

@ -254,6 +254,7 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin
log.error("Error at termination account of company {} by document {}: {}",
profileDocument.getCompanyId(), profileDocument.getId(), hasError + "(" + hasError.getId() + ")");
}
log.debug("Now wait notification from account-service.");
/* todo processXCNT
Дальнейшая обработка документа о расторжении, то есть обновление статусов в company и relation, возможна только после ответа об успешном обновлении статуса в account.
1.2. Обновить статус в бизнес-объекте company [profileDocument.companyId=company.id] согласно описанию с тегом "При расторжении".

View file

@ -1,5 +1,6 @@
package ru.spcex.clearing.company.service;
import org.apache.commons.lang3.StringUtils;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer;
import org.slf4j.Logger;
@ -36,10 +37,9 @@ import ru.spcex.platform.utils.error.ValidationException;
import ru.spcex.platform.utils.validation.IValidator;
import java.time.Instant;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static ru.spcex.platform.enumeration.Service.FOND;
import static ru.spcex.platform.enumeration.Service.MKR;
@ -55,6 +55,7 @@ public class RelationService extends QueueConsumer implements InitializingBean {
protected ImdgId idSequence;
protected Imdg<Relation> relationMap;
protected Imdg<Company> companyMap;
protected Imdg<ClearingMemberCategory> clearingMemberCategoryImdg;
protected AccountNotificationHelper accountNotification;
protected UserRoleVerification userRoleVerification;
protected RequestHelper requestHelper;
@ -90,6 +91,7 @@ public class RelationService extends QueueConsumer implements InitializingBean {
relationMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
clearingMemberCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
this.requestHelper = requestHelper.setLogger(log);
}
@ -177,11 +179,12 @@ public class RelationService extends QueueConsumer implements InitializingBean {
WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus()) ? Closed.getKey() :
null;
log.debug("Request has no status. Set status by company[{}].status={}. Relation[{}].serviceSStatus={}",
company.getId(), company.getWorkflowStatus(), toStatus);
company.getId(), company.getWorkflowStatus(), relation.getId(), toStatus);
relation.setServiceStatus(toStatus);
}
}
relation.setService(MKR.getKey()); // MKR
String service = serviceForCMC(req.getClearingMemberCategory());
relation.setService(service); // MKR
relation.setServiceProduct(ServiceProduct.ZERO.getKey());
relation.setComment(req.getComment());
@ -191,8 +194,42 @@ public class RelationService extends QueueConsumer implements InitializingBean {
return null;
}
private Relation searchRelation(String clearingMemberCategory, Long consumerId) {
String svc;
Relation relationNew0(ImdgTransaction tx, RelationUpdateRequest req, Long companyId, String clearingMemberCategory) {
Imdg<Company> companyMap = tx.getImdg(IMDGDistributedNames.Map_Company, Company.class);
Imdg<Relation> relationMap = tx.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
Company company = companyMap.getSingleObjectByID(companyId);
Relation relation = new Relation();
relation.setId(idSequence.nextId());
relation.setCreated(Instant.now());
relation.setUpdated(relation.getCreated());
log.debug("New relation.id={}", relation.getId());
relation.setConsumerId(companyId);
relation.setSupplierId(SPVB_ID); // 1 СПВБ
if (req.getServiceStatus() != null) {
relation.setServiceStatus(req.getServiceStatus());
} else {
String toStatus = WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? ServiceStatus.Active.getKey() :
WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus()) ? Closed.getKey() :
null;
log.debug("Request has no status. Set status by company[{}].status={}. Relation[{}].serviceSStatus={}",
company.getId(), company.getWorkflowStatus(), relation.getId(), toStatus);
relation.setServiceStatus(toStatus);
}
String service = serviceForCMC(clearingMemberCategory);
relation.setService(service); // MKR
relation.setServiceProduct(ServiceProduct.ZERO.getKey());
relation.setComment(req.getComment());
relationMap.insert(relation);
log.debug("New Relation[{}] created.", relation.getId());
return null;
}
String serviceForCMC(String clearingMemberCategory) {
String svc = null;
if (ClearingCategory.B.equalsByKey(clearingMemberCategory)
|| ClearingCategory.I.equalsByKey(clearingMemberCategory)
|| ClearingCategory.V.equalsByKey(clearingMemberCategory)
@ -202,7 +239,24 @@ public class RelationService extends QueueConsumer implements InitializingBean {
|| ClearingCategory.F.equalsByKey(clearingMemberCategory)
) {
svc = ru.spcex.platform.enumeration.Service.FOND.getKey();
} else {
}
return svc;
}
ru.spcex.platform.enumeration.Service serviceForCMC(ClearingCategory clearingCategory) {
switch (Objects.requireNonNull(clearingCategory)) {
case B, I, V:
return MKR;
case C, F:
return FOND;
default:
throw new IllegalStateException("Illegal state of clearingCategory " + clearingCategory);
}
}
private Relation searchRelation(String clearingMemberCategory, Long consumerId) {
String svc = serviceForCMC(clearingMemberCategory);
if (svc == null) {
log.warn("Unexpected relation clearingMemberCategory={}", clearingMemberCategory);
return null;
}
@ -217,6 +271,46 @@ public class RelationService extends QueueConsumer implements InitializingBean {
return existRelation;
}
Collection<String> selectCompanyClearingMemberCategory(Long companyId) {
Collection<ClearingMemberCategory> companyCategory = clearingMemberCategoryImdg.getCollectionObjectsByFieldValues(
Map.of("companyId", companyId)
);
return companyCategory.stream()
.map(ClearingMemberCategory::getClearingMemberCategory)
.filter(StringUtils::isNotEmpty)
.distinct()
.collect(Collectors.toList());
}
/**
* @param companyId
* @param service
* @param statusActive фильтр, если null - разрешает всё.
* @return
*/
Relation selectRelation(ImdgTransaction tx, Long companyId, String service, Boolean statusActive) {
Objects.requireNonNull(companyId, "companyId");
Objects.requireNonNull(service, "service");
Imdg<Relation> relationMap = tx.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
Collection<Relation> relations = relationMap.getCollectionObjectsByFieldValues(Map.of("consumerId", companyId, "service", service));
Optional<Relation> r = relations.stream()
.filter(rel -> {
if (statusActive == null) return true;
boolean wasClosed = IEnumKey.contains(rel.getServiceStatus(),
Closed, ServiceStatus.Suspended, ServiceStatus.Blocked);
return statusActive ? !wasClosed : wasClosed;
}).findFirst();
if (r.isPresent()) {
log.trace("Found relation[{}] by consumerId={} and service={} and active={}",
r.get().getId(), companyId, service, statusActive);
return r.get();
} else {
log.trace("Relation not found by consumerId={} and service={} and active={}",
companyId, service, statusActive);
return null;
}
}
private synchronized RequestInfoUpdate relationUpdate(BaseRequest<RelationUpdateRequest> relationUpdateBaseRequest) {
RelationUpdateRequest req = relationUpdateBaseRequest.getRequestPayload();
log.debug("relation-update request received, BaseRequest.id = {}", relationUpdateBaseRequest.getId());
@ -228,10 +322,115 @@ public class RelationService extends QueueConsumer implements InitializingBean {
if (requestInfoUpdate != null) return requestInfoUpdate;
}
Relation relation = relationMap.getSingleObjectByID(req.getId());
relation.setUpdated(Instant.now());
final Long companyId = relation.getConsumerId();
Collection<String> companyCMC = selectCompanyClearingMemberCategory(companyId);
boolean companyCMCisBIV = companyCMC.contains(ClearingCategory.B.getKey()) || companyCMC.contains(ClearingCategory.I.getKey())
|| companyCMC.contains(ClearingCategory.V.getKey());
boolean companyCMCisCF = companyCMC.contains(ClearingCategory.C.getKey()) || companyCMC.contains(ClearingCategory.F.getKey());
String firstCMC = companyCMC.isEmpty() ? null : companyCMC.iterator().next();
ImdgTransaction tx = imdgProvider.newTransaction();
boolean txOk = false;
try {
relationUpdate0(tx, req, relation); // первоначальное ТЗ.
boolean needAddNewRelation = false; // call relationNew0(req, companyId, firstCMC);
if (ru.spcex.platform.enumeration.Service.MKR.equalsByKey(relation.getService())) { // relation B or I or V
if (companyCMCisCF) {
// 4.1. Если clearingMemberCategory = B or I or V и для этой компании установлены clearingMemberCategory = C or F:
Relation relation1 = selectRelation(tx, companyId, MKR.getKey(), false);
if (relation1 != null) {
relationUpdate0WithResume(tx, req, relation1);
} else {
needAddNewRelation = true;
}
Relation relation2 = selectRelation(tx, companyId, MKR.getKey(), true);
if (relation2 != null) {
// nothing
} else {
needAddNewRelation = true;
}
}
if (!companyCMCisCF) {
// 4.3. Если clearingMemberCategory = B or I or V и для этой компании не установлены clearingMemberCategory = C or F:
Relation relation1 = selectRelation(tx, companyId, MKR.getKey(), false);
if (relation1 != null) {
relationUpdate0WithResume(tx, req, relation1);
} else {
needAddNewRelation = true;
}
Relation relation2 = selectRelation(tx, companyId, MKR.getKey(), true);
if (relation2 != null) {
// nothing
} else {
needAddNewRelation = true;
}
Relation relation3 = selectRelation(tx, companyId, FOND.getKey(), null);
if (relation3 != null) {
// nothing
relationClose0(tx, relation3);
}
}
} else if (FOND.equalsByKey(relation.getService())) { // relation C or F
if (companyCMCisBIV) {
// 4.2. Если clearingMemberCategory = C or F и для этой компании установлены clearingMemberCategory = B or I or V:
Relation relation1 = selectRelation(tx, companyId, FOND.getKey(), false);
if (relation1 != null) {
relationUpdate0WithResume(tx, req, relation1);
} else {
needAddNewRelation = true;
}
Relation relation2 = selectRelation(tx, companyId, FOND.getKey(), true);
if (relation2 != null) {
// nothing
} else {
needAddNewRelation = true;
}
}
if (!companyCMCisBIV) {
// 4.4. Если clearingMemberCategory = C or F и для этой компании установлены не clearingMemberCategory = B or I or V:
Relation relation1 = selectRelation(tx, companyId, FOND.getKey(), false);
if (relation1 != null) {
relationUpdate0WithResume(tx, req, relation1);
} else {
needAddNewRelation = true;
}
Relation relation2 = selectRelation(tx, companyId, FOND.getKey(), true);
if (relation2 != null) {
// nothing
} else {
needAddNewRelation = true;
}
Relation relation3 = selectRelation(tx, companyId, MKR.getKey(), null);
if (relation3 != null) {
relationClose0(tx, relation3);
}
}
} else {
// unknown type
relationUpdate0(tx, req, relation);
}
if (needAddNewRelation) {
relationNew0(tx, req, companyId, firstCMC);
}
txOk = true;
} finally {
if (txOk) {
tx.commitTransaction();
} else {
tx.rollbackTransaction();
}
}
return null;
}
private synchronized Relation relationUpdate0(ImdgTransaction tx, RelationUpdateRequest req, Relation relation) {
Imdg<Company> companyMap = tx.getImdg(IMDGDistributedNames.Map_Company, Company.class);
Imdg<Relation> relationMap = tx.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
if (req.getServiceStatus() != null) {
log.debug("To relation {} set serivceStatus=\"{}\" by user request.", relation.getId(), req.getServiceStatus());
relation.setServiceStatus(req.getServiceStatus());
@ -254,11 +453,38 @@ public class RelationService extends QueueConsumer implements InitializingBean {
}
relation.setComment(req.getComment());
relation.setUpdated(Instant.now());
relationMap.insert(relation);
log.debug("Update Relation[{}] created.", relation.getId());
relationMap.update(relation);
log.debug("Update Relation[{}].", relation.getId());
return relation;
}
return null;
private synchronized Relation relationUpdate0WithResume(ImdgTransaction tx, RelationUpdateRequest req, Relation relation) {
if (ServiceStatus.Reopened.equalsByKey(relation.getServiceStatus())) {
log.debug("Relation {} already reopened(resumed)", relation.getId());
return relation;
}
relation.setServiceStatus(ServiceStatus.Reopened.getKey());
relation.setUpdated(Instant.now());
Imdg<Relation> relationMap = tx.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
relationMap.update(relation);
log.debug("Update Relation[{}] - resume.", relation.getId());
return relation;
}
private synchronized void relationClose0(ImdgTransaction tx, Relation relation) {
if (ServiceStatus.Closed.equalsByKey((relation.getServiceStatus()))) {
log.debug("Relation {} already closed.", relation.getId());
return;
}
relation.setServiceStatus(Closed.getKey());
relation.setUpdated(Instant.now());
Imdg<Relation> relationMap = tx.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
relationMap.update(relation);
log.debug("Relation[{}] was closed.", relation.getId());
}
@ -301,19 +527,7 @@ public class RelationService extends QueueConsumer implements InitializingBean {
log.warn("clearingMemberCategory not set for companyId={}", companyId);
} else {
ClearingCategory clearingCategory = getEnumByKey(ClearingCategory.class, clearingMemberCategory.getClearingMemberCategory());
switch (Objects.requireNonNull(clearingCategory)) {
case B:
case I:
case V:
serviceStatus = MKR.getKey();
break;
case C:
case F:
serviceStatus = FOND.getKey();
break;
default:
throw new IllegalStateException("Illegal state of clearingCategory");
}
serviceStatus = serviceForCMC(clearingCategory).getKey();
}
Relation relation = searchRelation(clearingMemberCategory.getClearingMemberCategory(), companyId);
@ -344,19 +558,7 @@ public class RelationService extends QueueConsumer implements InitializingBean {
log.warn("clearingMemberCategory not set for companyId={}", companyId);
} else {
ClearingCategory clearingCategory = getEnumByKey(ClearingCategory.class, clearingMemberCategory.getClearingMemberCategory());
switch (Objects.requireNonNull(clearingCategory)) {
case B:
case I:
case V:
serviceStatus = MKR.getKey();
break;
case C:
case F:
serviceStatus = FOND.getKey();
break;
default:
throw new IllegalStateException("Illegal state of clearingCategory");
}
serviceStatus = serviceForCMC(clearingCategory).getKey();
}
Relation relation = searchRelation(clearingMemberCategory.getClearingMemberCategory(), companyId);