次月政策
This commit is contained in:
parent
7df5a8e04d
commit
fb4184584d
@ -0,0 +1,32 @@
|
|||||||
|
package com.red.circle.other.inner.enums.team;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队政策状态.
|
||||||
|
*/
|
||||||
|
public enum TeamPolicyStatusEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 草稿.
|
||||||
|
*/
|
||||||
|
DRAFT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 待生效.
|
||||||
|
*/
|
||||||
|
SCHEDULED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前生效.
|
||||||
|
*/
|
||||||
|
ACTIVE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 历史政策.
|
||||||
|
*/
|
||||||
|
HISTORY,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已取消.
|
||||||
|
*/
|
||||||
|
CANCELLED
|
||||||
|
}
|
||||||
@ -46,6 +46,26 @@ public class TeamPolicyManagerCmd extends CommonCommand {
|
|||||||
*/
|
*/
|
||||||
private Boolean release;
|
private Boolean release;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 政策状态 DRAFT/SCHEDULED/ACTIVE/HISTORY/CANCELLED.
|
||||||
|
*/
|
||||||
|
private String policyStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生效月份 yyyyMM.
|
||||||
|
*/
|
||||||
|
private Integer effectiveMonth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生效时间.
|
||||||
|
*/
|
||||||
|
private Timestamp effectiveStartTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实际激活时间.
|
||||||
|
*/
|
||||||
|
private Timestamp activatedTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标题.
|
* 标题.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -52,6 +52,26 @@ public class TeamPolicyManagerDTO implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private Boolean release;
|
private Boolean release;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 政策状态 DRAFT/SCHEDULED/ACTIVE/HISTORY/CANCELLED.
|
||||||
|
*/
|
||||||
|
private String policyStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生效月份 yyyyMM.
|
||||||
|
*/
|
||||||
|
private Integer effectiveMonth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生效时间.
|
||||||
|
*/
|
||||||
|
private Timestamp effectiveStartTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实际激活时间.
|
||||||
|
*/
|
||||||
|
private Timestamp activatedTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标题.
|
* 标题.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import com.red.circle.console.app.dto.clienobject.team.TeamPolicyManagerCO;
|
|||||||
import com.red.circle.console.app.service.app.team.TeamPolicyManagerBackService;
|
import com.red.circle.console.app.service.app.team.TeamPolicyManagerBackService;
|
||||||
import com.red.circle.framework.web.controller.BaseController;
|
import com.red.circle.framework.web.controller.BaseController;
|
||||||
import com.red.circle.other.inner.endpoint.team.target.TeamBillCycleClient;
|
import com.red.circle.other.inner.endpoint.team.target.TeamBillCycleClient;
|
||||||
|
import com.red.circle.other.inner.enums.team.TeamPolicyStatusEnum;
|
||||||
import com.red.circle.other.inner.model.cmd.team.TeamBillCycleBackQryCmd;
|
import com.red.circle.other.inner.model.cmd.team.TeamBillCycleBackQryCmd;
|
||||||
import com.red.circle.other.inner.model.cmd.team.TeamPolicyManagerBackQryCmd;
|
import com.red.circle.other.inner.model.cmd.team.TeamPolicyManagerBackQryCmd;
|
||||||
import com.red.circle.other.inner.model.cmd.team.TeamPolicyManagerCmd;
|
import com.red.circle.other.inner.model.cmd.team.TeamPolicyManagerCmd;
|
||||||
@ -60,7 +61,8 @@ public class TeamPolicyManagerRestController extends BaseController {
|
|||||||
teamPolicyManagerBackService.add(param);
|
teamPolicyManagerBackService.add(param);
|
||||||
|
|
||||||
// 发布完政策如果有团队是其他政策需要替换最新的政策,可能出现的情况:钻石->美元;美元->钻石;美元->美元;钻石->钻石
|
// 发布完政策如果有团队是其他政策需要替换最新的政策,可能出现的情况:钻石->美元;美元->钻石;美元->美元;钻石->钻石
|
||||||
if (Objects.equals(param.getRelease(), Boolean.TRUE)) {
|
if (Objects.equals(param.getRelease(), Boolean.TRUE)
|
||||||
|
&& !Objects.equals(param.getPolicyStatus(), TeamPolicyStatusEnum.SCHEDULED.name())) {
|
||||||
// 发布后主动重算该系统、该区域下团队的未出账账单。
|
// 发布后主动重算该系统、该区域下团队的未出账账单。
|
||||||
teamBillCycleClient.refreshUnpaidBills(new TeamBillCycleBackQryCmd()
|
teamBillCycleClient.refreshUnpaidBills(new TeamBillCycleBackQryCmd()
|
||||||
.setSysOrigin(param.getSysOrigin())
|
.setSysOrigin(param.getSysOrigin())
|
||||||
|
|||||||
@ -53,6 +53,26 @@ public class TeamPolicyManagerCO implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private Boolean release;
|
private Boolean release;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 政策状态 DRAFT/SCHEDULED/ACTIVE/HISTORY/CANCELLED.
|
||||||
|
*/
|
||||||
|
private String policyStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生效月份 yyyyMM.
|
||||||
|
*/
|
||||||
|
private Integer effectiveMonth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生效时间.
|
||||||
|
*/
|
||||||
|
private Timestamp effectiveStartTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实际激活时间.
|
||||||
|
*/
|
||||||
|
private Timestamp activatedTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标题.
|
* 标题.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -0,0 +1,94 @@
|
|||||||
|
package com.red.circle.other.app.scheduler;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.red.circle.component.redis.annotation.TaskCacheLock;
|
||||||
|
import com.red.circle.mq.rocket.business.producer.TeamSalaryMqMessage;
|
||||||
|
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamPolicyManager;
|
||||||
|
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamProfile;
|
||||||
|
import com.red.circle.other.infra.database.mongo.service.team.team.TeamPolicyManagerService;
|
||||||
|
import com.red.circle.other.infra.database.mongo.service.team.team.TeamProfileService;
|
||||||
|
import com.red.circle.other.inner.model.dto.agency.agency.TeamStatus;
|
||||||
|
import com.red.circle.tool.core.collection.CollectionUtils;
|
||||||
|
import com.red.circle.tool.core.date.TimestampUtils;
|
||||||
|
import com.red.circle.tool.core.text.StringUtils;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 团队政策待生效切换任务.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class TeamPolicyActivationTask {
|
||||||
|
|
||||||
|
private final TeamPolicyManagerService teamPolicyManagerService;
|
||||||
|
private final TeamProfileService teamProfileService;
|
||||||
|
private final TeamSalaryMqMessage teamSalaryMqMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每5分钟补偿激活已到生效时间的政策,避免服务短暂不可用导致漏切换.
|
||||||
|
*/
|
||||||
|
@Scheduled(cron = "15 0/5 * * * ?", zone = "Asia/Riyadh")
|
||||||
|
@TaskCacheLock(key = "TEAM_POLICY_ACTIVATION_TASK", expireSecond = 300)
|
||||||
|
public void activateScheduledPolicies() {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
Timestamp now = TimestampUtils.now();
|
||||||
|
List<TeamPolicyManager> policies = teamPolicyManagerService.listDueScheduledPolicies(now);
|
||||||
|
if (CollectionUtils.isEmpty(policies)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> refreshedRegions = new HashSet<>();
|
||||||
|
int activatedCount = 0;
|
||||||
|
for (TeamPolicyManager policy : policies) {
|
||||||
|
TeamPolicyManager activatedPolicy = teamPolicyManagerService.activateScheduledPolicy(policy.getId(), now);
|
||||||
|
if (Objects.isNull(activatedPolicy)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
activatedCount++;
|
||||||
|
String refreshKey = buildRefreshKey(activatedPolicy);
|
||||||
|
if (refreshedRegions.add(refreshKey)) {
|
||||||
|
refreshUnpaidBills(activatedPolicy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("exec team_policy_activation_task activated={}, cost={}",
|
||||||
|
activatedCount, System.currentTimeMillis() - startTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshUnpaidBills(TeamPolicyManager policy) {
|
||||||
|
if (Objects.isNull(policy)
|
||||||
|
|| StringUtils.isBlank(policy.getSysOrigin())
|
||||||
|
|| StringUtils.isBlank(policy.getRegion())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TeamProfile> teamProfiles = Optional.ofNullable(teamProfileService.listRegionAll(policy.getRegion()))
|
||||||
|
.orElse(Lists.newArrayList())
|
||||||
|
.stream()
|
||||||
|
.filter(teamProfile -> Objects.equals(TeamStatus.AVAILABLE, teamProfile.getStatus()))
|
||||||
|
.filter(teamProfile -> Objects.equals(policy.getSysOrigin(), teamProfile.getSysOrigin()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(teamProfiles)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Lists.partition(teamProfiles, 200).forEach(teamList -> teamSalaryMqMessage.sendSalaryCount(
|
||||||
|
teamList.stream().map(TeamProfile::getId).collect(Collectors.toSet())));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildRefreshKey(TeamPolicyManager policy) {
|
||||||
|
return policy.getSysOrigin() + ":" + policy.getRegion();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -51,6 +51,26 @@ public class TeamPolicyManagerCO extends ClientObject {
|
|||||||
*/
|
*/
|
||||||
private Boolean release;
|
private Boolean release;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 政策状态 DRAFT/SCHEDULED/ACTIVE/HISTORY/CANCELLED.
|
||||||
|
*/
|
||||||
|
private String policyStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生效月份 yyyyMM.
|
||||||
|
*/
|
||||||
|
private Integer effectiveMonth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生效时间.
|
||||||
|
*/
|
||||||
|
private java.sql.Timestamp effectiveStartTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实际激活时间.
|
||||||
|
*/
|
||||||
|
private java.sql.Timestamp activatedTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标题.
|
* 标题.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -57,6 +57,26 @@ public class TeamPolicyManager implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private Boolean release;
|
private Boolean release;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 政策状态 DRAFT/SCHEDULED/ACTIVE/HISTORY/CANCELLED.
|
||||||
|
*/
|
||||||
|
private String policyStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生效月份 yyyyMM.
|
||||||
|
*/
|
||||||
|
private Integer effectiveMonth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生效时间.
|
||||||
|
*/
|
||||||
|
private Timestamp effectiveStartTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实际激活时间.
|
||||||
|
*/
|
||||||
|
private Timestamp activatedTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标题.
|
* 标题.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.red.circle.other.infra.database.mongo.service.team.team;
|
package com.red.circle.other.infra.database.mongo.service.team.team;
|
||||||
|
|
||||||
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamPolicyManager;
|
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamPolicyManager;
|
||||||
|
import java.sql.Timestamp;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -79,6 +80,16 @@ public interface TeamPolicyManagerService {
|
|||||||
*/
|
*/
|
||||||
void add(TeamPolicyManager policyManager);
|
void add(TeamPolicyManager policyManager);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询到期的待生效政策.
|
||||||
|
*/
|
||||||
|
List<TeamPolicyManager> listDueScheduledPolicies(Timestamp now);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 激活待生效政策.
|
||||||
|
*/
|
||||||
|
TeamPolicyManager activateScheduledPolicy(Long id, Timestamp now);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除策略.
|
* 删除策略.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
package com.red.circle.other.infra.database.mongo.service.team.team.impl;
|
package com.red.circle.other.infra.database.mongo.service.team.team.impl;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.mongodb.client.result.UpdateResult;
|
||||||
import com.red.circle.other.infra.common.sys.CountryCodeAliasSupport;
|
import com.red.circle.other.infra.common.sys.CountryCodeAliasSupport;
|
||||||
import com.red.circle.other.infra.database.mongo.dto.team.TeamPolicy;
|
import com.red.circle.other.infra.database.mongo.dto.team.TeamPolicy;
|
||||||
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamPolicyManager;
|
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamPolicyManager;
|
||||||
import com.red.circle.other.infra.database.mongo.service.team.team.TeamPolicyManagerService;
|
import com.red.circle.other.infra.database.mongo.service.team.team.TeamPolicyManagerService;
|
||||||
|
import com.red.circle.other.inner.enums.team.TeamPolicyStatusEnum;
|
||||||
import com.red.circle.other.inner.enums.team.TeamPolicyTypeEnum;
|
import com.red.circle.other.inner.enums.team.TeamPolicyTypeEnum;
|
||||||
import com.red.circle.tool.core.collection.CollectionUtils;
|
import com.red.circle.tool.core.collection.CollectionUtils;
|
||||||
import com.red.circle.tool.core.text.StringUtils;
|
import com.red.circle.tool.core.text.StringUtils;
|
||||||
@ -16,6 +18,10 @@ import org.springframework.data.mongodb.core.query.Query;
|
|||||||
import org.springframework.data.mongodb.core.query.Update;
|
import org.springframework.data.mongodb.core.query.Update;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -28,6 +34,10 @@ import java.util.stream.Collectors;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class TeamPolicyManagerServiceImpl implements TeamPolicyManagerService {
|
public class TeamPolicyManagerServiceImpl implements TeamPolicyManagerService {
|
||||||
|
|
||||||
|
private static final ZoneId RIYADH_ZONE = ZoneId.of("Asia/Riyadh");
|
||||||
|
private static final DateTimeFormatter EFFECTIVE_MONTH_FORMATTER =
|
||||||
|
DateTimeFormatter.ofPattern("yyyyMM");
|
||||||
|
|
||||||
private final MongoTemplate mongoTemplate;
|
private final MongoTemplate mongoTemplate;
|
||||||
private final CountryCodeAliasSupport countryCodeAliasSupport;
|
private final CountryCodeAliasSupport countryCodeAliasSupport;
|
||||||
|
|
||||||
@ -72,7 +82,7 @@ public class TeamPolicyManagerServiceImpl implements TeamPolicyManagerService {
|
|||||||
.find(Query.query(Criteria.where("region").is(region)
|
.find(Query.query(Criteria.where("region").is(region)
|
||||||
.and("release").is(Boolean.TRUE)
|
.and("release").is(Boolean.TRUE)
|
||||||
.and("sysOrigin").is(sysOrigin))
|
.and("sysOrigin").is(sysOrigin))
|
||||||
.with(Sort.by(Sort.Order.desc("createTime"))),
|
.with(activePolicySort()),
|
||||||
TeamPolicyManager.class);
|
TeamPolicyManager.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +93,7 @@ public class TeamPolicyManagerServiceImpl implements TeamPolicyManagerService {
|
|||||||
Criteria.where("region").is(region)
|
Criteria.where("region").is(region)
|
||||||
.and("release").is(Boolean.TRUE)
|
.and("release").is(Boolean.TRUE)
|
||||||
.and("sysOrigin").is(sysOrigin)
|
.and("sysOrigin").is(sysOrigin)
|
||||||
), TeamPolicyManager.class);
|
).with(activePolicySort()), TeamPolicyManager.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -102,7 +112,7 @@ public class TeamPolicyManagerServiceImpl implements TeamPolicyManagerService {
|
|||||||
criteria.and("countryCode").in(countryCodeAliasSupport.getMatchCodes(countryCode));
|
criteria.and("countryCode").in(countryCodeAliasSupport.getMatchCodes(countryCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mongoTemplate.findOne(Query.query(criteria), TeamPolicyManager.class);
|
return mongoTemplate.findOne(Query.query(criteria).with(activePolicySort()), TeamPolicyManager.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -113,7 +123,8 @@ public class TeamPolicyManagerServiceImpl implements TeamPolicyManagerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<TeamPolicyManager> teamPolicyManagers = mongoTemplate.find(
|
List<TeamPolicyManager> teamPolicyManagers = mongoTemplate.find(
|
||||||
Query.query(Criteria.where("region").in(regions).and("release").is(Boolean.TRUE)),
|
Query.query(Criteria.where("region").in(regions).and("release").is(Boolean.TRUE))
|
||||||
|
.with(activePolicySort()),
|
||||||
TeamPolicyManager.class);
|
TeamPolicyManager.class);
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(teamPolicyManagers)) {
|
if (CollectionUtils.isEmpty(teamPolicyManagers)) {
|
||||||
@ -121,7 +132,7 @@ public class TeamPolicyManagerServiceImpl implements TeamPolicyManagerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return teamPolicyManagers.stream()
|
return teamPolicyManagers.stream()
|
||||||
.collect(Collectors.toMap(TeamPolicyManager::getRegion, v -> v));
|
.collect(Collectors.toMap(TeamPolicyManager::getRegion, v -> v, (existing, replacement) -> existing));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -134,7 +145,8 @@ public class TeamPolicyManagerServiceImpl implements TeamPolicyManagerService {
|
|||||||
// 查询所有 region 的已发布政策(所有 countryCode)
|
// 查询所有 region 的已发布政策(所有 countryCode)
|
||||||
List<TeamPolicyManager> policies = mongoTemplate.find(
|
List<TeamPolicyManager> policies = mongoTemplate.find(
|
||||||
Query.query(Criteria.where("region").in(regions)
|
Query.query(Criteria.where("region").in(regions)
|
||||||
.and("release").is(Boolean.TRUE)),
|
.and("release").is(Boolean.TRUE))
|
||||||
|
.with(activePolicySort()),
|
||||||
TeamPolicyManager.class);
|
TeamPolicyManager.class);
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(policies)) {
|
if (CollectionUtils.isEmpty(policies)) {
|
||||||
@ -167,25 +179,171 @@ public class TeamPolicyManagerServiceImpl implements TeamPolicyManagerService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(TeamPolicyManager policyManager) {
|
public void add(TeamPolicyManager policyManager) {
|
||||||
policyManager.setHistoryRelease(Boolean.FALSE);
|
Timestamp now = Optional.ofNullable(policyManager.getCreateTime())
|
||||||
|
.orElseGet(() -> new Timestamp(System.currentTimeMillis()));
|
||||||
|
normalizePolicyState(policyManager, now);
|
||||||
|
|
||||||
if (Boolean.TRUE.equals(policyManager.getRelease()) && StringUtils
|
if (Boolean.TRUE.equals(policyManager.getRelease()) && StringUtils.isNotBlank(policyManager.getRegion())
|
||||||
.isNotBlank(policyManager.getRegion())
|
|
||||||
&& StringUtils.isNotBlank(policyManager.getSysOrigin())) {
|
&& StringUtils.isNotBlank(policyManager.getSysOrigin())) {
|
||||||
|
deactivateActivePolicies(policyManager, now);
|
||||||
policyManager.setHistoryRelease(Boolean.TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
policyManager.setPolicy(policyManager.getPolicy().stream()
|
if (CollectionUtils.isNotEmpty(policyManager.getPolicy())) {
|
||||||
.sorted(Comparator.comparing(TeamPolicy::getLevel))
|
policyManager.setPolicy(policyManager.getPolicy().stream()
|
||||||
.collect(Collectors.toList()));
|
.sorted(Comparator.comparing(TeamPolicy::getLevel))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
}
|
||||||
mongoTemplate.save(policyManager);
|
mongoTemplate.save(policyManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TeamPolicyManager> listDueScheduledPolicies(Timestamp now) {
|
||||||
|
return mongoTemplate.find(Query.query(Criteria.where("policyStatus")
|
||||||
|
.is(TeamPolicyStatusEnum.SCHEDULED.name())
|
||||||
|
.and("release").is(Boolean.FALSE)
|
||||||
|
.and("effectiveStartTime").lte(now))
|
||||||
|
.with(Sort.by(Sort.Order.asc("effectiveStartTime"), Sort.Order.asc("createTime"))),
|
||||||
|
TeamPolicyManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TeamPolicyManager activateScheduledPolicy(Long id, Timestamp now) {
|
||||||
|
TeamPolicyManager scheduled = mongoTemplate.findOne(Query.query(Criteria.where("id").is(id)
|
||||||
|
.and("policyStatus").is(TeamPolicyStatusEnum.SCHEDULED.name())
|
||||||
|
.and("release").is(Boolean.FALSE)
|
||||||
|
.and("effectiveStartTime").lte(now)),
|
||||||
|
TeamPolicyManager.class);
|
||||||
|
if (Objects.isNull(scheduled)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
deactivateActivePolicies(scheduled, now);
|
||||||
|
|
||||||
|
Update update = new Update()
|
||||||
|
.set("release", Boolean.TRUE)
|
||||||
|
.set("historyRelease", Boolean.TRUE)
|
||||||
|
.set("policyStatus", TeamPolicyStatusEnum.ACTIVE.name())
|
||||||
|
.set("effectiveMonth", resolveEffectiveMonth(scheduled.getEffectiveStartTime()))
|
||||||
|
.set("activatedTime", now)
|
||||||
|
.set("updateTime", now);
|
||||||
|
|
||||||
|
UpdateResult result = mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(id)
|
||||||
|
.and("policyStatus").is(TeamPolicyStatusEnum.SCHEDULED.name())
|
||||||
|
.and("release").is(Boolean.FALSE)),
|
||||||
|
update,
|
||||||
|
TeamPolicyManager.class);
|
||||||
|
|
||||||
|
if (result.getModifiedCount() <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getById(id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteById(Long id) {
|
public void deleteById(Long id) {
|
||||||
|
|
||||||
mongoTemplate.remove(Query.query(Criteria.where("id").is(id)), TeamPolicyManager.class);
|
mongoTemplate.remove(Query.query(Criteria.where("id").is(id)), TeamPolicyManager.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void normalizePolicyState(TeamPolicyManager policyManager, Timestamp now) {
|
||||||
|
String policyStatus = policyManager.getPolicyStatus();
|
||||||
|
if (StringUtils.isBlank(policyStatus)) {
|
||||||
|
policyStatus = Boolean.TRUE.equals(policyManager.getRelease())
|
||||||
|
? TeamPolicyStatusEnum.ACTIVE.name()
|
||||||
|
: TeamPolicyStatusEnum.DRAFT.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Objects.equals(policyStatus, TeamPolicyStatusEnum.SCHEDULED.name())) {
|
||||||
|
Timestamp effectiveStartTime = Optional.ofNullable(policyManager.getEffectiveStartTime())
|
||||||
|
.orElseGet(this::nextMonthStartTime);
|
||||||
|
policyManager.setPolicyStatus(TeamPolicyStatusEnum.SCHEDULED.name());
|
||||||
|
policyManager.setRelease(Boolean.FALSE);
|
||||||
|
policyManager.setHistoryRelease(Boolean.FALSE);
|
||||||
|
policyManager.setEffectiveStartTime(effectiveStartTime);
|
||||||
|
policyManager.setEffectiveMonth(resolveEffectiveMonth(effectiveStartTime));
|
||||||
|
policyManager.setActivatedTime(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Boolean.TRUE.equals(policyManager.getRelease())
|
||||||
|
|| Objects.equals(policyStatus, TeamPolicyStatusEnum.ACTIVE.name())) {
|
||||||
|
policyManager.setPolicyStatus(TeamPolicyStatusEnum.ACTIVE.name());
|
||||||
|
policyManager.setRelease(Boolean.TRUE);
|
||||||
|
policyManager.setHistoryRelease(Boolean.TRUE);
|
||||||
|
policyManager.setActivatedTime(Optional.ofNullable(policyManager.getActivatedTime()).orElse(now));
|
||||||
|
policyManager.setEffectiveStartTime(Optional.ofNullable(policyManager.getEffectiveStartTime()).orElse(now));
|
||||||
|
policyManager.setEffectiveMonth(Optional.ofNullable(policyManager.getEffectiveMonth())
|
||||||
|
.orElseGet(() -> resolveEffectiveMonth(policyManager.getEffectiveStartTime())));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
policyManager.setPolicyStatus(policyStatus);
|
||||||
|
policyManager.setRelease(Boolean.FALSE);
|
||||||
|
policyManager.setHistoryRelease(Boolean.TRUE.equals(policyManager.getHistoryRelease()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deactivateActivePolicies(TeamPolicyManager policyManager, Timestamp now) {
|
||||||
|
Criteria criteria = samePolicyScopeCriteria(policyManager)
|
||||||
|
.and("release").is(Boolean.TRUE);
|
||||||
|
if (Objects.nonNull(policyManager.getId())) {
|
||||||
|
criteria.and("id").ne(policyManager.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
mongoTemplate.updateMulti(Query.query(criteria), new Update()
|
||||||
|
.set("release", Boolean.FALSE)
|
||||||
|
.set("historyRelease", Boolean.TRUE)
|
||||||
|
.set("policyStatus", TeamPolicyStatusEnum.HISTORY.name())
|
||||||
|
.set("updateTime", now),
|
||||||
|
TeamPolicyManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Criteria samePolicyScopeCriteria(TeamPolicyManager policyManager) {
|
||||||
|
Criteria criteria = Criteria.where("region").is(policyManager.getRegion())
|
||||||
|
.and("sysOrigin").is(policyManager.getSysOrigin());
|
||||||
|
appendPolicyTypeCriteria(criteria, policyManager.getPolicyType());
|
||||||
|
appendCountryScopeCriteria(criteria, policyManager.getCountryCode());
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendPolicyTypeCriteria(Criteria criteria, String policyType) {
|
||||||
|
if (StringUtils.isNotBlank(policyType)
|
||||||
|
&& Objects.equals(policyType, TeamPolicyTypeEnum.SALARY_DIAMOND.name())) {
|
||||||
|
criteria.and("policyType").is(policyType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
criteria.and("policyType").ne(TeamPolicyTypeEnum.SALARY_DIAMOND.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendCountryScopeCriteria(Criteria criteria, String countryCode) {
|
||||||
|
if (StringUtils.isNotBlank(countryCode)) {
|
||||||
|
criteria.and("countryCode").in(countryCodeAliasSupport.getMatchCodes(countryCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
criteria.orOperator(
|
||||||
|
Criteria.where("countryCode").exists(false),
|
||||||
|
Criteria.where("countryCode").is(null),
|
||||||
|
Criteria.where("countryCode").is(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Timestamp nextMonthStartTime() {
|
||||||
|
LocalDate nextMonthFirstDay = LocalDate.now(RIYADH_ZONE).plusMonths(1).withDayOfMonth(1);
|
||||||
|
return Timestamp.from(nextMonthFirstDay.atStartOfDay(RIYADH_ZONE).toInstant());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer resolveEffectiveMonth(Timestamp effectiveStartTime) {
|
||||||
|
if (Objects.isNull(effectiveStartTime)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Integer.valueOf(effectiveStartTime.toInstant()
|
||||||
|
.atZone(RIYADH_ZONE)
|
||||||
|
.format(EFFECTIVE_MONTH_FORMATTER));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Sort activePolicySort() {
|
||||||
|
return Sort.by(
|
||||||
|
Sort.Order.desc("effectiveStartTime"),
|
||||||
|
Sort.Order.desc("activatedTime"),
|
||||||
|
Sort.Order.desc("createTime"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import com.red.circle.other.infra.convertor.team.TeamInfraConvertor;
|
|||||||
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamPolicyManager;
|
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamPolicyManager;
|
||||||
import com.red.circle.other.infra.database.mongo.service.team.team.TeamPolicyManagerService;
|
import com.red.circle.other.infra.database.mongo.service.team.team.TeamPolicyManagerService;
|
||||||
import com.red.circle.other.app.inner.service.team.TeamPolicyManagerClientService;
|
import com.red.circle.other.app.inner.service.team.TeamPolicyManagerClientService;
|
||||||
|
import com.red.circle.other.inner.enums.team.TeamPolicyStatusEnum;
|
||||||
import com.red.circle.other.inner.model.cmd.team.TeamPolicyManagerCmd;
|
import com.red.circle.other.inner.model.cmd.team.TeamPolicyManagerCmd;
|
||||||
import com.red.circle.other.inner.model.dto.agency.agency.TeamPolicyManagerDTO;
|
import com.red.circle.other.inner.model.dto.agency.agency.TeamPolicyManagerDTO;
|
||||||
import com.red.circle.tool.core.sequence.IdWorkerUtils;
|
import com.red.circle.tool.core.sequence.IdWorkerUtils;
|
||||||
@ -71,12 +72,24 @@ public class TeamPolicyManagerClientServiceImpl implements TeamPolicyManagerClie
|
|||||||
@Override
|
@Override
|
||||||
public void add(TeamPolicyManagerCmd cmd) {
|
public void add(TeamPolicyManagerCmd cmd) {
|
||||||
if (Objects.nonNull(cmd.getId())) {
|
if (Objects.nonNull(cmd.getId())) {
|
||||||
teamPolicyManagerService.deleteById(cmd.getId());
|
TeamPolicyManager existingPolicy = teamPolicyManagerService.getById(cmd.getId());
|
||||||
|
if (Objects.nonNull(existingPolicy) && shouldReplaceExistingPolicy(cmd, existingPolicy)) {
|
||||||
|
teamPolicyManagerService.deleteById(cmd.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cmd.setId(IdWorkerUtils.getId());
|
cmd.setId(IdWorkerUtils.getId());
|
||||||
teamPolicyManagerService.add(teamAppConvertor.toTeamPolicyManager(cmd));
|
teamPolicyManagerService.add(teamAppConvertor.toTeamPolicyManager(cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean shouldReplaceExistingPolicy(TeamPolicyManagerCmd cmd, TeamPolicyManager existingPolicy) {
|
||||||
|
if (!Objects.equals(cmd.getPolicyStatus(), TeamPolicyStatusEnum.SCHEDULED.name())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return Objects.equals(existingPolicy.getPolicyStatus(), TeamPolicyStatusEnum.SCHEDULED.name())
|
||||||
|
&& !Boolean.TRUE.equals(existingPolicy.getHistoryRelease())
|
||||||
|
&& !Boolean.TRUE.equals(existingPolicy.getRelease());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteById(Long id) {
|
public void deleteById(Long id) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user