项目总览修改成:当前专业所员工在“专业角色人员分配明细”中参与过的合约规划+当前专业所员工担任项目经理/工程负责人的项目下的合约规划
This commit is contained in:
@@ -600,8 +600,8 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
|||||||
List<ProjectPlanningDO> planningList = getProjectOverviewPlanningList(reportYear, employeeIds);
|
List<ProjectPlanningDO> planningList = getProjectOverviewPlanningList(reportYear, employeeIds);
|
||||||
Map<Long, ProjectDO> projectMap = getProjectMap(planningList);
|
Map<Long, ProjectDO> projectMap = getProjectMap(planningList);
|
||||||
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap = getQuarterMap(planningList);
|
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap = getQuarterMap(planningList);
|
||||||
Map<Long, ProjectOutputSplitDO> outputSplitMap = getOutputSplitMap(planningList);
|
|
||||||
Map<Long, List<SpecialtyRoleSplitRespVO>> roleSplitMap = getRoleSplitMap(planningList);
|
Map<Long, List<SpecialtyRoleSplitRespVO>> roleSplitMap = getRoleSplitMap(planningList);
|
||||||
|
Map<Long, ProjectOutputSplitDO> outputSplitMap = getExistingOutputSplitMap(planningList);
|
||||||
|
|
||||||
Map<Long, ProjectOverviewAccumulator> accumulatorMap = new LinkedHashMap<>();
|
Map<Long, ProjectOverviewAccumulator> accumulatorMap = new LinkedHashMap<>();
|
||||||
for (ProjectPlanningDO planning : planningList) {
|
for (ProjectPlanningDO planning : planningList) {
|
||||||
@@ -945,19 +945,33 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
|||||||
if (reportYear == null || employeeIds == null || employeeIds.isEmpty()) {
|
if (reportYear == null || employeeIds == null || employeeIds.isEmpty()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
Set<Long> yearPlanningIds = getYearAmountPlanningIds(reportYear);
|
Set<Long> candidatePlanningIds = specialtyRoleSplitPersonMapper.selectListByEmployeeIds(employeeIds).stream()
|
||||||
if (yearPlanningIds.isEmpty()) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
List<SpecialtyRoleSplitPersonDO> personList = specialtyRoleSplitPersonMapper
|
|
||||||
.selectListByPlanningIdsAndEmployeeIds(yearPlanningIds, employeeIds);
|
|
||||||
if (personList.isEmpty()) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
Set<Long> matchedPlanningIds = personList.stream()
|
|
||||||
.map(SpecialtyRoleSplitPersonDO::getPlanningId)
|
.map(SpecialtyRoleSplitPersonDO::getPlanningId)
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||||
|
|
||||||
|
Set<Long> projectLeadProjectIds = projectRolePersonMapper.selectListByEmployeeIds(employeeIds).stream()
|
||||||
|
.filter(item -> Objects.equals(item.getRoleCode(), OutputSplitBizConstants.ROLE_PROJECT_MANAGER)
|
||||||
|
|| Objects.equals(item.getRoleCode(), OutputSplitBizConstants.ROLE_ENGINEERING_PRINCIPAL))
|
||||||
|
.map(ProjectRolePersonDO::getProjectId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||||
|
if (!projectLeadProjectIds.isEmpty()) {
|
||||||
|
projectPlanningMapper.selectList(new LambdaQueryWrapperX<ProjectPlanningDO>()
|
||||||
|
.in(ProjectPlanningDO::getProjectId, projectLeadProjectIds)
|
||||||
|
.in(ProjectPlanningDO::getOwnershipType, Arrays.asList(
|
||||||
|
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_MAJOR,
|
||||||
|
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_COMPREHENSIVE,
|
||||||
|
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_SPECIAL_SUBCONTRACT,
|
||||||
|
ProjectPlanningBizTypeConstants.OWNERSHIP_TYPE_SOURCE_COOP_SUBCONTRACT
|
||||||
|
)))
|
||||||
|
.stream()
|
||||||
|
.map(ProjectPlanningDO::getId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.forEach(candidatePlanningIds::add);
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Long> matchedPlanningIds = getYearAmountPlanningIds(reportYear, candidatePlanningIds);
|
||||||
if (matchedPlanningIds.isEmpty()) {
|
if (matchedPlanningIds.isEmpty()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
@@ -1023,6 +1037,42 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
|
|||||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<Long> getYearAmountPlanningIds(Integer reportYear, Collection<Long> planningIds) {
|
||||||
|
if (reportYear == null || planningIds == null || planningIds.isEmpty()) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
Set<Long> result = new LinkedHashSet<>();
|
||||||
|
for (List<Long> partition : partitionIds(planningIds, 1000)) {
|
||||||
|
projectPlanningQuarterMapper.selectList(new LambdaQueryWrapperX<ProjectPlanningQuarterDO>()
|
||||||
|
.in(ProjectPlanningQuarterDO::getPlanningId, partition)
|
||||||
|
.eq(ProjectPlanningQuarterDO::getDistributionYear, reportYear)
|
||||||
|
.gt(ProjectPlanningQuarterDO::getDistributionAmount, BigDecimal.ZERO))
|
||||||
|
.stream()
|
||||||
|
.map(ProjectPlanningQuarterDO::getPlanningId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.forEach(result::add);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<List<Long>> partitionIds(Collection<Long> ids, int partitionSize) {
|
||||||
|
if (ids == null || ids.isEmpty()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
List<Long> normalizedIds = ids.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (normalizedIds.isEmpty()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
List<List<Long>> result = new ArrayList<>();
|
||||||
|
for (int start = 0; start < normalizedIds.size(); start += partitionSize) {
|
||||||
|
result.add(normalizedIds.subList(start, Math.min(start + partitionSize, normalizedIds.size())));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private List<ProjectQuarterOutputExcelBuilder.QuarterRow> buildProjectQuarterOutputRows(
|
private List<ProjectQuarterOutputExcelBuilder.QuarterRow> buildProjectQuarterOutputRows(
|
||||||
List<ProjectPlanningDO> planningList, Map<Long, List<ProjectPlanningQuarterDO>> quarterMap,
|
List<ProjectPlanningDO> planningList, Map<Long, List<ProjectPlanningQuarterDO>> quarterMap,
|
||||||
Map<Long, ProjectOutputSplitDO> outputSplitMap, Integer reportYear) {
|
Map<Long, ProjectOutputSplitDO> outputSplitMap, Integer reportYear) {
|
||||||
|
|||||||
@@ -157,14 +157,17 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
|||||||
item -> item.getSpecialtyCode() + ":" + item.getRoleCode(), item -> item, (a, b) -> b));
|
item -> item.getSpecialtyCode() + ":" + item.getRoleCode(), item -> item, (a, b) -> b));
|
||||||
List<SpecialtyRoleSplitRespVO> result = new ArrayList<>();
|
List<SpecialtyRoleSplitRespVO> result = new ArrayList<>();
|
||||||
BigDecimal assessmentOutputValue = planning.getAssessmentOutputValue();
|
BigDecimal assessmentOutputValue = planning.getAssessmentOutputValue();
|
||||||
|
boolean useDefaultProjectLeadRoleRatio = shouldUseDefaultProjectLeadRoleRatio(dbMap, projectRolePersonMap);
|
||||||
for (OutputSplitBizConstants.SpecialtyItem specialtyItem : OutputSplitBizConstants.ASSIGNMENT_SPECIALTY_ITEMS) {
|
for (OutputSplitBizConstants.SpecialtyItem specialtyItem : OutputSplitBizConstants.ASSIGNMENT_SPECIALTY_ITEMS) {
|
||||||
BigDecimal specialtyAmount = getSpecialtyAmount(outputSplit, assessmentOutputValue, specialtyItem.getCode());
|
BigDecimal specialtyAmount = getSpecialtyAmount(outputSplit, assessmentOutputValue, specialtyItem.getCode());
|
||||||
Map<String, BigDecimal> defaultRoleRatioMap = buildDefaultRoleRatioMap(
|
Map<String, BigDecimal> defaultRoleRatioMap = buildDefaultRoleRatioMap(
|
||||||
specialtyItem.getCode(), projectRolePersonMap);
|
specialtyItem.getCode(), projectRolePersonMap);
|
||||||
for (OutputSplitBizConstants.RoleItem roleItem : OutputSplitBizConstants.getRoleItems(specialtyItem.getCode())) {
|
for (OutputSplitBizConstants.RoleItem roleItem : OutputSplitBizConstants.getRoleItems(specialtyItem.getCode())) {
|
||||||
SpecialtyRoleSplitDO dbItem = dbMap.get(specialtyItem.getCode() + ":" + roleItem.getCode());
|
SpecialtyRoleSplitDO dbItem = dbMap.get(specialtyItem.getCode() + ":" + roleItem.getCode());
|
||||||
BigDecimal roleRatio = getStoredRoleRatio(
|
BigDecimal roleRatio = useDefaultProjectLeadRoleRatio
|
||||||
dbItem, specialtyItem.getCode(), roleItem.getCode(), defaultRoleRatioMap);
|
&& OutputSplitBizConstants.SPECIALTY_PROJECT_LEAD.equals(specialtyItem.getCode())
|
||||||
|
? ratio(defaultRoleRatioMap.get(roleItem.getCode()))
|
||||||
|
: getStoredRoleRatio(dbItem, specialtyItem.getCode(), roleItem.getCode(), defaultRoleRatioMap);
|
||||||
BigDecimal roleAmount = multiplyAmount(specialtyAmount, roleRatio);
|
BigDecimal roleAmount = multiplyAmount(specialtyAmount, roleRatio);
|
||||||
List<SpecialtyRolePersonRespVO> persons = buildRespPersons(
|
List<SpecialtyRolePersonRespVO> persons = buildRespPersons(
|
||||||
dbItem, specialtyItem.getCode(), roleItem.getCode(), roleAmount, projectRolePersonMap, personMap);
|
dbItem, specialtyItem.getCode(), roleItem.getCode(), roleAmount, projectRolePersonMap, personMap);
|
||||||
@@ -193,6 +196,33 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean shouldUseDefaultProjectLeadRoleRatio(Map<String, SpecialtyRoleSplitDO> dbMap,
|
||||||
|
Map<String, List<ProjectRolePersonDO>> projectRolePersonMap) {
|
||||||
|
if (projectRolePersonMap == null || projectRolePersonMap.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
boolean hasProjectLeadPerson = (projectRolePersonMap.get(OutputSplitBizConstants.ROLE_PROJECT_MANAGER) != null
|
||||||
|
&& !projectRolePersonMap.get(OutputSplitBizConstants.ROLE_PROJECT_MANAGER).isEmpty())
|
||||||
|
|| (projectRolePersonMap.get(OutputSplitBizConstants.ROLE_ENGINEERING_PRINCIPAL) != null
|
||||||
|
&& !projectRolePersonMap.get(OutputSplitBizConstants.ROLE_ENGINEERING_PRINCIPAL).isEmpty());
|
||||||
|
if (!hasProjectLeadPerson || dbMap == null || dbMap.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
BigDecimal storedTotal = ZERO_RATIO;
|
||||||
|
boolean hasStoredProjectLead = false;
|
||||||
|
for (String roleCode : Arrays.asList(
|
||||||
|
OutputSplitBizConstants.ROLE_PROJECT_MANAGER,
|
||||||
|
OutputSplitBizConstants.ROLE_ENGINEERING_PRINCIPAL)) {
|
||||||
|
SpecialtyRoleSplitDO dbItem = dbMap.get(OutputSplitBizConstants.SPECIALTY_PROJECT_LEAD + ":" + roleCode);
|
||||||
|
if (dbItem == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
hasStoredProjectLead = true;
|
||||||
|
storedTotal = storedTotal.add(ratio(dbItem.getRoleRatio())).setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||||
|
}
|
||||||
|
return hasStoredProjectLead && storedTotal.compareTo(ZERO_RATIO) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void saveSpecialtyRoleSplitBatch(SpecialtyRoleSplitBatchSaveReqVO reqVO) {
|
public void saveSpecialtyRoleSplitBatch(SpecialtyRoleSplitBatchSaveReqVO reqVO) {
|
||||||
@@ -217,6 +247,9 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
|||||||
BigDecimal assessmentOutputValue,
|
BigDecimal assessmentOutputValue,
|
||||||
boolean strictValidate) {
|
boolean strictValidate) {
|
||||||
for (OutputSplitBizConstants.SpecialtyItem specialtyItem : OutputSplitBizConstants.ASSIGNMENT_SPECIALTY_ITEMS) {
|
for (OutputSplitBizConstants.SpecialtyItem specialtyItem : OutputSplitBizConstants.ASSIGNMENT_SPECIALTY_ITEMS) {
|
||||||
|
if (!groupedMap.containsKey(specialtyItem.getCode())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Map<String, SpecialtyRoleSplitSaveItemReqVO> roleMap = groupedMap.getOrDefault(
|
Map<String, SpecialtyRoleSplitSaveItemReqVO> roleMap = groupedMap.getOrDefault(
|
||||||
specialtyItem.getCode(), new LinkedHashMap<>());
|
specialtyItem.getCode(), new LinkedHashMap<>());
|
||||||
BigDecimal roleTotal = ZERO_RATIO;
|
BigDecimal roleTotal = ZERO_RATIO;
|
||||||
|
|||||||
Reference in New Issue
Block a user