Compare commits
12 Commits
1d26048bc1
...
masterlzm
| Author | SHA1 | Date | |
|---|---|---|---|
| 33c5fe89b6 | |||
| ac3b1050cb | |||
| 559f92e850 | |||
| a29ebce743 | |||
| 2401a27fa7 | |||
| 6c6c02ae59 | |||
| 8898c95caa | |||
| b7b23f7613 | |||
| 62b83546a1 | |||
| 6b2b91249a | |||
| bac721f5c4 | |||
| c496f00fd2 |
@@ -74,8 +74,9 @@ public class EmployeeController {
|
||||
@RequestParam(value = "keyword", required = false) String keyword,
|
||||
@RequestParam(value = "officeId", required = false) Long officeId,
|
||||
@RequestParam(value = "status", required = false) String status,
|
||||
@RequestParam(value = "enabledFlag", required = false) Boolean enabledFlag) {
|
||||
return success(employeeService.getEmployeeSimpleList(keyword, officeId, status, enabledFlag));
|
||||
@RequestParam(value = "enabledFlag", required = false) Boolean enabledFlag,
|
||||
@RequestParam(value = "officeLeaderFlag", required = false) Boolean officeLeaderFlag) {
|
||||
return success(employeeService.getEmployeeSimpleList(keyword, officeId, status, enabledFlag, officeLeaderFlag));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,4 +22,7 @@ public class EmployeePageReqVO extends PageParam {
|
||||
@Schema(description = "是否启用", example = "true")
|
||||
private Boolean enabledFlag;
|
||||
|
||||
@Schema(description = "是否所长", example = "false")
|
||||
private Boolean officeLeaderFlag;
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +46,9 @@ public class EmployeeRespVO {
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "是否所长")
|
||||
private Boolean officeLeaderFlag;
|
||||
|
||||
@Schema(description = "排序号")
|
||||
private Integer sortNo;
|
||||
|
||||
|
||||
@@ -64,6 +64,9 @@ public class EmployeeSaveReqVO {
|
||||
@Size(max = 255, message = "备注长度不能超过 255 个字符")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "是否所长", example = "false")
|
||||
private Boolean officeLeaderFlag;
|
||||
|
||||
@Schema(description = "排序号", example = "1")
|
||||
private Integer sortNo;
|
||||
|
||||
|
||||
@@ -28,4 +28,7 @@ public class EmployeeSimpleRespVO {
|
||||
@Schema(description = "职称")
|
||||
private String jobTitle;
|
||||
|
||||
@Schema(description = "是否所长")
|
||||
private Boolean officeLeaderFlag;
|
||||
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetPageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.*;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.employeeyearcostbudget.EmployeeYearCostBudgetService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -34,6 +32,14 @@ public class EmployeeYearCostBudgetController {
|
||||
return success(employeeYearCostBudgetService.createEmployeeYearCostBudget(createReqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/generate")
|
||||
@Operation(summary = "按年度生成员工年度成本预算")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-cost-budget:create')")
|
||||
public CommonResult<EmployeeYearCostBudgetGenerateRespVO> generateEmployeeYearCostBudget(
|
||||
@Valid @RequestBody EmployeeYearCostBudgetGenerateReqVO generateReqVO) {
|
||||
return success(employeeYearCostBudgetService.generateEmployeeYearCostBudget(generateReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "修改员工年度成本预算")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-cost-budget:update')")
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.DecimalMin;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - 员工年度成本预算按年度生成 Request VO")
|
||||
@Data
|
||||
public class EmployeeYearCostBudgetGenerateReqVO {
|
||||
|
||||
@Schema(description = "预算年度", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026")
|
||||
@NotNull(message = "预算年度不能为空")
|
||||
private Integer budgetYear;
|
||||
|
||||
@Schema(description = "默认预计发生成本", example = "0")
|
||||
@DecimalMin(value = "0", message = "默认预计发生成本不能小于 0")
|
||||
private BigDecimal expectedCostAmount;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 员工年度成本预算按年度生成 Response VO")
|
||||
@Data
|
||||
public class EmployeeYearCostBudgetGenerateRespVO {
|
||||
|
||||
@Schema(description = "预算年度")
|
||||
private Integer budgetYear;
|
||||
|
||||
@Schema(description = "已启用员工数量")
|
||||
private Integer totalEnabledEmployeeCount;
|
||||
|
||||
@Schema(description = "本次新增预算记录数量")
|
||||
private Integer createdCount;
|
||||
|
||||
@Schema(description = "已存在并跳过的预算记录数量")
|
||||
private Integer skippedCount;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo.*;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.employeeyearleaderoutput.EmployeeYearLeaderOutputService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 年度所长考核产值")
|
||||
@RestController
|
||||
@RequestMapping("/tjt/employee-year-leader-output")
|
||||
@Validated
|
||||
public class EmployeeYearLeaderOutputController {
|
||||
|
||||
@Resource
|
||||
private EmployeeYearLeaderOutputService employeeYearLeaderOutputService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建年度所长考核产值")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-leader-output:create')")
|
||||
public CommonResult<Long> createEmployeeYearLeaderOutput(
|
||||
@Valid @RequestBody EmployeeYearLeaderOutputSaveReqVO createReqVO) {
|
||||
return success(employeeYearLeaderOutputService.createEmployeeYearLeaderOutput(createReqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/generate")
|
||||
@Operation(summary = "按年度生成年度所长考核产值")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-leader-output:create')")
|
||||
public CommonResult<EmployeeYearLeaderOutputGenerateRespVO> generateEmployeeYearLeaderOutput(
|
||||
@Valid @RequestBody EmployeeYearLeaderOutputGenerateReqVO generateReqVO) {
|
||||
return success(employeeYearLeaderOutputService.generateEmployeeYearLeaderOutput(generateReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "修改年度所长考核产值")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-leader-output:update')")
|
||||
public CommonResult<Boolean> updateEmployeeYearLeaderOutput(
|
||||
@Valid @RequestBody EmployeeYearLeaderOutputSaveReqVO updateReqVO) {
|
||||
employeeYearLeaderOutputService.updateEmployeeYearLeaderOutput(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除年度所长考核产值")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-leader-output:delete')")
|
||||
public CommonResult<Boolean> deleteEmployeeYearLeaderOutput(@RequestParam("id") Long id) {
|
||||
employeeYearLeaderOutputService.deleteEmployeeYearLeaderOutput(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得年度所长考核产值详情")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-leader-output:query')")
|
||||
public CommonResult<EmployeeYearLeaderOutputRespVO> getEmployeeYearLeaderOutput(@RequestParam("id") Long id) {
|
||||
return success(employeeYearLeaderOutputService.getEmployeeYearLeaderOutput(id));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得年度所长考核产值分页")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:employee-year-leader-output:query')")
|
||||
public CommonResult<PageResult<EmployeeYearLeaderOutputRespVO>> getEmployeeYearLeaderOutputPage(
|
||||
@Valid EmployeeYearLeaderOutputPageReqVO pageReqVO) {
|
||||
return success(employeeYearLeaderOutputService.getEmployeeYearLeaderOutputPage(pageReqVO));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.DecimalMin;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - 年度所长考核产值按年度生成 Request VO")
|
||||
@Data
|
||||
public class EmployeeYearLeaderOutputGenerateReqVO {
|
||||
|
||||
@Schema(description = "产值年度", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026")
|
||||
@NotNull(message = "产值年度不能为空")
|
||||
private Integer outputYear;
|
||||
|
||||
@Schema(description = "默认所长考核产值", example = "0")
|
||||
@DecimalMin(value = "0", message = "默认所长考核产值不能小于 0")
|
||||
private BigDecimal leaderOutputAmount;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 年度所长考核产值按年度生成 Response VO")
|
||||
@Data
|
||||
public class EmployeeYearLeaderOutputGenerateRespVO {
|
||||
|
||||
@Schema(description = "产值年度")
|
||||
private Integer outputYear;
|
||||
|
||||
@Schema(description = "已启用所长数量")
|
||||
private Integer totalEnabledLeaderCount;
|
||||
|
||||
@Schema(description = "本次新增记录数量")
|
||||
private Integer createdCount;
|
||||
|
||||
@Schema(description = "已存在并跳过的记录数量")
|
||||
private Integer skippedCount;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Schema(description = "管理后台 - 年度所长考核产值分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class EmployeeYearLeaderOutputPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "员工 ID", example = "1")
|
||||
private Long employeeId;
|
||||
|
||||
@Schema(description = "员工姓名", example = "张")
|
||||
private String employeeName;
|
||||
|
||||
@Schema(description = "产值年度", example = "2026")
|
||||
private Integer outputYear;
|
||||
|
||||
@Schema(description = "是否启用", example = "true")
|
||||
private Boolean enabledFlag;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 年度所长考核产值 Response VO")
|
||||
@Data
|
||||
public class EmployeeYearLeaderOutputRespVO {
|
||||
|
||||
@Schema(description = "记录 ID", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "员工 ID")
|
||||
private Long employeeId;
|
||||
|
||||
@Schema(description = "员工姓名")
|
||||
private String employeeName;
|
||||
|
||||
@Schema(description = "产值年度")
|
||||
private Integer outputYear;
|
||||
|
||||
@Schema(description = "所长考核产值")
|
||||
private BigDecimal leaderOutputAmount;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "排序号")
|
||||
private Integer sortNo;
|
||||
|
||||
@Schema(description = "是否启用")
|
||||
private Boolean enabledFlag;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - 年度所长考核产值新增/修改 Request VO")
|
||||
@Data
|
||||
public class EmployeeYearLeaderOutputSaveReqVO {
|
||||
|
||||
@Schema(description = "记录 ID", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "员工 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "员工 ID 不能为空")
|
||||
private Long employeeId;
|
||||
|
||||
@Schema(description = "员工姓名,后端根据 employeeId 回填", example = "张三")
|
||||
@Size(max = 64, message = "员工姓名长度不能超过 64 个字符")
|
||||
private String employeeName;
|
||||
|
||||
@Schema(description = "产值年度", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026")
|
||||
@NotNull(message = "产值年度不能为空")
|
||||
private Integer outputYear;
|
||||
|
||||
@Schema(description = "所长考核产值", requiredMode = Schema.RequiredMode.REQUIRED, example = "100000")
|
||||
@NotNull(message = "所长考核产值不能为空")
|
||||
private BigDecimal leaderOutputAmount;
|
||||
|
||||
@Schema(description = "备注")
|
||||
@Size(max = 255, message = "备注长度不能超过 255 个字符")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "排序号", example = "1")
|
||||
private Integer sortNo;
|
||||
|
||||
@Schema(description = "是否启用", example = "true")
|
||||
private Boolean enabledFlag;
|
||||
|
||||
}
|
||||
@@ -1,9 +1,17 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.outputsplit;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.outputsplit.vo.ProjectOutputSplitPlanningDetailRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.outputsplit.vo.ProjectOutputSplitRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.outputsplit.vo.ProjectOutputSplitSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planning.ProjectPlanningDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningquarter.ProjectPlanningQuarterDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.outputsplit.ProjectOutputSplitService;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.planning.ProjectPlanningService;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.planningquarter.ProjectPlanningQuarterService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -13,6 +21,14 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@@ -22,8 +38,17 @@ import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success;
|
||||
@Validated
|
||||
public class ProjectOutputSplitController {
|
||||
|
||||
private static final int AMOUNT_SCALE = 2;
|
||||
private static final int RATIO_SCALE = 4;
|
||||
private static final BigDecimal ZERO_AMOUNT = BigDecimal.ZERO.setScale(AMOUNT_SCALE, RoundingMode.HALF_UP);
|
||||
private static final BigDecimal ZERO_RATIO = BigDecimal.ZERO.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
|
||||
@Resource
|
||||
private ProjectOutputSplitService projectOutputSplitService;
|
||||
@Resource
|
||||
private ProjectPlanningService projectPlanningService;
|
||||
@Resource
|
||||
private ProjectPlanningQuarterService projectPlanningQuarterService;
|
||||
|
||||
@GetMapping("/get-by-planning")
|
||||
@Operation(summary = "根据合约规划获得页面4拆分比例")
|
||||
@@ -33,6 +58,29 @@ public class ProjectOutputSplitController {
|
||||
return success(projectOutputSplitService.getProjectOutputSplit(planningId));
|
||||
}
|
||||
|
||||
@GetMapping("/planning-detail")
|
||||
@Operation(summary = "获得页面4合约规划分配聚合详情")
|
||||
@Parameter(name = "planningId", description = "合约规划 ID", required = true, example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:planning:query') && @ss.hasPermission('tjt:output-split:query') && @ss.hasPermission('tjt:planning-quarter:query')")
|
||||
public CommonResult<ProjectOutputSplitPlanningDetailRespVO> getProjectOutputSplitPlanningDetail(
|
||||
@RequestParam("planningId") Long planningId) {
|
||||
ProjectPlanningDO planning = projectPlanningService.getProjectPlanning(planningId);
|
||||
if (planning == null) {
|
||||
return success(null);
|
||||
}
|
||||
ProjectOutputSplitPlanningDetailRespVO respVO = new ProjectOutputSplitPlanningDetailRespVO();
|
||||
Map<Long, BigDecimal> allocatedAmountMap =
|
||||
projectPlanningService.getAllocatedAmountMap(Collections.singleton(planningId));
|
||||
respVO.setPlanning(BeanUtils.toBean(planning, ProjectPlanningRespVO.class,
|
||||
planningRespVO -> fillDistributionSummary(planningRespVO, allocatedAmountMap)));
|
||||
respVO.setOutputSplit(projectOutputSplitService.getProjectOutputSplit(planningId));
|
||||
|
||||
List<ProjectPlanningQuarterDO> quarterList =
|
||||
projectPlanningQuarterService.getProjectPlanningQuarterListByPlanningId(planningId);
|
||||
respVO.setQuarters(buildPlanningQuarterRespList(planning, quarterList));
|
||||
return success(respVO);
|
||||
}
|
||||
|
||||
@PutMapping("/save")
|
||||
@Operation(summary = "保存页面4拆分比例")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:output-split:update')")
|
||||
@@ -40,4 +88,72 @@ public class ProjectOutputSplitController {
|
||||
return success(projectOutputSplitService.saveProjectOutputSplit(reqVO));
|
||||
}
|
||||
|
||||
private void fillDistributionSummary(ProjectPlanningRespVO respVO, Map<Long, BigDecimal> allocatedAmountMap) {
|
||||
BigDecimal allocatedRatio = allocatedAmountMap.getOrDefault(respVO.getId(), ZERO_RATIO);
|
||||
BigDecimal totalDistributionAmount = respVO.getTotalDistributionAmount() == null
|
||||
? ZERO_RATIO : respVO.getTotalDistributionAmount().setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
BigDecimal allocatedAmount = totalDistributionAmount.multiply(allocatedRatio)
|
||||
.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
respVO.setAllocatedAmount(allocatedAmount);
|
||||
respVO.setPendingAmount(totalDistributionAmount.subtract(allocatedAmount)
|
||||
.setScale(RATIO_SCALE, RoundingMode.HALF_UP));
|
||||
}
|
||||
|
||||
private List<ProjectPlanningQuarterRespVO> buildPlanningQuarterRespList(
|
||||
ProjectPlanningDO planning, List<ProjectPlanningQuarterDO> quarterList) {
|
||||
if (quarterList == null || quarterList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
boolean hasGuideDetailQuarter = quarterList.stream().anyMatch(item -> item.getGuideDetailId() != null);
|
||||
if (!hasGuideDetailQuarter) {
|
||||
return BeanUtils.toBean(quarterList, ProjectPlanningQuarterRespVO.class);
|
||||
}
|
||||
BigDecimal baseAmount = amount(planning.getAssessmentOutputValue())
|
||||
.multiply(ratio(planning.getTotalDistributionAmount()))
|
||||
.setScale(AMOUNT_SCALE, RoundingMode.HALF_UP);
|
||||
Map<String, ProjectPlanningQuarterRespVO> aggregateMap = new LinkedHashMap<>();
|
||||
for (ProjectPlanningQuarterDO quarter : quarterList) {
|
||||
if (quarter.getGuideDetailId() == null) {
|
||||
continue;
|
||||
}
|
||||
String key = quarter.getDistributionYear() + "_" + quarter.getQuarterNo();
|
||||
ProjectPlanningQuarterRespVO aggregate = aggregateMap.computeIfAbsent(key, ignored -> {
|
||||
ProjectPlanningQuarterRespVO item = new ProjectPlanningQuarterRespVO();
|
||||
item.setPlanningId(planning.getId());
|
||||
item.setDistributionYear(quarter.getDistributionYear());
|
||||
item.setQuarterNo(quarter.getQuarterNo());
|
||||
item.setDistributionAmount(ZERO_AMOUNT);
|
||||
item.setDistributionRatio(ZERO_RATIO);
|
||||
return item;
|
||||
});
|
||||
BigDecimal distributionAmount = amount(aggregate.getDistributionAmount())
|
||||
.add(amount(quarter.getDistributionAmount()))
|
||||
.setScale(AMOUNT_SCALE, RoundingMode.HALF_UP);
|
||||
aggregate.setDistributionAmount(distributionAmount);
|
||||
aggregate.setDistributionRatio(amountToDistributionRatio(distributionAmount, baseAmount));
|
||||
}
|
||||
List<ProjectPlanningQuarterRespVO> result = new ArrayList<>(aggregateMap.values());
|
||||
result.sort(Comparator
|
||||
.comparing(ProjectPlanningQuarterRespVO::getDistributionYear,
|
||||
Comparator.nullsLast(Integer::compareTo))
|
||||
.thenComparing(ProjectPlanningQuarterRespVO::getQuarterNo,
|
||||
Comparator.nullsLast(Integer::compareTo)));
|
||||
return result;
|
||||
}
|
||||
|
||||
private BigDecimal amountToDistributionRatio(BigDecimal amount, BigDecimal baseAmount) {
|
||||
if (baseAmount == null || baseAmount.compareTo(BigDecimal.ZERO) == 0) {
|
||||
return ZERO_RATIO;
|
||||
}
|
||||
return amount(amount).divide(baseAmount, RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private BigDecimal amount(BigDecimal value) {
|
||||
return value == null ? ZERO_AMOUNT : value.setScale(AMOUNT_SCALE, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private BigDecimal ratio(BigDecimal value) {
|
||||
return value == null ? ZERO_RATIO : value.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.outputsplit.vo;
|
||||
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterRespVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 页面4合约规划分配聚合详情 Response VO")
|
||||
@Data
|
||||
public class ProjectOutputSplitPlanningDetailRespVO {
|
||||
|
||||
@Schema(description = "合约规划详情")
|
||||
private ProjectPlanningRespVO planning;
|
||||
|
||||
@Schema(description = "页面4拆分比例")
|
||||
private ProjectOutputSplitRespVO outputSplit;
|
||||
|
||||
@Schema(description = "季度分配列表")
|
||||
private List<ProjectPlanningQuarterRespVO> quarters = Collections.emptyList();
|
||||
|
||||
}
|
||||
@@ -4,11 +4,16 @@ import cn.iocoder.lyzsys.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningOutputEditDetailRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningPageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningguidedetail.vo.ProjectPlanningGuideDetailRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planning.ProjectPlanningDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningguidedetail.ProjectPlanningGuideDetailDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.enums.ProjectPlanningBizTypeConstants;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.planning.ProjectPlanningService;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.planningguidedetail.ProjectPlanningGuideDetailService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -37,6 +42,8 @@ public class ProjectPlanningController {
|
||||
|
||||
@Resource
|
||||
private ProjectPlanningService projectPlanningService;
|
||||
@Resource
|
||||
private ProjectPlanningGuideDetailService projectPlanningGuideDetailService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建合约规划")
|
||||
@@ -97,6 +104,30 @@ public class ProjectPlanningController {
|
||||
respVO -> fillDistributionSummary(respVO, allocatedAmountMap)));
|
||||
}
|
||||
|
||||
@GetMapping("/output-edit-detail")
|
||||
@Operation(summary = "获得合约规划测算参数编辑详情")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:planning:query')")
|
||||
public CommonResult<ProjectPlanningOutputEditDetailRespVO> getProjectPlanningOutputEditDetail(@RequestParam("id") Long id) {
|
||||
ProjectPlanningDO planning = projectPlanningService.getProjectPlanning(id);
|
||||
if (planning == null) {
|
||||
return success(null);
|
||||
}
|
||||
|
||||
Map<Long, BigDecimal> allocatedAmountMap = projectPlanningService.getAllocatedAmountMap(
|
||||
Collections.singleton(planning.getId()));
|
||||
ProjectPlanningOutputEditDetailRespVO respVO = new ProjectPlanningOutputEditDetailRespVO();
|
||||
respVO.setPlanning(BeanUtils.toBean(planning, ProjectPlanningRespVO.class,
|
||||
planningRespVO -> fillDistributionSummary(planningRespVO, allocatedAmountMap)));
|
||||
if (ProjectPlanningBizTypeConstants.isMajorGuidanceScene(
|
||||
planning.getOwnershipType(), planning.getCalculationMethod())) {
|
||||
List<ProjectPlanningGuideDetailDO> guideDetails =
|
||||
projectPlanningGuideDetailService.getProjectPlanningGuideDetailListByPlanningId(id);
|
||||
respVO.setGuideDetails(BeanUtils.toBean(guideDetails, ProjectPlanningGuideDetailRespVO.class));
|
||||
}
|
||||
return success(respVO);
|
||||
}
|
||||
|
||||
@GetMapping("/list-by-project")
|
||||
@Operation(summary = "根据项目获得合约规划列表")
|
||||
@Parameter(name = "projectId", description = "项目 ID", required = true, example = "1")
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo;
|
||||
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningguidedetail.vo.ProjectPlanningGuideDetailRespVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 合约规划测算参数编辑聚合详情 Response VO")
|
||||
@Data
|
||||
public class ProjectPlanningOutputEditDetailRespVO {
|
||||
|
||||
@Schema(description = "合约规划详情")
|
||||
private ProjectPlanningRespVO planning;
|
||||
|
||||
@Schema(description = "指导价法明细列表,仅专业所 + 指导价法场景返回")
|
||||
private List<ProjectPlanningGuideDetailRespVO> guideDetails = Collections.emptyList();
|
||||
|
||||
}
|
||||
@@ -18,10 +18,10 @@ public class ProjectPlanningPageReqVO extends PageParam {
|
||||
@Schema(description = "项目 ID", example = "1")
|
||||
private Long projectId;
|
||||
|
||||
@Schema(description = "归属类型", example = "专业所")
|
||||
@Schema(description = "归属类型", example = "major")
|
||||
private String ownershipType;
|
||||
|
||||
@Schema(description = "产值计算方式", example = "指导价法")
|
||||
@Schema(description = "产值计算方式", example = "guidance_price")
|
||||
private String calculationMethod;
|
||||
|
||||
@Schema(description = "项目任务包,模糊匹配", example = "建筑")
|
||||
|
||||
@@ -17,7 +17,7 @@ public class ProjectPlanningRespVO {
|
||||
private Long projectId;
|
||||
|
||||
@Schema(description = "排序")
|
||||
private Integer sortNo;
|
||||
private String sortNo;
|
||||
|
||||
@Schema(description = "归属类型")
|
||||
private String ownershipType;
|
||||
|
||||
@@ -21,15 +21,16 @@ public class ProjectPlanningSaveReqVO {
|
||||
@NotNull(message = "项目 ID 不能为空")
|
||||
private Long projectId;
|
||||
|
||||
@Schema(description = "排序", example = "0")
|
||||
private Integer sortNo;
|
||||
@Schema(description = "排序", example = "A-01")
|
||||
@Size(max = 50, message = "排序长度不能超过 50 个字符")
|
||||
private String sortNo;
|
||||
|
||||
@Schema(description = "归属类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "专业所")
|
||||
@Schema(description = "归属类型:major/comprehensive/special_subcontract_major/special_subcontract_source_coop/special_subcontract_comprehensive", requiredMode = Schema.RequiredMode.REQUIRED, example = "major")
|
||||
@NotBlank(message = "归属类型不能为空")
|
||||
@Size(max = 20, message = "归属类型长度不能超过 20 个字符")
|
||||
@Size(max = 64, message = "归属类型长度不能超过 64 个字符")
|
||||
private String ownershipType;
|
||||
|
||||
@Schema(description = "产值计算方式,页面 2 维护", example = "指导价法")
|
||||
@Schema(description = "产值计算方式:guidance_price/contract_price/virtual_output,页面 2 维护", example = "guidance_price")
|
||||
@Size(max = 30, message = "产值计算方式长度不能超过 30 个字符")
|
||||
private String calculationMethod;
|
||||
|
||||
@@ -73,7 +74,7 @@ public class ProjectPlanningSaveReqVO {
|
||||
@Schema(description = "面积", example = "30000")
|
||||
private BigDecimal planningArea;
|
||||
|
||||
@Schema(description = "设计阶段", example = "方案设计")
|
||||
@Schema(description = "设计阶段:scheme/construction_drawing/scheme_and_construction_drawing", example = "scheme")
|
||||
@Size(max = 50, message = "设计阶段长度不能超过 50 个字符")
|
||||
private String designStage;
|
||||
|
||||
@@ -119,7 +120,7 @@ public class ProjectPlanningSaveReqVO {
|
||||
@Schema(description = "内部指导单价(元/m²)", example = "80.00")
|
||||
private BigDecimal internalGuidanceUnitPrice;
|
||||
|
||||
@Schema(description = "虚拟产值计算方式:指导单价法/指导总价法/工日法", example = "工日法")
|
||||
@Schema(description = "虚拟产值计算方式:guidance_price/guidance_total_price/working_day", example = "working_day")
|
||||
@Size(max = 30, message = "虚拟产值计算方式长度不能超过 30 个字符")
|
||||
private String virtualCalculationMethod;
|
||||
|
||||
@@ -140,4 +141,8 @@ public class ProjectPlanningSaveReqVO {
|
||||
@DecimalMax(value = "1.0000", message = "calculationRatio must be <= 1")
|
||||
private BigDecimal calculationRatio;
|
||||
|
||||
@Schema(description = "合同单价(元/m²),为空时系统按分项合同产值 / 面积计算", example = "120.00")
|
||||
@DecimalMin(value = "0.0000", message = "contractUnitPrice must be >= 0")
|
||||
private BigDecimal contractUnitPrice;
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public class ProjectPlanningGuideDetailRespVO {
|
||||
@Schema(description = "设计部位")
|
||||
private String designPart;
|
||||
|
||||
@Schema(description = "建筑类型")
|
||||
@Schema(description = "设计内容/设计类型")
|
||||
private String buildingType;
|
||||
|
||||
@Schema(description = "设计面积")
|
||||
|
||||
@@ -17,14 +17,14 @@ public class ProjectPlanningGuideDetailSaveReqVO {
|
||||
@Schema(description = "明细 ID", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "设计部位", requiredMode = Schema.RequiredMode.REQUIRED, example = "地上部分")
|
||||
@Schema(description = "设计部位:above_ground/underground/other", requiredMode = Schema.RequiredMode.REQUIRED, example = "above_ground")
|
||||
@NotBlank(message = "设计部位不能为空")
|
||||
@Size(max = 20, message = "设计部位长度不能超过 20 个字符")
|
||||
private String designPart;
|
||||
|
||||
@Schema(description = "建筑类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "住宅")
|
||||
@NotBlank(message = "建筑类型不能为空")
|
||||
@Size(max = 100, message = "建筑类型长度不能超过 100 个字符")
|
||||
@Schema(description = "设计内容/设计类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "住宅")
|
||||
@NotBlank(message = "设计内容/设计类型不能为空")
|
||||
@Size(max = 100, message = "设计内容/设计类型长度不能超过 100 个字符")
|
||||
private String buildingType;
|
||||
|
||||
@Schema(description = "设计面积", requiredMode = Schema.RequiredMode.REQUIRED, example = "12000")
|
||||
|
||||
@@ -2,9 +2,17 @@ package cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterGuideDetailRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterPlanningDetailRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planning.ProjectPlanningDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningguidedetail.ProjectPlanningGuideDetailDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningquarter.ProjectPlanningQuarterDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.enums.ProjectPlanningBizTypeConstants;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.planning.ProjectPlanningService;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.planningguidedetail.ProjectPlanningGuideDetailService;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.planningquarter.ProjectPlanningQuarterService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -15,7 +23,14 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@@ -25,8 +40,15 @@ import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success;
|
||||
@Validated
|
||||
public class ProjectPlanningQuarterController {
|
||||
|
||||
private static final int RATIO_SCALE = 4;
|
||||
private static final BigDecimal ZERO_RATIO = BigDecimal.ZERO.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
|
||||
@Resource
|
||||
private ProjectPlanningQuarterService projectPlanningQuarterService;
|
||||
@Resource
|
||||
private ProjectPlanningService projectPlanningService;
|
||||
@Resource
|
||||
private ProjectPlanningGuideDetailService projectPlanningGuideDetailService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建季度分配")
|
||||
@@ -80,4 +102,109 @@ public class ProjectPlanningQuarterController {
|
||||
return success(BeanUtils.toBean(list, ProjectPlanningQuarterRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/planning-detail")
|
||||
@Operation(summary = "获得合约规划详情及季度分配列表")
|
||||
@Parameter(name = "planningId", description = "合约规划 ID", required = true, example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:planning:query') && @ss.hasPermission('tjt:planning-quarter:query')")
|
||||
public CommonResult<ProjectPlanningQuarterPlanningDetailRespVO> getProjectPlanningQuarterPlanningDetail(
|
||||
@RequestParam("planningId") Long planningId) {
|
||||
ProjectPlanningDO planning = projectPlanningService.getProjectPlanning(planningId);
|
||||
if (planning == null) {
|
||||
return success(null);
|
||||
}
|
||||
List<ProjectPlanningQuarterDO> quarterList =
|
||||
projectPlanningQuarterService.getProjectPlanningQuarterListByPlanningId(planningId);
|
||||
|
||||
ProjectPlanningQuarterPlanningDetailRespVO respVO = new ProjectPlanningQuarterPlanningDetailRespVO();
|
||||
Map<Long, BigDecimal> allocatedAmountMap =
|
||||
projectPlanningService.getAllocatedAmountMap(Collections.singleton(planningId));
|
||||
respVO.setPlanning(BeanUtils.toBean(planning, ProjectPlanningRespVO.class,
|
||||
planningRespVO -> fillDistributionSummary(planningRespVO, allocatedAmountMap)));
|
||||
List<ProjectPlanningQuarterDO> parentQuarterList = quarterList.stream()
|
||||
.filter(item -> item.getGuideDetailId() == null)
|
||||
.collect(Collectors.toList());
|
||||
List<ProjectPlanningQuarterDO> detailQuarterList = quarterList.stream()
|
||||
.filter(item -> item.getGuideDetailId() != null)
|
||||
.collect(Collectors.toList());
|
||||
boolean guideDetailMode = ProjectPlanningBizTypeConstants.isMajorGuidanceScene(
|
||||
planning.getOwnershipType(), planning.getCalculationMethod());
|
||||
respVO.setGuideDetailMode(guideDetailMode);
|
||||
respVO.setParentQuarters(BeanUtils.toBean(parentQuarterList, ProjectPlanningQuarterRespVO.class));
|
||||
respVO.setQuarters(guideDetailMode
|
||||
? respVO.getParentQuarters()
|
||||
: BeanUtils.toBean(quarterList, ProjectPlanningQuarterRespVO.class));
|
||||
if (guideDetailMode) {
|
||||
List<ProjectPlanningGuideDetailDO> guideDetailList =
|
||||
projectPlanningGuideDetailService.getProjectPlanningGuideDetailListByPlanningId(planningId);
|
||||
respVO.setGuideDetails(buildGuideDetailRespList(planning, guideDetailList, detailQuarterList));
|
||||
boolean historyParentMode = !parentQuarterList.isEmpty() && detailQuarterList.isEmpty();
|
||||
respVO.setHistoryParentMode(historyParentMode);
|
||||
if (historyParentMode) {
|
||||
respVO.setMessage("当前合约规划存在历史父级季度分配。请先清空历史父级分配后,再按指导价法明细维护。");
|
||||
}
|
||||
}
|
||||
return success(respVO);
|
||||
}
|
||||
|
||||
private List<ProjectPlanningQuarterGuideDetailRespVO> buildGuideDetailRespList(
|
||||
ProjectPlanningDO planning,
|
||||
List<ProjectPlanningGuideDetailDO> guideDetailList,
|
||||
List<ProjectPlanningQuarterDO> detailQuarterList) {
|
||||
if (guideDetailList == null || guideDetailList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap = detailQuarterList == null
|
||||
? Collections.emptyMap()
|
||||
: detailQuarterList.stream()
|
||||
.filter(item -> item.getGuideDetailId() != null)
|
||||
.collect(Collectors.groupingBy(ProjectPlanningQuarterDO::getGuideDetailId));
|
||||
List<ProjectPlanningQuarterGuideDetailRespVO> result = new ArrayList<>();
|
||||
for (ProjectPlanningGuideDetailDO guideDetail : guideDetailList) {
|
||||
ProjectPlanningQuarterGuideDetailRespVO respVO =
|
||||
BeanUtils.toBean(guideDetail, ProjectPlanningQuarterGuideDetailRespVO.class);
|
||||
List<ProjectPlanningQuarterDO> quarterList =
|
||||
quarterMap.getOrDefault(guideDetail.getId(), Collections.emptyList());
|
||||
respVO.setQuarters(BeanUtils.toBean(quarterList, ProjectPlanningQuarterRespVO.class));
|
||||
fillGuideDetailDistributionSummary(respVO, planning, quarterList);
|
||||
result.add(respVO);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void fillGuideDetailDistributionSummary(ProjectPlanningQuarterGuideDetailRespVO respVO,
|
||||
ProjectPlanningDO planning,
|
||||
List<ProjectPlanningQuarterDO> quarterList) {
|
||||
BigDecimal allocatedRatio = ZERO_RATIO;
|
||||
if (quarterList != null) {
|
||||
for (ProjectPlanningQuarterDO quarter : quarterList) {
|
||||
allocatedRatio = allocatedRatio.add(ratio(quarter.getDistributionRatio()))
|
||||
.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
}
|
||||
}
|
||||
BigDecimal totalDistributionAmount = planning.getTotalDistributionAmount() == null
|
||||
? BigDecimal.ONE.setScale(RATIO_SCALE, RoundingMode.HALF_UP)
|
||||
: planning.getTotalDistributionAmount().setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
BigDecimal allocatedAmount = totalDistributionAmount.multiply(allocatedRatio)
|
||||
.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
respVO.setAllocatedAmount(allocatedAmount);
|
||||
respVO.setPendingAmount(totalDistributionAmount.subtract(allocatedAmount)
|
||||
.max(BigDecimal.ZERO)
|
||||
.setScale(RATIO_SCALE, RoundingMode.HALF_UP));
|
||||
}
|
||||
|
||||
private void fillDistributionSummary(ProjectPlanningRespVO respVO, Map<Long, BigDecimal> allocatedAmountMap) {
|
||||
BigDecimal allocatedRatio = allocatedAmountMap.getOrDefault(respVO.getId(), ZERO_RATIO);
|
||||
BigDecimal totalDistributionAmount = respVO.getTotalDistributionAmount() == null
|
||||
? ZERO_RATIO : respVO.getTotalDistributionAmount().setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
BigDecimal allocatedAmount = totalDistributionAmount.multiply(allocatedRatio)
|
||||
.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
respVO.setAllocatedAmount(allocatedAmount);
|
||||
respVO.setPendingAmount(totalDistributionAmount.subtract(allocatedAmount)
|
||||
.setScale(RATIO_SCALE, RoundingMode.HALF_UP));
|
||||
}
|
||||
|
||||
private BigDecimal ratio(BigDecimal value) {
|
||||
return value == null ? ZERO_RATIO : value.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo;
|
||||
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningguidedetail.vo.ProjectPlanningGuideDetailRespVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 指导价法明细季度分配 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ProjectPlanningQuarterGuideDetailRespVO extends ProjectPlanningGuideDetailRespVO {
|
||||
|
||||
@Schema(description = "明细已分配比例")
|
||||
private BigDecimal allocatedAmount;
|
||||
|
||||
@Schema(description = "明细待分配比例")
|
||||
private BigDecimal pendingAmount;
|
||||
|
||||
@Schema(description = "明细季度分配列表")
|
||||
private List<ProjectPlanningQuarterRespVO> quarters = Collections.emptyList();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo;
|
||||
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planning.vo.ProjectPlanningRespVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 合约规划季度分配聚合详情 Response VO")
|
||||
@Data
|
||||
public class ProjectPlanningQuarterPlanningDetailRespVO {
|
||||
|
||||
@Schema(description = "合约规划详情")
|
||||
private ProjectPlanningRespVO planning;
|
||||
|
||||
@Schema(description = "季度分配列表")
|
||||
private List<ProjectPlanningQuarterRespVO> quarters = Collections.emptyList();
|
||||
|
||||
@Schema(description = "是否指导价法明细分配模式")
|
||||
private Boolean guideDetailMode = Boolean.FALSE;
|
||||
|
||||
@Schema(description = "是否存在历史父级季度分配")
|
||||
private Boolean historyParentMode = Boolean.FALSE;
|
||||
|
||||
@Schema(description = "提示信息")
|
||||
private String message;
|
||||
|
||||
@Schema(description = "父级季度分配列表")
|
||||
private List<ProjectPlanningQuarterRespVO> parentQuarters = Collections.emptyList();
|
||||
|
||||
@Schema(description = "指导价法明细及各自季度分配列表")
|
||||
private List<ProjectPlanningQuarterGuideDetailRespVO> guideDetails = Collections.emptyList();
|
||||
|
||||
}
|
||||
@@ -16,6 +16,12 @@ public class ProjectPlanningQuarterRespVO {
|
||||
@Schema(description = "Planning ID", example = "1")
|
||||
private Long planningId;
|
||||
|
||||
@Schema(description = "Guide detail ID")
|
||||
private Long guideDetailId;
|
||||
|
||||
@Schema(description = "Guide detail sort number snapshot")
|
||||
private Integer guideDetailSortNo;
|
||||
|
||||
@Schema(description = "Distribution year")
|
||||
private Integer distributionYear;
|
||||
|
||||
|
||||
@@ -19,6 +19,12 @@ public class ProjectPlanningQuarterSaveReqVO {
|
||||
@NotNull(message = "planningId cannot be null")
|
||||
private Long planningId;
|
||||
|
||||
@Schema(description = "Guide detail ID, required only for major + guidance price planning", example = "1")
|
||||
private Long guideDetailId;
|
||||
|
||||
@Schema(description = "Guide detail sort number snapshot", example = "1")
|
||||
private Integer guideDetailSortNo;
|
||||
|
||||
@Schema(description = "Distribution year", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026")
|
||||
@NotNull(message = "distributionYear cannot be null")
|
||||
private Integer distributionYear;
|
||||
|
||||
@@ -4,6 +4,7 @@ import cn.iocoder.lyzsys.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.profit.vo.ProjectProfitPageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.profit.vo.ProjectProfitRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.profit.vo.ProjectProfitSettlementSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.profit.ProjectProfitService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -11,6 +12,9 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -44,4 +48,27 @@ public class ProjectProfitController {
|
||||
return success(projectProfitService.getProjectProfitPage(pageReqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/lock-budget")
|
||||
@Operation(summary = "锁定项目成本预算测算")
|
||||
@Parameter(name = "projectId", description = "项目 ID", required = true, example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:profit:query')")
|
||||
public CommonResult<ProjectProfitRespVO> lockBudgetSnapshot(@RequestParam("projectId") Long projectId) {
|
||||
return success(projectProfitService.lockBudgetSnapshot(projectId));
|
||||
}
|
||||
|
||||
@PostMapping("/lock-accounting")
|
||||
@Operation(summary = "锁定项目成本核算测算")
|
||||
@Parameter(name = "projectId", description = "项目 ID", required = true, example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:profit:query')")
|
||||
public CommonResult<ProjectProfitRespVO> lockAccountingSnapshot(@RequestParam("projectId") Long projectId) {
|
||||
return success(projectProfitService.lockAccountingSnapshot(projectId));
|
||||
}
|
||||
|
||||
@PutMapping("/save-settlement")
|
||||
@Operation(summary = "保存项目成本结算测算")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:profit:query')")
|
||||
public CommonResult<ProjectProfitRespVO> saveSettlementSnapshot(@Valid @RequestBody ProjectProfitSettlementSaveReqVO saveReqVO) {
|
||||
return success(projectProfitService.saveSettlementSnapshot(saveReqVO));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,27 +17,39 @@ public class ProjectProfitRespVO {
|
||||
private String projectName;
|
||||
|
||||
@Schema(description = "排序")
|
||||
private Integer sortNo;
|
||||
private String sortNo;
|
||||
|
||||
@Schema(description = "是否签订合同")
|
||||
private Boolean contractSignedFlag;
|
||||
|
||||
@Schema(description = "合同产值")
|
||||
@Schema(description = "合同总产值")
|
||||
private BigDecimal contractAmount;
|
||||
|
||||
@Schema(description = "最终结算金额")
|
||||
@Schema(description = "结算合同总产值")
|
||||
private BigDecimal finalSettlementAmount;
|
||||
|
||||
@Schema(description = "综合所协作金额")
|
||||
@Schema(description = "合同产值(不含增值税),合同总产值 / 1.06")
|
||||
private BigDecimal effectiveSettlementAmount;
|
||||
|
||||
@Schema(description = "综合所人工成本")
|
||||
private BigDecimal comprehensivePlanningAmount;
|
||||
|
||||
@Schema(description = "专业分包金额")
|
||||
@Schema(description = "专项分包人工成本合计")
|
||||
private BigDecimal subcontractPlanningAmount;
|
||||
|
||||
@Schema(description = "专业所产值")
|
||||
@Schema(description = "专项分包-专业所人工成本")
|
||||
private BigDecimal specialSubcontractPlanningAmount;
|
||||
|
||||
@Schema(description = "专项分包-源头合作分包人工成本")
|
||||
private BigDecimal sourceCoopSubcontractPlanningAmount;
|
||||
|
||||
@Schema(description = "专项分包-综合所人工成本")
|
||||
private BigDecimal comprehensiveSubcontractPlanningAmount;
|
||||
|
||||
@Schema(description = "专业所考核产值")
|
||||
private BigDecimal majorOutputValue;
|
||||
|
||||
@Schema(description = "专业所预计绩效")
|
||||
@Schema(description = "专业所人工成本")
|
||||
private BigDecimal majorExpectedPerformance;
|
||||
|
||||
@Schema(description = "科创产值比例")
|
||||
@@ -49,10 +61,10 @@ public class ProjectProfitRespVO {
|
||||
@Schema(description = "其他成本")
|
||||
private BigDecimal otherCost;
|
||||
|
||||
@Schema(description = "盈亏值")
|
||||
@Schema(description = "预算盈亏值")
|
||||
private BigDecimal profitLossValue;
|
||||
|
||||
@Schema(description = "盈亏百分比")
|
||||
@Schema(description = "预算盈亏百分比")
|
||||
private BigDecimal profitLossRate;
|
||||
|
||||
@Schema(description = "项目开始年度")
|
||||
@@ -61,4 +73,13 @@ public class ProjectProfitRespVO {
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "项目成本预算测算快照")
|
||||
private ProjectProfitSnapshotRespVO budgetSnapshot;
|
||||
|
||||
@Schema(description = "项目成本核算测算快照")
|
||||
private ProjectProfitSnapshotRespVO accountingSnapshot;
|
||||
|
||||
@Schema(description = "项目成本结算测算快照")
|
||||
private ProjectProfitSnapshotRespVO settlementSnapshot;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.profit.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
@Schema(description = "管理后台 - 项目成本结算测算保存 Request VO")
|
||||
@Data
|
||||
public class ProjectProfitSettlementSaveReqVO {
|
||||
|
||||
@Schema(description = "项目 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "项目 ID 不能为空")
|
||||
private Long projectId;
|
||||
|
||||
@Schema(description = "考核结果")
|
||||
@Size(max = 64, message = "考核结果长度不能超过 64 个字符")
|
||||
private String assessmentResult;
|
||||
|
||||
@Schema(description = "备注")
|
||||
@Size(max = 500, message = "备注长度不能超过 500 个字符")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.profit.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 项目成本测算快照 Response VO")
|
||||
@Data
|
||||
public class ProjectProfitSnapshotRespVO {
|
||||
|
||||
@Schema(description = "快照 ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "项目 ID")
|
||||
private Long projectId;
|
||||
|
||||
@Schema(description = "快照类型:budget/accounting/settlement")
|
||||
private String snapshotType;
|
||||
|
||||
@Schema(description = "是否锁定")
|
||||
private Boolean lockedFlag;
|
||||
|
||||
@Schema(description = "操作人 ID")
|
||||
private Long actionUserId;
|
||||
|
||||
@Schema(description = "操作人姓名")
|
||||
private String actionUserName;
|
||||
|
||||
@Schema(description = "操作时间")
|
||||
private LocalDateTime actionTime;
|
||||
|
||||
@Schema(description = "合同总产值")
|
||||
private BigDecimal contractAmount;
|
||||
|
||||
@Schema(description = "结算合同总产值")
|
||||
private BigDecimal finalSettlementAmount;
|
||||
|
||||
@Schema(description = "合同产值(不含增值税),合同总产值 / 1.06")
|
||||
private BigDecimal effectiveSettlementAmount;
|
||||
|
||||
@Schema(description = "综合所人工成本")
|
||||
private BigDecimal comprehensivePlanningAmount;
|
||||
|
||||
@Schema(description = "专项分包人工成本合计")
|
||||
private BigDecimal subcontractPlanningAmount;
|
||||
|
||||
@Schema(description = "专项分包-专业所人工成本")
|
||||
private BigDecimal specialSubcontractPlanningAmount;
|
||||
|
||||
@Schema(description = "专项分包-源头合作分包人工成本")
|
||||
private BigDecimal sourceCoopSubcontractPlanningAmount;
|
||||
|
||||
@Schema(description = "专项分包-综合所人工成本")
|
||||
private BigDecimal comprehensiveSubcontractPlanningAmount;
|
||||
|
||||
@Schema(description = "专业所考核产值")
|
||||
private BigDecimal majorOutputValue;
|
||||
|
||||
@Schema(description = "专业所人工成本")
|
||||
private BigDecimal majorExpectedPerformance;
|
||||
|
||||
@Schema(description = "科创产值比例")
|
||||
private BigDecimal innovationOutputRate;
|
||||
|
||||
@Schema(description = "科创产值")
|
||||
private BigDecimal innovationOutputValue;
|
||||
|
||||
@Schema(description = "其他成本")
|
||||
private BigDecimal otherCost;
|
||||
|
||||
@Schema(description = "预算盈亏值")
|
||||
private BigDecimal profitLossValue;
|
||||
|
||||
@Schema(description = "预算盈亏百分比")
|
||||
private BigDecimal profitLossRate;
|
||||
|
||||
@Schema(description = "考核结果")
|
||||
private String assessmentResult;
|
||||
|
||||
@Schema(description = "考核系数")
|
||||
private BigDecimal assessmentCoefficient;
|
||||
|
||||
@Schema(description = "综合所考核产值核算值")
|
||||
private BigDecimal comprehensiveAccountingOutputValue;
|
||||
|
||||
@Schema(description = "综合所考核产值结算值")
|
||||
private BigDecimal comprehensiveSettlementOutputValue;
|
||||
|
||||
@Schema(description = "专业所考核产值核算值")
|
||||
private BigDecimal majorAccountingOutputValue;
|
||||
|
||||
@Schema(description = "专业所考核产值结算值")
|
||||
private BigDecimal majorSettlementOutputValue;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@@ -24,7 +24,7 @@ public class ProjectPageReqVO extends PageParam {
|
||||
@Schema(description = "项目开始年度", example = "2026")
|
||||
private Integer projectStartYear;
|
||||
|
||||
@Schema(description = "项目状态", example = "进行中")
|
||||
@Schema(description = "项目状态:in_progress/completed/paused/terminated", example = "in_progress")
|
||||
private String projectStatus;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
|
||||
@@ -28,18 +28,18 @@ public class ProjectRespVO {
|
||||
|
||||
@Schema(description = "排序")
|
||||
@ExcelProperty("排序")
|
||||
private Integer sortNo;
|
||||
private String sortNo;
|
||||
|
||||
@Schema(description = "是否签订合同", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("是否签订合同")
|
||||
private Boolean contractSignedFlag;
|
||||
|
||||
@Schema(description = "合同产值", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("合同产值")
|
||||
@Schema(description = "合同总产值", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("合同总产值")
|
||||
private BigDecimal contractAmount;
|
||||
|
||||
@Schema(description = "工程总面积", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("工程总面积")
|
||||
@Schema(description = "建筑面积", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("建筑面积")
|
||||
private BigDecimal totalConstructionArea;
|
||||
|
||||
@Schema(description = "建设单位")
|
||||
@@ -71,8 +71,8 @@ public class ProjectRespVO {
|
||||
@ExcelProperty("工程类型")
|
||||
private String projectType;
|
||||
|
||||
@Schema(description = "工程类别")
|
||||
@ExcelProperty("工程类别")
|
||||
@Schema(description = "设计类型")
|
||||
@ExcelProperty("设计类型")
|
||||
private String projectCategory;
|
||||
|
||||
@Schema(description = "项目开始年度")
|
||||
@@ -95,8 +95,8 @@ public class ProjectRespVO {
|
||||
@Schema(description = "中止原因")
|
||||
private String terminateReason;
|
||||
|
||||
@Schema(description = "最终结算金额")
|
||||
@ExcelProperty("最终结算金额")
|
||||
@Schema(description = "结算合同总产值")
|
||||
@ExcelProperty("结算合同总产值")
|
||||
private BigDecimal finalSettlementAmount;
|
||||
|
||||
@Schema(description = "科创产值比例")
|
||||
|
||||
@@ -28,19 +28,20 @@ public class ProjectSaveReqVO {
|
||||
@Size(max = 200, message = "项目名称长度不能超过 200 个字符")
|
||||
private String projectName;
|
||||
|
||||
@Schema(description = "排序", example = "0")
|
||||
private Integer sortNo;
|
||||
@Schema(description = "排序", example = "A-01")
|
||||
@Size(max = 50, message = "排序长度不能超过 50 个字符")
|
||||
private String sortNo;
|
||||
|
||||
@Schema(description = "是否签订合同", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "是否签订合同不能为空")
|
||||
private Boolean contractSignedFlag;
|
||||
|
||||
@Schema(description = "合同产值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000000")
|
||||
@NotNull(message = "合同产值不能为空")
|
||||
@Schema(description = "合同总产值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000000")
|
||||
@NotNull(message = "合同总产值不能为空")
|
||||
private BigDecimal contractAmount;
|
||||
|
||||
@Schema(description = "工程总面积", requiredMode = Schema.RequiredMode.REQUIRED, example = "30000")
|
||||
@NotNull(message = "工程总面积不能为空")
|
||||
@Schema(description = "建筑面积", requiredMode = Schema.RequiredMode.REQUIRED, example = "30000")
|
||||
@NotNull(message = "建筑面积不能为空")
|
||||
private BigDecimal totalConstructionArea;
|
||||
|
||||
@Schema(description = "建设单位", example = "XX 建设单位")
|
||||
@@ -64,15 +65,15 @@ public class ProjectSaveReqVO {
|
||||
@Size(max = 50, message = "工程类型长度不能超过 50 个字符")
|
||||
private String projectType;
|
||||
|
||||
@Schema(description = "工程类别", example = "住宅")
|
||||
@Size(max = 50, message = "工程类别长度不能超过 50 个字符")
|
||||
@Schema(description = "设计类型", example = "住宅")
|
||||
@Size(max = 50, message = "设计类型长度不能超过 50 个字符")
|
||||
private String projectCategory;
|
||||
|
||||
@Schema(description = "项目开始年度", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026")
|
||||
@NotNull(message = "项目开始年度不能为空")
|
||||
private Integer projectStartYear;
|
||||
|
||||
@Schema(description = "项目状态", example = "进行中")
|
||||
@Schema(description = "项目状态:in_progress/completed/paused/terminated", example = "in_progress")
|
||||
@Size(max = 20, message = "项目状态长度不能超过 20 个字符")
|
||||
private String projectStatus;
|
||||
|
||||
@@ -84,7 +85,7 @@ public class ProjectSaveReqVO {
|
||||
@Size(max = 255, message = "中止原因长度不能超过 255 个字符")
|
||||
private String terminateReason;
|
||||
|
||||
@Schema(description = "最终结算金额", example = "1200000")
|
||||
@Schema(description = "结算合同总产值", example = "1200000")
|
||||
private BigDecimal finalSettlementAmount;
|
||||
|
||||
@Schema(description = "科创产值比例", example = "0.0100")
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.report;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.EmployeeOutputSummaryExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectBudgetExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectLeadQuarterOutputExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectOverviewExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectQuarterOutputExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.SpecialtyPersonOutputExportReqVO;
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.*;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.report.ProjectOutputReportService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -22,6 +18,7 @@ import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.lyzsys.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 产值报表导出")
|
||||
@RestController
|
||||
@@ -41,8 +38,16 @@ public class ProjectOutputReportController {
|
||||
projectOutputReportService.exportProjectBudgetExcel(response, reqVO);
|
||||
}
|
||||
|
||||
@GetMapping("/project-budget/preview")
|
||||
@Operation(summary = "预览项目考核产值预算表")
|
||||
@PreAuthorize("@ss.hasAnyPermissions('tjt:report-budget:query', 'tjt:report-budget:export')")
|
||||
public CommonResult<ProjectBudgetPreviewRespVO> getProjectBudgetPreview(
|
||||
@Valid ProjectBudgetExportReqVO reqVO) {
|
||||
return success(projectOutputReportService.getProjectBudgetPreview(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/project-quarter-output/export-excel")
|
||||
@Operation(summary = "导出项目级年度季度计取表")
|
||||
@Operation(summary = "导出专业间年度表")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:report-project-quarter:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportProjectQuarterOutputExcel(HttpServletResponse response,
|
||||
@@ -50,9 +55,17 @@ public class ProjectOutputReportController {
|
||||
projectOutputReportService.exportProjectQuarterOutputExcel(response, reqVO);
|
||||
}
|
||||
|
||||
@GetMapping("/project-quarter-output/preview")
|
||||
@Operation(summary = "预览专业间年度表")
|
||||
@PreAuthorize("@ss.hasAnyPermissions('tjt:report-project-quarter:query', 'tjt:report-project-quarter:export')")
|
||||
public CommonResult<ProjectQuarterOutputPreviewRespVO> getProjectQuarterOutputPreview(
|
||||
@Valid ProjectQuarterOutputExportReqVO reqVO) {
|
||||
return success(projectOutputReportService.getProjectQuarterOutputPreview(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/project-lead-quarter-output/export-excel")
|
||||
@Operation(summary = "导出工程负责人年度季度计取表")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:report-project-quarter:export')")
|
||||
@Operation(summary = "导出工程负责人年度表")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:report-project-lead-quarter:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportProjectLeadQuarterOutputExcel(HttpServletResponse response,
|
||||
@Valid ProjectLeadQuarterOutputExportReqVO reqVO)
|
||||
@@ -60,6 +73,14 @@ public class ProjectOutputReportController {
|
||||
projectOutputReportService.exportProjectLeadQuarterOutputExcel(response, reqVO);
|
||||
}
|
||||
|
||||
@GetMapping("/project-lead-quarter-output/preview")
|
||||
@Operation(summary = "预览工程负责人年度表")
|
||||
@PreAuthorize("@ss.hasAnyPermissions('tjt:report-project-lead-quarter:query', 'tjt:report-project-lead-quarter:export')")
|
||||
public CommonResult<ProjectLeadQuarterOutputPreviewRespVO> getProjectLeadQuarterOutputPreview(
|
||||
@Valid ProjectLeadQuarterOutputExportReqVO reqVO) {
|
||||
return success(projectOutputReportService.getProjectLeadQuarterOutputPreview(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/specialty-person-output/export-excel")
|
||||
@Operation(summary = "导出专业内人员年度季度计取表")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:report-specialty-person:export')")
|
||||
@@ -69,6 +90,22 @@ public class ProjectOutputReportController {
|
||||
projectOutputReportService.exportSpecialtyPersonOutputExcel(response, reqVO);
|
||||
}
|
||||
|
||||
@GetMapping("/specialty-person-output/preview")
|
||||
@Operation(summary = "预览专业内人员年度季度计取表")
|
||||
@PreAuthorize("@ss.hasAnyPermissions('tjt:report-specialty-person:query', 'tjt:report-specialty-person:export')")
|
||||
public CommonResult<SpecialtyPersonOutputPreviewRespVO> getSpecialtyPersonOutputPreview(
|
||||
@Valid SpecialtyPersonOutputPreviewReqVO reqVO) {
|
||||
return success(projectOutputReportService.getSpecialtyPersonOutputPreview(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/project-overview/preview")
|
||||
@Operation(summary = "预览项目总览表")
|
||||
@PreAuthorize("@ss.hasAnyPermissions('tjt:report-summary:query', 'tjt:report-summary:export')")
|
||||
public CommonResult<ProjectOverviewPreviewRespVO> getProjectOverviewPreview(
|
||||
@Valid ProjectOverviewExportReqVO reqVO) {
|
||||
return success(projectOutputReportService.getProjectOverviewPreview(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/project-overview/export-excel")
|
||||
@Operation(summary = "导出项目总览表")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:report-summary:export')")
|
||||
@@ -78,6 +115,14 @@ public class ProjectOutputReportController {
|
||||
projectOutputReportService.exportProjectOverviewExcel(response, reqVO);
|
||||
}
|
||||
|
||||
@GetMapping("/employee-output-summary/preview")
|
||||
@Operation(summary = "预览员工个人考核产值汇总表")
|
||||
@PreAuthorize("@ss.hasAnyPermissions('tjt:report-summary:query', 'tjt:report-summary:export')")
|
||||
public CommonResult<EmployeeOutputSummaryPreviewRespVO> getEmployeeOutputSummaryPreview(
|
||||
@Valid EmployeeOutputSummaryExportReqVO reqVO) {
|
||||
return success(projectOutputReportService.getEmployeeOutputSummaryPreview(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/employee-output-summary/export-excel")
|
||||
@Operation(summary = "导出员工个人考核产值汇总表")
|
||||
@PreAuthorize("@ss.hasPermission('tjt:report-summary:export')")
|
||||
|
||||
@@ -15,12 +15,14 @@ public class EmployeeOutputSummaryExcelRespVO {
|
||||
@ExcelProperty("序号")
|
||||
private Integer serialNo;
|
||||
|
||||
@ExcelProperty("专业所")
|
||||
private String officeName;
|
||||
|
||||
private Integer officeSortNo;
|
||||
|
||||
@ExcelProperty("姓名")
|
||||
private String employeeName;
|
||||
|
||||
@ExcelProperty("所属专业所")
|
||||
private String officeName;
|
||||
|
||||
@ExcelProperty("第一季度")
|
||||
private BigDecimal quarterOneAmount;
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 员工个人考核产值汇总表预览 Response VO")
|
||||
@Data
|
||||
public class EmployeeOutputSummaryPreviewRespVO {
|
||||
|
||||
@Schema(description = "年度", example = "2026")
|
||||
private Integer year;
|
||||
|
||||
@Schema(description = "预计 K 值,小数值,例如 0.4 表示 40%")
|
||||
private BigDecimal kValue;
|
||||
|
||||
@Schema(description = "员工明细行,金额单位:万元")
|
||||
private List<EmployeeOutputSummaryExcelRespVO> rows = Collections.emptyList();
|
||||
|
||||
@Schema(description = "合计行,金额单位:万元")
|
||||
private EmployeeOutputSummaryExcelRespVO totalRow;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 项目考核产值预算表预览 Response VO")
|
||||
@Data
|
||||
public class ProjectBudgetPreviewRespVO {
|
||||
|
||||
@Schema(description = "年度", example = "2026")
|
||||
private Integer year;
|
||||
|
||||
@Schema(description = "工程编号")
|
||||
private String projectCode;
|
||||
|
||||
@Schema(description = "项目名称")
|
||||
private String projectName;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "建筑(装饰)工程项目考核产值预算表")
|
||||
private List<BudgetRow> budgetRows = Collections.emptyList();
|
||||
|
||||
@Schema(description = "项目考核产值年度季度预算计取表")
|
||||
private List<QuarterBudgetRow> quarterBudgetRows = Collections.emptyList();
|
||||
|
||||
@Schema(description = "建筑(装饰)工程项目考核产值预算表行")
|
||||
@Data
|
||||
public static class BudgetRow {
|
||||
|
||||
@Schema(description = "行类型")
|
||||
private String rowType;
|
||||
|
||||
@Schema(description = "规划 ID")
|
||||
private Long planningId;
|
||||
|
||||
@Schema(description = "规划内容")
|
||||
private String planningContent;
|
||||
|
||||
@Schema(description = "设计部位")
|
||||
private String displayDesignPart;
|
||||
|
||||
@Schema(description = "设计内容/设计类型")
|
||||
private String displayBuildingType;
|
||||
|
||||
@Schema(description = "内部指导单价")
|
||||
private BigDecimal internalGuidanceUnitPrice;
|
||||
|
||||
@Schema(description = "设计面积")
|
||||
private BigDecimal designArea;
|
||||
|
||||
@Schema(description = "栋数/户型数")
|
||||
private Integer buildingOrUnitCount;
|
||||
|
||||
@Schema(description = "套图系数")
|
||||
private BigDecimal drawingSetFactor;
|
||||
|
||||
@Schema(description = "规模系数")
|
||||
private BigDecimal scaleFactor;
|
||||
|
||||
@Schema(description = "修改系数")
|
||||
private BigDecimal modificationFactor;
|
||||
|
||||
@Schema(description = "复杂系数/复杂等级")
|
||||
private BigDecimal complexityFactor;
|
||||
|
||||
@Schema(description = "小计")
|
||||
private BigDecimal subtotalArea;
|
||||
|
||||
@Schema(description = "设计阶段占比")
|
||||
private BigDecimal currentDesignStageRatio;
|
||||
|
||||
@Schema(description = "考核产值小计,单位:万元")
|
||||
private BigDecimal assessmentOutputValueWan;
|
||||
|
||||
}
|
||||
|
||||
@Schema(description = "项目考核产值年度季度预算计取表行")
|
||||
@Data
|
||||
public static class QuarterBudgetRow {
|
||||
|
||||
@Schema(description = "序号")
|
||||
private Integer serialNo;
|
||||
|
||||
@Schema(description = "是否合计行")
|
||||
private Boolean totalRow = false;
|
||||
|
||||
@Schema(description = "产值类型")
|
||||
private String outputType;
|
||||
|
||||
@Schema(description = "设计内容")
|
||||
private String designContent;
|
||||
|
||||
@Schema(description = "预算年度")
|
||||
private Integer budgetYear;
|
||||
|
||||
@Schema(description = "总建筑(精装)设计面积")
|
||||
private BigDecimal totalDesignArea;
|
||||
|
||||
@Schema(description = "总考核产值面积")
|
||||
private BigDecimal totalAssessmentArea;
|
||||
|
||||
@Schema(description = "总考核产值,单位:万元")
|
||||
private BigDecimal totalAssessmentOutputWan;
|
||||
|
||||
@Schema(description = "阶段占比")
|
||||
private BigDecimal designStageRatio;
|
||||
|
||||
@Schema(description = "设计阶段考核产值,单位:万元")
|
||||
private BigDecimal designStageOutputWan;
|
||||
|
||||
@Schema(description = "往年已发放比例")
|
||||
private BigDecimal historicalIssuedRatio;
|
||||
|
||||
@Schema(description = "一季度发放比例")
|
||||
private BigDecimal quarterOneRatio;
|
||||
|
||||
@Schema(description = "二季度发放比例")
|
||||
private BigDecimal quarterTwoRatio;
|
||||
|
||||
@Schema(description = "三季度发放比例")
|
||||
private BigDecimal quarterThreeRatio;
|
||||
|
||||
@Schema(description = "四季度发放比例")
|
||||
private BigDecimal quarterFourRatio;
|
||||
|
||||
@Schema(description = "本年度小计比例")
|
||||
private BigDecimal currentYearRatio;
|
||||
|
||||
@Schema(description = "未发放比例")
|
||||
private BigDecimal pendingRatio;
|
||||
|
||||
@Schema(description = "一季度金额,单位:万元")
|
||||
private BigDecimal quarterOneAmountWan;
|
||||
|
||||
@Schema(description = "二季度金额,单位:万元")
|
||||
private BigDecimal quarterTwoAmountWan;
|
||||
|
||||
@Schema(description = "三季度金额,单位:万元")
|
||||
private BigDecimal quarterThreeAmountWan;
|
||||
|
||||
@Schema(description = "四季度金额,单位:万元")
|
||||
private BigDecimal quarterFourAmountWan;
|
||||
|
||||
@Schema(description = "本年度小计金额,单位:万元")
|
||||
private BigDecimal yearTotalAmountWan;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String ratioRemark;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,13 +5,13 @@ import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 工程负责人年度季度计取表导出 Request VO")
|
||||
@Schema(description = "管理后台 - 工程负责人年度表导出 Request VO")
|
||||
@Data
|
||||
public class ProjectLeadQuarterOutputExportReqVO {
|
||||
|
||||
@Schema(description = "合约规划 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "合约规划 ID 不能为空")
|
||||
private Long planningId;
|
||||
@Schema(description = "项目 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "项目 ID 不能为空")
|
||||
private Long projectId;
|
||||
|
||||
@Schema(description = "导出年度", example = "2026")
|
||||
private Integer year;
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 工程负责人年度表预览 Response VO")
|
||||
@Data
|
||||
public class ProjectLeadQuarterOutputPreviewRespVO {
|
||||
|
||||
@Schema(description = "项目名称")
|
||||
private String projectName;
|
||||
|
||||
@Schema(description = "预览年度")
|
||||
private Integer year;
|
||||
|
||||
@Schema(description = "项目经理人员名称,多个使用 / 分隔")
|
||||
private String projectManagerNames;
|
||||
|
||||
@Schema(description = "工程负责人人员名称,多个使用 / 分隔")
|
||||
private String engineeringPrincipalNames;
|
||||
|
||||
@Schema(description = "预览行")
|
||||
private List<LeadQuarterRow> rows = Collections.emptyList();
|
||||
|
||||
@Schema(description = "工程负责人年度表预览行")
|
||||
@Data
|
||||
public static class LeadQuarterRow {
|
||||
|
||||
@Schema(description = "序号")
|
||||
private Integer serialNo;
|
||||
|
||||
@Schema(description = "产值类型")
|
||||
private String outputType;
|
||||
|
||||
@Schema(description = "设计内容")
|
||||
private String designContent;
|
||||
|
||||
@Schema(description = "是否小计行")
|
||||
private Boolean subtotalRow;
|
||||
|
||||
@Schema(description = "项目经理人员名称")
|
||||
private String projectManagerNames;
|
||||
|
||||
@Schema(description = "项目经理工作比例")
|
||||
private BigDecimal projectManagerRatio;
|
||||
|
||||
@Schema(description = "工程负责人人员名称")
|
||||
private String engineeringPrincipalNames;
|
||||
|
||||
@Schema(description = "工程负责人工作比例")
|
||||
private BigDecimal engineeringPrincipalRatio;
|
||||
|
||||
@Schema(description = "项目经理一季度金额,万元")
|
||||
private BigDecimal projectManagerQuarterOneAmountWan;
|
||||
|
||||
@Schema(description = "项目经理二季度金额,万元")
|
||||
private BigDecimal projectManagerQuarterTwoAmountWan;
|
||||
|
||||
@Schema(description = "项目经理三季度金额,万元")
|
||||
private BigDecimal projectManagerQuarterThreeAmountWan;
|
||||
|
||||
@Schema(description = "项目经理四季度金额,万元")
|
||||
private BigDecimal projectManagerQuarterFourAmountWan;
|
||||
|
||||
@Schema(description = "项目经理本年度小计,万元")
|
||||
private BigDecimal projectManagerYearTotalAmountWan;
|
||||
|
||||
@Schema(description = "工程负责人一季度金额,万元")
|
||||
private BigDecimal engineeringPrincipalQuarterOneAmountWan;
|
||||
|
||||
@Schema(description = "工程负责人二季度金额,万元")
|
||||
private BigDecimal engineeringPrincipalQuarterTwoAmountWan;
|
||||
|
||||
@Schema(description = "工程负责人三季度金额,万元")
|
||||
private BigDecimal engineeringPrincipalQuarterThreeAmountWan;
|
||||
|
||||
@Schema(description = "工程负责人四季度金额,万元")
|
||||
private BigDecimal engineeringPrincipalQuarterFourAmountWan;
|
||||
|
||||
@Schema(description = "工程负责人本年度小计,万元")
|
||||
private BigDecimal engineeringPrincipalYearTotalAmountWan;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "管理后台 - 项目总览表预览 Response VO")
|
||||
@Data
|
||||
public class ProjectOverviewPreviewRespVO {
|
||||
|
||||
@Schema(description = "年度", example = "2026")
|
||||
private Integer year;
|
||||
|
||||
@Schema(description = "专业所名称", example = "给排水所")
|
||||
private String officeName;
|
||||
|
||||
@Schema(description = "员工动态列")
|
||||
private List<EmployeeColumn> employeeColumns = Collections.emptyList();
|
||||
|
||||
@Schema(description = "项目行")
|
||||
private List<ProjectRow> rows = Collections.emptyList();
|
||||
|
||||
@Schema(description = "合计行")
|
||||
private ProjectRow totalRow;
|
||||
|
||||
@Schema(description = "员工动态列")
|
||||
@Data
|
||||
public static class EmployeeColumn {
|
||||
|
||||
@Schema(description = "员工 ID", example = "1")
|
||||
private Long employeeId;
|
||||
|
||||
@Schema(description = "员工姓名", example = "张三")
|
||||
private String employeeName;
|
||||
|
||||
}
|
||||
|
||||
@Schema(description = "项目总览行")
|
||||
@Data
|
||||
public static class ProjectRow {
|
||||
|
||||
@Schema(description = "序号", example = "1")
|
||||
private Integer serialNo;
|
||||
|
||||
@Schema(description = "是否合计行", example = "false")
|
||||
private Boolean totalRow = false;
|
||||
|
||||
@Schema(description = "项目名称")
|
||||
private String projectName;
|
||||
|
||||
@Schema(description = "工程进度情况及其它说明")
|
||||
private String progressText;
|
||||
|
||||
@Schema(description = "工作阶段")
|
||||
private String workStage;
|
||||
|
||||
@Schema(description = "本专业 + 项目总核算总产值,单位:万元")
|
||||
private BigDecimal totalOutputAmountWan;
|
||||
|
||||
@Schema(description = "往期已发放比例,小数值,例如 0.2 表示 20%")
|
||||
private BigDecimal historicalIssuedRatio;
|
||||
|
||||
@Schema(description = "本期结算占比,小数值,例如 0.2 表示 20%")
|
||||
private BigDecimal currentSettlementRatio;
|
||||
|
||||
@Schema(description = "本期结算考核产值,单位:万元")
|
||||
private BigDecimal currentSettlementAmountWan;
|
||||
|
||||
@Schema(description = "未结算比例,小数值,例如 0.2 表示 20%")
|
||||
private BigDecimal pendingRatio;
|
||||
|
||||
@Schema(description = "员工季度金额,key 为员工 ID,金额单位:万元")
|
||||
private Map<Long, EmployeeAmountValue> employeeAmountMap = new LinkedHashMap<>();
|
||||
|
||||
}
|
||||
|
||||
@Schema(description = "员工季度金额")
|
||||
@Data
|
||||
public static class EmployeeAmountValue {
|
||||
|
||||
@Schema(description = "一季度,单位:万元")
|
||||
private BigDecimal quarterOneAmountWan;
|
||||
|
||||
@Schema(description = "二季度,单位:万元")
|
||||
private BigDecimal quarterTwoAmountWan;
|
||||
|
||||
@Schema(description = "三季度,单位:万元")
|
||||
private BigDecimal quarterThreeAmountWan;
|
||||
|
||||
@Schema(description = "四季度,单位:万元")
|
||||
private BigDecimal quarterFourAmountWan;
|
||||
|
||||
@Schema(description = "本年度小计,单位:万元")
|
||||
private BigDecimal annualTotalAmountWan;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,13 +5,13 @@ import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 项目级年度季度计取表导出 Request VO")
|
||||
@Schema(description = "管理后台 - 专业间年度表导出 Request VO")
|
||||
@Data
|
||||
public class ProjectQuarterOutputExportReqVO {
|
||||
|
||||
@Schema(description = "合约规划 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "合约规划 ID 不能为空")
|
||||
private Long planningId;
|
||||
@Schema(description = "项目 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "项目 ID 不能为空")
|
||||
private Long projectId;
|
||||
|
||||
@Schema(description = "导出年度", example = "2026")
|
||||
private Integer year;
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 专业间年度表预览 Response VO")
|
||||
@Data
|
||||
public class ProjectQuarterOutputPreviewRespVO {
|
||||
|
||||
@Schema(description = "工程编号")
|
||||
private String projectCode;
|
||||
|
||||
@Schema(description = "项目名称")
|
||||
private String projectName;
|
||||
|
||||
@Schema(description = "预览年度")
|
||||
private Integer year;
|
||||
|
||||
@Schema(description = "预览行")
|
||||
private List<QuarterRow> rows = Collections.emptyList();
|
||||
|
||||
@Schema(description = "专业间年度表预览行")
|
||||
@Data
|
||||
public static class QuarterRow {
|
||||
|
||||
@Schema(description = "序号")
|
||||
private Integer serialNo;
|
||||
|
||||
@Schema(description = "是否合计行")
|
||||
private Boolean totalRow;
|
||||
|
||||
@Schema(description = "是否占位行")
|
||||
private Boolean placeholderRow;
|
||||
|
||||
@Schema(description = "产值类型")
|
||||
private String outputType;
|
||||
|
||||
@Schema(description = "设计内容")
|
||||
private String designContent;
|
||||
|
||||
@Schema(description = "一季度金额,万元")
|
||||
private BigDecimal quarterOneAmountWan;
|
||||
|
||||
@Schema(description = "二季度金额,万元")
|
||||
private BigDecimal quarterTwoAmountWan;
|
||||
|
||||
@Schema(description = "三季度金额,万元")
|
||||
private BigDecimal quarterThreeAmountWan;
|
||||
|
||||
@Schema(description = "四季度金额,万元")
|
||||
private BigDecimal quarterFourAmountWan;
|
||||
|
||||
@Schema(description = "本年度小计,万元")
|
||||
private BigDecimal yearTotalAmountWan;
|
||||
|
||||
@Schema(description = "项目经理/工程负责人占比")
|
||||
private BigDecimal projectLeadRatio;
|
||||
|
||||
@Schema(description = "项目经理/工程负责人总考核产值,万元")
|
||||
private BigDecimal projectLeadAssessmentOutputWan;
|
||||
|
||||
@Schema(description = "项目经理/工程负责人一季度金额,万元")
|
||||
private BigDecimal projectLeadQuarterOneAmountWan;
|
||||
|
||||
@Schema(description = "项目经理/工程负责人二季度金额,万元")
|
||||
private BigDecimal projectLeadQuarterTwoAmountWan;
|
||||
|
||||
@Schema(description = "项目经理/工程负责人三季度金额,万元")
|
||||
private BigDecimal projectLeadQuarterThreeAmountWan;
|
||||
|
||||
@Schema(description = "项目经理/工程负责人四季度金额,万元")
|
||||
private BigDecimal projectLeadQuarterFourAmountWan;
|
||||
|
||||
@Schema(description = "项目经理/工程负责人本年度总计,万元")
|
||||
private BigDecimal projectLeadYearTotalAmountWan;
|
||||
|
||||
@Schema(description = "专业所占比")
|
||||
private BigDecimal officeRatio;
|
||||
|
||||
@Schema(description = "专业所总考核产值,万元")
|
||||
private BigDecimal officeAssessmentOutputWan;
|
||||
|
||||
@Schema(description = "专业所一季度金额,万元")
|
||||
private BigDecimal officeQuarterOneAmountWan;
|
||||
|
||||
@Schema(description = "专业所二季度金额,万元")
|
||||
private BigDecimal officeQuarterTwoAmountWan;
|
||||
|
||||
@Schema(description = "专业所三季度金额,万元")
|
||||
private BigDecimal officeQuarterThreeAmountWan;
|
||||
|
||||
@Schema(description = "专业所四季度金额,万元")
|
||||
private BigDecimal officeQuarterFourAmountWan;
|
||||
|
||||
@Schema(description = "专业所本年度总计,万元")
|
||||
private BigDecimal officeYearTotalAmountWan;
|
||||
|
||||
@Schema(description = "建筑专业占比")
|
||||
private BigDecimal archRatio;
|
||||
|
||||
@Schema(description = "精装专业占比")
|
||||
private BigDecimal decorRatio;
|
||||
|
||||
@Schema(description = "结构专业占比")
|
||||
private BigDecimal structRatio;
|
||||
|
||||
@Schema(description = "给排水专业占比")
|
||||
private BigDecimal waterRatio;
|
||||
|
||||
@Schema(description = "暖通专业占比")
|
||||
private BigDecimal hvacRatio;
|
||||
|
||||
@Schema(description = "电气专业占比")
|
||||
private BigDecimal elecRatio;
|
||||
|
||||
@Schema(description = "数字化设计专业占比")
|
||||
private BigDecimal digitalRatio;
|
||||
|
||||
@Schema(description = "建筑专业考核产值,万元")
|
||||
private BigDecimal archAssessmentOutputWan;
|
||||
|
||||
@Schema(description = "精装专业考核产值,万元")
|
||||
private BigDecimal decorAssessmentOutputWan;
|
||||
|
||||
@Schema(description = "结构专业考核产值,万元")
|
||||
private BigDecimal structAssessmentOutputWan;
|
||||
|
||||
@Schema(description = "给排水专业考核产值,万元")
|
||||
private BigDecimal waterAssessmentOutputWan;
|
||||
|
||||
@Schema(description = "暖通专业考核产值,万元")
|
||||
private BigDecimal hvacAssessmentOutputWan;
|
||||
|
||||
@Schema(description = "电气专业考核产值,万元")
|
||||
private BigDecimal elecAssessmentOutputWan;
|
||||
|
||||
@Schema(description = "数字化设计专业考核产值,万元")
|
||||
private BigDecimal digitalAssessmentOutputWan;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 专业内人员年度季度计取预览 Request VO")
|
||||
@Data
|
||||
public class SpecialtyPersonOutputPreviewReqVO {
|
||||
|
||||
@Schema(description = "合约规划 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "合约规划 ID 不能为空")
|
||||
private Long planningId;
|
||||
|
||||
@Schema(description = "预览年度", example = "2026")
|
||||
private Integer year;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 专业内人员年度季度计取预览 Response VO")
|
||||
@Data
|
||||
public class SpecialtyPersonOutputPreviewRespVO {
|
||||
|
||||
@Schema(description = "锚点合约规划 ID")
|
||||
private Long planningId;
|
||||
|
||||
@Schema(description = "预览年度")
|
||||
private Integer year;
|
||||
|
||||
@Schema(description = "项目名称")
|
||||
private String projectName;
|
||||
|
||||
@Schema(description = "专业分组")
|
||||
private List<GroupRow> groups;
|
||||
|
||||
@Schema(description = "专业分组")
|
||||
@Data
|
||||
public static class GroupRow {
|
||||
|
||||
@Schema(description = "专业编码")
|
||||
private String specialtyCode;
|
||||
|
||||
@Schema(description = "专业名称")
|
||||
private String specialtyName;
|
||||
|
||||
@Schema(description = "是否允许导出专业内人员计取表")
|
||||
private Boolean exportable;
|
||||
|
||||
@Schema(description = "专业金额(元)")
|
||||
private BigDecimal specialtyAmount;
|
||||
|
||||
@Schema(description = "角色比例合计")
|
||||
private BigDecimal roleTotal;
|
||||
|
||||
@Schema(description = "已配置人数")
|
||||
private Integer personCount;
|
||||
|
||||
@Schema(description = "是否超额")
|
||||
private Boolean overRatio;
|
||||
|
||||
@Schema(description = "专业一季度金额(万元)")
|
||||
private BigDecimal specialtyQuarterOneAmountWan;
|
||||
|
||||
@Schema(description = "专业二季度金额(万元)")
|
||||
private BigDecimal specialtyQuarterTwoAmountWan;
|
||||
|
||||
@Schema(description = "专业三季度金额(万元)")
|
||||
private BigDecimal specialtyQuarterThreeAmountWan;
|
||||
|
||||
@Schema(description = "专业四季度金额(万元)")
|
||||
private BigDecimal specialtyQuarterFourAmountWan;
|
||||
|
||||
@Schema(description = "专业本年度小计金额(万元)")
|
||||
private BigDecimal specialtyYearTotalAmountWan;
|
||||
|
||||
@Schema(description = "角色人员年度季度计取明细")
|
||||
private List<RoleRow> rows;
|
||||
|
||||
}
|
||||
|
||||
@Schema(description = "角色人员年度季度计取明细")
|
||||
@Data
|
||||
public static class RoleRow {
|
||||
|
||||
@Schema(description = "专业编码")
|
||||
private String specialtyCode;
|
||||
|
||||
@Schema(description = "专业名称")
|
||||
private String specialtyName;
|
||||
|
||||
@Schema(description = "角色编码")
|
||||
private String roleCode;
|
||||
|
||||
@Schema(description = "角色名称")
|
||||
private String roleName;
|
||||
|
||||
@Schema(description = "角色比例")
|
||||
private BigDecimal roleRatio;
|
||||
|
||||
@Schema(description = "角色金额(元)")
|
||||
private BigDecimal roleAmount;
|
||||
|
||||
@Schema(description = "人员比例合计")
|
||||
private BigDecimal personTotalRatio;
|
||||
|
||||
@Schema(description = "人员明细")
|
||||
private List<PersonRow> persons;
|
||||
|
||||
}
|
||||
|
||||
@Schema(description = "人员年度季度计取明细")
|
||||
@Data
|
||||
public static class PersonRow {
|
||||
|
||||
@Schema(description = "人员唯一键")
|
||||
private String personKey;
|
||||
|
||||
@Schema(description = "员工 ID")
|
||||
private Long employeeId;
|
||||
|
||||
@Schema(description = "员工姓名")
|
||||
private String employeeName;
|
||||
|
||||
@Schema(description = "人员工作量比例")
|
||||
private BigDecimal personRatio;
|
||||
|
||||
@Schema(description = "人员金额(元)")
|
||||
private BigDecimal personAmount;
|
||||
|
||||
@Schema(description = "参与角色")
|
||||
private String roleNames;
|
||||
|
||||
@Schema(description = "占专业比例合计")
|
||||
private BigDecimal adjustedPersonRatio;
|
||||
|
||||
@Schema(description = "一季度比例")
|
||||
private BigDecimal quarterOneRatio;
|
||||
|
||||
@Schema(description = "一季度金额(万元)")
|
||||
private BigDecimal quarterOneAmountWan;
|
||||
|
||||
@Schema(description = "二季度比例")
|
||||
private BigDecimal quarterTwoRatio;
|
||||
|
||||
@Schema(description = "二季度金额(万元)")
|
||||
private BigDecimal quarterTwoAmountWan;
|
||||
|
||||
@Schema(description = "三季度比例")
|
||||
private BigDecimal quarterThreeRatio;
|
||||
|
||||
@Schema(description = "三季度金额(万元)")
|
||||
private BigDecimal quarterThreeAmountWan;
|
||||
|
||||
@Schema(description = "四季度比例")
|
||||
private BigDecimal quarterFourRatio;
|
||||
|
||||
@Schema(description = "四季度金额(万元)")
|
||||
private BigDecimal quarterFourAmountWan;
|
||||
|
||||
@Schema(description = "本年度小计比例")
|
||||
private BigDecimal yearTotalRatio;
|
||||
|
||||
@Schema(description = "本年度小计金额(万元)")
|
||||
private BigDecimal yearTotalAmountWan;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,4 +21,7 @@ public class SpecialtyRoleSplitBatchSaveReqVO {
|
||||
@Valid
|
||||
private List<SpecialtyRoleSplitSaveItemReqVO> items;
|
||||
|
||||
@Schema(description = "是否临时保存。true 时仅做基础格式处理,跳过角色合计、设计人员必填等强校验", example = "false")
|
||||
private Boolean temporarySave;
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ public class EmployeeDO extends TenantBaseDO {
|
||||
|
||||
private String remark;
|
||||
|
||||
private Boolean officeLeaderFlag;
|
||||
|
||||
private Integer sortNo;
|
||||
|
||||
private Boolean enabledFlag;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.dal.dataobject.employeeyearleaderoutput;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@TableName("tjt_employee_year_leader_output")
|
||||
@KeySequence("tjt_employee_year_leader_output_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class EmployeeYearLeaderOutputDO extends TenantBaseDO {
|
||||
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
private Long employeeId;
|
||||
|
||||
private String employeeName;
|
||||
|
||||
private Integer outputYear;
|
||||
|
||||
private BigDecimal leaderOutputAmount;
|
||||
|
||||
private String remark;
|
||||
|
||||
private Integer sortNo;
|
||||
|
||||
private Boolean enabledFlag;
|
||||
|
||||
}
|
||||
@@ -25,7 +25,7 @@ public class ProjectPlanningDO extends TenantBaseDO {
|
||||
|
||||
private Long projectId;
|
||||
|
||||
private Integer sortNo;
|
||||
private String sortNo;
|
||||
|
||||
private String ownershipType;
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@ public class ProjectPlanningQuarterDO extends TenantBaseDO {
|
||||
|
||||
private Long planningId;
|
||||
|
||||
private Long guideDetailId;
|
||||
|
||||
private Integer guideDetailSortNo;
|
||||
|
||||
private Integer distributionYear;
|
||||
|
||||
private Integer quarterNo;
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.dal.dataobject.profit;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 项目成本测算快照 DO
|
||||
*
|
||||
* @author Codex
|
||||
*/
|
||||
@TableName("tjt_project_cost_measure_snapshot")
|
||||
@KeySequence("tjt_project_cost_measure_snapshot_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ProjectCostMeasureSnapshotDO extends TenantBaseDO {
|
||||
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
private Long projectId;
|
||||
|
||||
private String snapshotType;
|
||||
|
||||
private Boolean lockedFlag;
|
||||
|
||||
private Long actionUserId;
|
||||
|
||||
private String actionUserName;
|
||||
|
||||
private LocalDateTime actionTime;
|
||||
|
||||
private BigDecimal contractAmount;
|
||||
|
||||
private BigDecimal finalSettlementAmount;
|
||||
|
||||
private BigDecimal effectiveSettlementAmount;
|
||||
|
||||
private BigDecimal comprehensivePlanningAmount;
|
||||
|
||||
private BigDecimal subcontractPlanningAmount;
|
||||
|
||||
private BigDecimal specialSubcontractPlanningAmount;
|
||||
|
||||
private BigDecimal sourceCoopSubcontractPlanningAmount;
|
||||
|
||||
private BigDecimal comprehensiveSubcontractPlanningAmount;
|
||||
|
||||
private BigDecimal majorOutputValue;
|
||||
|
||||
private BigDecimal majorExpectedPerformance;
|
||||
|
||||
private BigDecimal innovationOutputRate;
|
||||
|
||||
private BigDecimal innovationOutputValue;
|
||||
|
||||
private BigDecimal otherCost;
|
||||
|
||||
private BigDecimal profitLossValue;
|
||||
|
||||
private BigDecimal profitLossRate;
|
||||
|
||||
private String assessmentResult;
|
||||
|
||||
private BigDecimal assessmentCoefficient;
|
||||
|
||||
private BigDecimal comprehensiveAccountingOutputValue;
|
||||
|
||||
private BigDecimal comprehensiveSettlementOutputValue;
|
||||
|
||||
private BigDecimal majorAccountingOutputValue;
|
||||
|
||||
private BigDecimal majorSettlementOutputValue;
|
||||
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@@ -34,17 +34,17 @@ public class ProjectDO extends TenantBaseDO {
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sortNo;
|
||||
private String sortNo;
|
||||
/**
|
||||
* 是否签订合同
|
||||
*/
|
||||
private Boolean contractSignedFlag;
|
||||
/**
|
||||
* 合同产值
|
||||
* 合同总产值
|
||||
*/
|
||||
private BigDecimal contractAmount;
|
||||
/**
|
||||
* 工程总面积
|
||||
* 建筑面积
|
||||
*/
|
||||
private BigDecimal totalConstructionArea;
|
||||
/**
|
||||
@@ -68,7 +68,7 @@ public class ProjectDO extends TenantBaseDO {
|
||||
*/
|
||||
private String projectType;
|
||||
/**
|
||||
* 工程类别
|
||||
* 设计类型
|
||||
*/
|
||||
private String projectCategory;
|
||||
/**
|
||||
@@ -96,7 +96,7 @@ public class ProjectDO extends TenantBaseDO {
|
||||
*/
|
||||
private String terminateReason;
|
||||
/**
|
||||
* 最终结算金额
|
||||
* 结算合同总产值
|
||||
*/
|
||||
private BigDecimal finalSettlementAmount;
|
||||
/**
|
||||
|
||||
@@ -35,8 +35,6 @@ public class SpecialtyRoleSplitDO extends TenantBaseDO {
|
||||
|
||||
private BigDecimal roleRatio;
|
||||
|
||||
private String personsJson;
|
||||
|
||||
private Integer sortNo;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.dal.dataobject.specialtyrolesplitperson;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 页面 5 角色人员分配明细 DO
|
||||
*
|
||||
* @author Codex
|
||||
*/
|
||||
@TableName("tjt_specialty_role_split_person")
|
||||
@KeySequence("tjt_specialty_role_split_person_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SpecialtyRoleSplitPersonDO extends TenantBaseDO {
|
||||
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
private Long roleSplitId;
|
||||
|
||||
private Long outputSplitId;
|
||||
|
||||
private Long projectId;
|
||||
|
||||
private Long planningId;
|
||||
|
||||
private String specialtyCode;
|
||||
|
||||
private String specialtyName;
|
||||
|
||||
private String roleCode;
|
||||
|
||||
private String roleName;
|
||||
|
||||
private Long employeeId;
|
||||
|
||||
private String employeeName;
|
||||
|
||||
private BigDecimal personRatio;
|
||||
|
||||
private Integer sortNo;
|
||||
|
||||
}
|
||||
@@ -18,16 +18,34 @@ public interface EmployeeMapper extends BaseMapperX<EmployeeDO> {
|
||||
.eqIfPresent(EmployeeDO::getOfficeId, reqVO.getOfficeId())
|
||||
.eqIfPresent(EmployeeDO::getEmployeeStatus, reqVO.getEmployeeStatus())
|
||||
.eqIfPresent(EmployeeDO::getEnabledFlag, reqVO.getEnabledFlag())
|
||||
.eqIfPresent(EmployeeDO::getOfficeLeaderFlag, reqVO.getOfficeLeaderFlag())
|
||||
.orderByAsc(EmployeeDO::getSortNo)
|
||||
.orderByAsc(EmployeeDO::getId));
|
||||
}
|
||||
|
||||
default List<EmployeeDO> selectSimpleList(String keyword, Long officeId, String status, Boolean enabledFlag) {
|
||||
default List<EmployeeDO> selectSimpleList(String keyword, Long officeId, String status, Boolean enabledFlag,
|
||||
Boolean officeLeaderFlag) {
|
||||
return selectList(new LambdaQueryWrapperX<EmployeeDO>()
|
||||
.likeIfPresent(EmployeeDO::getEmployeeName, keyword)
|
||||
.eqIfPresent(EmployeeDO::getOfficeId, officeId)
|
||||
.eqIfPresent(EmployeeDO::getEmployeeStatus, status)
|
||||
.eqIfPresent(EmployeeDO::getEnabledFlag, enabledFlag)
|
||||
.eqIfPresent(EmployeeDO::getOfficeLeaderFlag, officeLeaderFlag)
|
||||
.orderByAsc(EmployeeDO::getSortNo)
|
||||
.orderByAsc(EmployeeDO::getId));
|
||||
}
|
||||
|
||||
default List<EmployeeDO> selectEnabledList() {
|
||||
return selectList(new LambdaQueryWrapperX<EmployeeDO>()
|
||||
.eq(EmployeeDO::getEnabledFlag, Boolean.TRUE)
|
||||
.orderByAsc(EmployeeDO::getSortNo)
|
||||
.orderByAsc(EmployeeDO::getId));
|
||||
}
|
||||
|
||||
default List<EmployeeDO> selectEnabledLeaderList() {
|
||||
return selectList(new LambdaQueryWrapperX<EmployeeDO>()
|
||||
.eq(EmployeeDO::getEnabledFlag, Boolean.TRUE)
|
||||
.eq(EmployeeDO::getOfficeLeaderFlag, Boolean.TRUE)
|
||||
.orderByAsc(EmployeeDO::getSortNo)
|
||||
.orderByAsc(EmployeeDO::getId));
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.E
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employeeyearcostbudget.EmployeeYearCostBudgetDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface EmployeeYearCostBudgetMapper extends BaseMapperX<EmployeeYearCostBudgetDO> {
|
||||
|
||||
@@ -27,6 +29,11 @@ public interface EmployeeYearCostBudgetMapper extends BaseMapperX<EmployeeYearCo
|
||||
.eq(EmployeeYearCostBudgetDO::getBudgetYear, budgetYear));
|
||||
}
|
||||
|
||||
default List<EmployeeYearCostBudgetDO> selectListByBudgetYear(Integer budgetYear) {
|
||||
return selectList(new LambdaQueryWrapperX<EmployeeYearCostBudgetDO>()
|
||||
.eq(EmployeeYearCostBudgetDO::getBudgetYear, budgetYear));
|
||||
}
|
||||
|
||||
default Long selectCountByEmployeeId(Long employeeId) {
|
||||
return selectCount(new LambdaQueryWrapperX<EmployeeYearCostBudgetDO>()
|
||||
.eq(EmployeeYearCostBudgetDO::getEmployeeId, employeeId));
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.dal.mysql.employeeyearleaderoutput;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.lyzsys.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo.EmployeeYearLeaderOutputPageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employeeyearleaderoutput.EmployeeYearLeaderOutputDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface EmployeeYearLeaderOutputMapper extends BaseMapperX<EmployeeYearLeaderOutputDO> {
|
||||
|
||||
default PageResult<EmployeeYearLeaderOutputDO> selectPage(EmployeeYearLeaderOutputPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<EmployeeYearLeaderOutputDO>()
|
||||
.eqIfPresent(EmployeeYearLeaderOutputDO::getEmployeeId, reqVO.getEmployeeId())
|
||||
.likeIfPresent(EmployeeYearLeaderOutputDO::getEmployeeName, reqVO.getEmployeeName())
|
||||
.eqIfPresent(EmployeeYearLeaderOutputDO::getOutputYear, reqVO.getOutputYear())
|
||||
.eqIfPresent(EmployeeYearLeaderOutputDO::getEnabledFlag, reqVO.getEnabledFlag())
|
||||
.orderByDesc(EmployeeYearLeaderOutputDO::getOutputYear)
|
||||
.orderByAsc(EmployeeYearLeaderOutputDO::getSortNo)
|
||||
.orderByAsc(EmployeeYearLeaderOutputDO::getId));
|
||||
}
|
||||
|
||||
default EmployeeYearLeaderOutputDO selectByEmployeeIdAndOutputYear(Long employeeId, Integer outputYear) {
|
||||
return selectOne(new LambdaQueryWrapperX<EmployeeYearLeaderOutputDO>()
|
||||
.eq(EmployeeYearLeaderOutputDO::getEmployeeId, employeeId)
|
||||
.eq(EmployeeYearLeaderOutputDO::getOutputYear, outputYear));
|
||||
}
|
||||
|
||||
default List<EmployeeYearLeaderOutputDO> selectListByOutputYear(Integer outputYear) {
|
||||
return selectList(new LambdaQueryWrapperX<EmployeeYearLeaderOutputDO>()
|
||||
.eq(EmployeeYearLeaderOutputDO::getOutputYear, outputYear));
|
||||
}
|
||||
|
||||
default List<EmployeeYearLeaderOutputDO> selectEnabledListByOutputYear(Integer outputYear,
|
||||
Collection<Long> employeeIds) {
|
||||
return selectList(new LambdaQueryWrapperX<EmployeeYearLeaderOutputDO>()
|
||||
.eq(EmployeeYearLeaderOutputDO::getOutputYear, outputYear)
|
||||
.eq(EmployeeYearLeaderOutputDO::getEnabledFlag, Boolean.TRUE)
|
||||
.inIfPresent(EmployeeYearLeaderOutputDO::getEmployeeId, employeeIds)
|
||||
.orderByAsc(EmployeeYearLeaderOutputDO::getSortNo)
|
||||
.orderByAsc(EmployeeYearLeaderOutputDO::getId));
|
||||
}
|
||||
|
||||
default Long selectCountByEmployeeId(Long employeeId) {
|
||||
return selectCount(new LambdaQueryWrapperX<EmployeeYearLeaderOutputDO>()
|
||||
.eq(EmployeeYearLeaderOutputDO::getEmployeeId, employeeId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,8 +25,7 @@ public interface ProjectPlanningMapper extends BaseMapperX<ProjectPlanningDO> {
|
||||
.likeIfPresent(ProjectPlanningDO::getPlanningContent, reqVO.getPlanningContent())
|
||||
.eqIfPresent(ProjectPlanningDO::getPlanningStartYear, reqVO.getPlanningStartYear())
|
||||
.betweenIfPresent(ProjectPlanningDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByAsc(ProjectPlanningDO::getSortNo)
|
||||
.orderByAsc(ProjectPlanningDO::getId));
|
||||
.last("ORDER BY CASE WHEN sort_no IS NULL OR sort_no = N'' THEN 1 ELSE 0 END, sort_no ASC, id ASC"));
|
||||
}
|
||||
|
||||
default List<ProjectPlanningDO> selectListByProjectId(Long projectId) {
|
||||
@@ -38,8 +37,7 @@ public interface ProjectPlanningMapper extends BaseMapperX<ProjectPlanningDO> {
|
||||
default List<ProjectPlanningDO> selectDisplayListByProjectId(Long projectId) {
|
||||
return selectList(new LambdaQueryWrapperX<ProjectPlanningDO>()
|
||||
.eq(ProjectPlanningDO::getProjectId, projectId)
|
||||
.orderByAsc(ProjectPlanningDO::getSortNo)
|
||||
.orderByAsc(ProjectPlanningDO::getId));
|
||||
.last("ORDER BY CASE WHEN sort_no IS NULL OR sort_no = N'' THEN 1 ELSE 0 END, sort_no ASC, id ASC"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,25 +20,102 @@ public interface ProjectPlanningQuarterMapper extends BaseMapperX<ProjectPlannin
|
||||
default ProjectPlanningQuarterDO selectByPlanningIdAndDistributionYearAndQuarter(Long planningId,
|
||||
Integer distributionYear,
|
||||
Integer quarterNo) {
|
||||
return selectOne(ProjectPlanningQuarterDO::getPlanningId, planningId,
|
||||
ProjectPlanningQuarterDO::getDistributionYear, distributionYear,
|
||||
ProjectPlanningQuarterDO::getQuarterNo, quarterNo);
|
||||
return selectParentByPlanningIdAndDistributionYearAndQuarter(planningId, distributionYear, quarterNo);
|
||||
}
|
||||
|
||||
default ProjectPlanningQuarterDO selectParentByPlanningIdAndDistributionYearAndQuarter(Long planningId,
|
||||
Integer distributionYear,
|
||||
Integer quarterNo) {
|
||||
return selectOne(new LambdaQueryWrapperX<ProjectPlanningQuarterDO>()
|
||||
.eq(ProjectPlanningQuarterDO::getPlanningId, planningId)
|
||||
.eq(ProjectPlanningQuarterDO::getDistributionYear, distributionYear)
|
||||
.eq(ProjectPlanningQuarterDO::getQuarterNo, quarterNo)
|
||||
.isNull(ProjectPlanningQuarterDO::getGuideDetailId));
|
||||
}
|
||||
|
||||
default ProjectPlanningQuarterDO selectByPlanningIdAndGuideDetailIdAndDistributionYearAndQuarter(
|
||||
Long planningId, Long guideDetailId, Integer distributionYear, Integer quarterNo) {
|
||||
return selectOne(new LambdaQueryWrapperX<ProjectPlanningQuarterDO>()
|
||||
.eq(ProjectPlanningQuarterDO::getPlanningId, planningId)
|
||||
.eq(ProjectPlanningQuarterDO::getGuideDetailId, guideDetailId)
|
||||
.eq(ProjectPlanningQuarterDO::getDistributionYear, distributionYear)
|
||||
.eq(ProjectPlanningQuarterDO::getQuarterNo, quarterNo));
|
||||
}
|
||||
|
||||
default List<ProjectPlanningQuarterDO> selectListByPlanningId(Long planningId) {
|
||||
return selectList(new LambdaQueryWrapperX<ProjectPlanningQuarterDO>()
|
||||
.eq(ProjectPlanningQuarterDO::getPlanningId, planningId)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getGuideDetailSortNo)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getGuideDetailId)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getDistributionYear)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getQuarterNo)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getId));
|
||||
}
|
||||
|
||||
default List<ProjectPlanningQuarterDO> selectParentListByPlanningId(Long planningId) {
|
||||
return selectList(new LambdaQueryWrapperX<ProjectPlanningQuarterDO>()
|
||||
.eq(ProjectPlanningQuarterDO::getPlanningId, planningId)
|
||||
.isNull(ProjectPlanningQuarterDO::getGuideDetailId)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getDistributionYear)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getQuarterNo)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getId));
|
||||
}
|
||||
|
||||
default List<ProjectPlanningQuarterDO> selectDetailListByPlanningId(Long planningId) {
|
||||
return selectList(new LambdaQueryWrapperX<ProjectPlanningQuarterDO>()
|
||||
.eq(ProjectPlanningQuarterDO::getPlanningId, planningId)
|
||||
.isNotNull(ProjectPlanningQuarterDO::getGuideDetailId)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getGuideDetailSortNo)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getGuideDetailId)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getDistributionYear)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getQuarterNo)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getId));
|
||||
}
|
||||
|
||||
default List<ProjectPlanningQuarterDO> selectListByGuideDetailId(Long guideDetailId) {
|
||||
return selectList(new LambdaQueryWrapperX<ProjectPlanningQuarterDO>()
|
||||
.eq(ProjectPlanningQuarterDO::getGuideDetailId, guideDetailId)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getDistributionYear)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getQuarterNo)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getId));
|
||||
}
|
||||
|
||||
default List<ProjectPlanningQuarterDO> selectListByGuideDetailIds(Collection<Long> guideDetailIds) {
|
||||
if (guideDetailIds == null || guideDetailIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<ProjectPlanningQuarterDO>()
|
||||
.in(ProjectPlanningQuarterDO::getGuideDetailId, guideDetailIds)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getGuideDetailSortNo)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getGuideDetailId)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getDistributionYear)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getQuarterNo)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getId));
|
||||
}
|
||||
|
||||
default boolean existsParentQuarter(Long planningId, Long excludeId) {
|
||||
return selectCount(new LambdaQueryWrapperX<ProjectPlanningQuarterDO>()
|
||||
.eq(ProjectPlanningQuarterDO::getPlanningId, planningId)
|
||||
.isNull(ProjectPlanningQuarterDO::getGuideDetailId)
|
||||
.ne(excludeId != null, ProjectPlanningQuarterDO::getId, excludeId)) > 0;
|
||||
}
|
||||
|
||||
default boolean existsGuideDetailQuarter(Long planningId, Long excludeId) {
|
||||
return selectCount(new LambdaQueryWrapperX<ProjectPlanningQuarterDO>()
|
||||
.eq(ProjectPlanningQuarterDO::getPlanningId, planningId)
|
||||
.isNotNull(ProjectPlanningQuarterDO::getGuideDetailId)
|
||||
.ne(excludeId != null, ProjectPlanningQuarterDO::getId, excludeId)) > 0;
|
||||
}
|
||||
|
||||
default List<ProjectPlanningQuarterDO> selectListByPlanningIds(Collection<Long> planningIds) {
|
||||
if (planningIds == null || planningIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<ProjectPlanningQuarterDO>()
|
||||
.in(ProjectPlanningQuarterDO::getPlanningId, planningIds)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getPlanningId)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getGuideDetailSortNo)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getGuideDetailId)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getDistributionYear)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getQuarterNo)
|
||||
.orderByAsc(ProjectPlanningQuarterDO::getId));
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.dal.mysql.profit;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.lyzsys.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.profit.ProjectCostMeasureSnapshotDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ProjectCostMeasureSnapshotMapper extends BaseMapperX<ProjectCostMeasureSnapshotDO> {
|
||||
|
||||
default ProjectCostMeasureSnapshotDO selectByProjectIdAndType(Long projectId, String snapshotType) {
|
||||
return selectOne(new LambdaQueryWrapperX<ProjectCostMeasureSnapshotDO>()
|
||||
.eq(ProjectCostMeasureSnapshotDO::getProjectId, projectId)
|
||||
.eq(ProjectCostMeasureSnapshotDO::getSnapshotType, snapshotType));
|
||||
}
|
||||
|
||||
default List<ProjectCostMeasureSnapshotDO> selectListByProjectId(Long projectId) {
|
||||
return selectList(new LambdaQueryWrapperX<ProjectCostMeasureSnapshotDO>()
|
||||
.eq(ProjectCostMeasureSnapshotDO::getProjectId, projectId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,8 +22,7 @@ public interface ProjectMapper extends BaseMapperX<ProjectDO> {
|
||||
.eqIfPresent(ProjectDO::getProjectStartYear, reqVO.getProjectStartYear())
|
||||
.eqIfPresent(ProjectDO::getProjectStatus, reqVO.getProjectStatus())
|
||||
.betweenIfPresent(ProjectDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByAsc(ProjectDO::getSortNo)
|
||||
.orderByAsc(ProjectDO::getId));
|
||||
.last("ORDER BY CASE WHEN sort_no IS NULL OR sort_no = N'' THEN 1 ELSE 0 END, sort_no ASC, id ASC"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,6 +34,19 @@ public interface ProjectRolePersonMapper extends BaseMapperX<ProjectRolePersonDO
|
||||
.orderByAsc(ProjectRolePersonDO::getId));
|
||||
}
|
||||
|
||||
default List<ProjectRolePersonDO> selectListByEmployeeIds(Collection<Long> employeeIds) {
|
||||
if (employeeIds == null || employeeIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<ProjectRolePersonDO>()
|
||||
.in(ProjectRolePersonDO::getEmployeeId, employeeIds)
|
||||
.eq(ProjectRolePersonDO::getEnabledFlag, Boolean.TRUE)
|
||||
.orderByAsc(ProjectRolePersonDO::getProjectId)
|
||||
.orderByAsc(ProjectRolePersonDO::getRoleCode)
|
||||
.orderByAsc(ProjectRolePersonDO::getSortNo)
|
||||
.orderByAsc(ProjectRolePersonDO::getId));
|
||||
}
|
||||
|
||||
default Long selectCountByEmployeeId(Long employeeId) {
|
||||
return selectCount(new LambdaQueryWrapperX<ProjectRolePersonDO>()
|
||||
.eq(ProjectRolePersonDO::getEmployeeId, employeeId));
|
||||
|
||||
@@ -5,6 +5,8 @@ import cn.iocoder.lyzsys.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.specialtyrolesplit.SpecialtyRoleSplitDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -22,9 +24,15 @@ public interface SpecialtyRoleSplitMapper extends BaseMapperX<SpecialtyRoleSplit
|
||||
.orderByAsc(SpecialtyRoleSplitDO::getId));
|
||||
}
|
||||
|
||||
default List<SpecialtyRoleSplitDO> selectListByPersonsJsonKeyword(String keyword) {
|
||||
default List<SpecialtyRoleSplitDO> selectListByOutputSplitIds(Collection<Long> outputSplitIds) {
|
||||
if (outputSplitIds == null || outputSplitIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<SpecialtyRoleSplitDO>()
|
||||
.like(SpecialtyRoleSplitDO::getPersonsJson, keyword));
|
||||
.in(SpecialtyRoleSplitDO::getOutputSplitId, outputSplitIds)
|
||||
.orderByAsc(SpecialtyRoleSplitDO::getOutputSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitDO::getSortNo)
|
||||
.orderByAsc(SpecialtyRoleSplitDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.dal.mysql.specialtyrolesplitperson;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.lyzsys.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.specialtyrolesplitperson.SpecialtyRoleSplitPersonDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 页面 5 角色人员分配明细 Mapper
|
||||
*
|
||||
* @author Codex
|
||||
*/
|
||||
@Mapper
|
||||
public interface SpecialtyRoleSplitPersonMapper extends BaseMapperX<SpecialtyRoleSplitPersonDO> {
|
||||
|
||||
default List<SpecialtyRoleSplitPersonDO> selectListByRoleSplitId(Long roleSplitId) {
|
||||
return selectList(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.eq(SpecialtyRoleSplitPersonDO::getRoleSplitId, roleSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getSortNo)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getId));
|
||||
}
|
||||
|
||||
default List<SpecialtyRoleSplitPersonDO> selectListByRoleSplitIds(Collection<Long> roleSplitIds) {
|
||||
if (roleSplitIds == null || roleSplitIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.in(SpecialtyRoleSplitPersonDO::getRoleSplitId, roleSplitIds)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getRoleSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getSortNo)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getId));
|
||||
}
|
||||
|
||||
default List<SpecialtyRoleSplitPersonDO> selectListByOutputSplitIds(Collection<Long> outputSplitIds) {
|
||||
if (outputSplitIds == null || outputSplitIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.in(SpecialtyRoleSplitPersonDO::getOutputSplitId, outputSplitIds)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getOutputSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getRoleSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getSortNo)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getId));
|
||||
}
|
||||
|
||||
default List<SpecialtyRoleSplitPersonDO> selectListByEmployeeIds(Collection<Long> employeeIds) {
|
||||
if (employeeIds == null || employeeIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.in(SpecialtyRoleSplitPersonDO::getEmployeeId, employeeIds)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getPlanningId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getRoleSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getSortNo)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getId));
|
||||
}
|
||||
|
||||
default List<SpecialtyRoleSplitPersonDO> selectListByPlanningIdsAndEmployeeIds(Collection<Long> planningIds,
|
||||
Collection<Long> employeeIds) {
|
||||
if (planningIds == null || planningIds.isEmpty() || employeeIds == null || employeeIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.in(SpecialtyRoleSplitPersonDO::getPlanningId, planningIds)
|
||||
.in(SpecialtyRoleSplitPersonDO::getEmployeeId, employeeIds)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getPlanningId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getRoleSplitId)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getSortNo)
|
||||
.orderByAsc(SpecialtyRoleSplitPersonDO::getId));
|
||||
}
|
||||
|
||||
default void deleteByRoleSplitId(Long roleSplitId) {
|
||||
delete(SpecialtyRoleSplitPersonDO::getRoleSplitId, roleSplitId);
|
||||
}
|
||||
|
||||
default void deleteByRoleSplitIds(Collection<Long> roleSplitIds) {
|
||||
if (roleSplitIds == null || roleSplitIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
delete(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.in(SpecialtyRoleSplitPersonDO::getRoleSplitId, roleSplitIds));
|
||||
}
|
||||
|
||||
default void deleteByOutputSplitId(Long outputSplitId) {
|
||||
delete(SpecialtyRoleSplitPersonDO::getOutputSplitId, outputSplitId);
|
||||
}
|
||||
|
||||
default void deleteByOutputSplitIds(Collection<Long> outputSplitIds) {
|
||||
if (outputSplitIds == null || outputSplitIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
delete(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.in(SpecialtyRoleSplitPersonDO::getOutputSplitId, outputSplitIds));
|
||||
}
|
||||
|
||||
default Long selectCountByEmployeeId(Long employeeId) {
|
||||
return selectCount(new LambdaQueryWrapperX<SpecialtyRoleSplitPersonDO>()
|
||||
.eq(SpecialtyRoleSplitPersonDO::getEmployeeId, employeeId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,7 @@ public interface ErrorCodeConstants {
|
||||
|
||||
// ========== 项目管理 1-020-001-000 ==========
|
||||
ErrorCode PROJECT_NOT_EXISTS = new ErrorCode(1_020_001_000, "项目不存在");
|
||||
ErrorCode PROJECT_STATUS_INVALID = new ErrorCode(1_020_001_001, "项目状态不正确");
|
||||
|
||||
// ========== 合约规划管理 1-020-002-000 ==========
|
||||
ErrorCode PROJECT_PLANNING_NOT_EXISTS = new ErrorCode(1_020_002_000, "合约规划不存在");
|
||||
@@ -25,11 +26,16 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode PROJECT_PLANNING_DESIGN_PART_INVALID = new ErrorCode(1_020_002_009, "设计部位不正确");
|
||||
ErrorCode PROJECT_PLANNING_GUIDE_DETAIL_NOT_EXISTS = new ErrorCode(1_020_002_010, "指导价法明细不存在");
|
||||
ErrorCode PROJECT_PLANNING_GUIDE_DETAIL_SCENE_INVALID = new ErrorCode(1_020_002_011, "当前合约规划不是专业所指导价法,不能维护指导价法明细");
|
||||
ErrorCode PROJECT_PLANNING_DESIGN_STAGE_INVALID = new ErrorCode(1_020_002_012, "设计阶段不正确");
|
||||
|
||||
// ========== 季度分配管理 1-020-003-000 ==========
|
||||
ErrorCode PROJECT_PLANNING_QUARTER_NOT_EXISTS = new ErrorCode(1_020_003_000, "季度分配明细不存在");
|
||||
ErrorCode PROJECT_PLANNING_QUARTER_DUPLICATE = new ErrorCode(1_020_003_001, "同一合约规划下该年度季度分配已存在");
|
||||
ErrorCode PROJECT_PLANNING_QUARTER_PLANNING_NOT_EXISTS = new ErrorCode(1_020_003_002, "关联合约规划不存在");
|
||||
ErrorCode PROJECT_PLANNING_QUARTER_GUIDE_DETAIL_REQUIRED = new ErrorCode(1_020_003_003, "专业所指导价法季度分配必须选择指导价法明细");
|
||||
ErrorCode PROJECT_PLANNING_QUARTER_GUIDE_DETAIL_INVALID = new ErrorCode(1_020_003_004, "指导价法明细不属于当前合约规划");
|
||||
ErrorCode PROJECT_PLANNING_QUARTER_GUIDE_DETAIL_NOT_ALLOWED = new ErrorCode(1_020_003_005, "非专业所指导价法季度分配不能选择指导价法明细");
|
||||
ErrorCode PROJECT_PLANNING_QUARTER_SCOPE_MIXED = new ErrorCode(1_020_003_006, "当前合约规划同时存在父级和明细季度分配,请先清理后再保存");
|
||||
|
||||
// ========== 页面 4 拆分管理 1-020-004-000 ==========
|
||||
ErrorCode PROJECT_OUTPUT_SPLIT_PLANNING_NOT_EXISTS = new ErrorCode(1_020_004_000, "关联合约规划不存在");
|
||||
@@ -55,9 +61,20 @@ public interface ErrorCodeConstants {
|
||||
// ========== 员工管理 1-020-008-000 ==========
|
||||
ErrorCode EMPLOYEE_NOT_EXISTS = new ErrorCode(1_020_008_000, "员工记录不存在");
|
||||
ErrorCode EMPLOYEE_IN_USE = new ErrorCode(1_020_008_001, "当前员工已被业务数据引用,不能删除");
|
||||
ErrorCode EMPLOYEE_NOT_OFFICE_LEADER = new ErrorCode(1_020_008_002, "当前员工未启用或未标记为所长,不能维护年度所长考核产值");
|
||||
|
||||
// ========== 员工年度成本预算 1-020-009-000 ==========
|
||||
ErrorCode EMPLOYEE_YEAR_COST_BUDGET_NOT_EXISTS = new ErrorCode(1_020_009_000, "员工年度成本预算记录不存在");
|
||||
ErrorCode EMPLOYEE_YEAR_COST_BUDGET_DUPLICATE = new ErrorCode(1_020_009_001, "当前员工该年度预计发生成本已存在");
|
||||
|
||||
// ========== 年度所长考核产值 1-020-010-000 ==========
|
||||
ErrorCode EMPLOYEE_YEAR_LEADER_OUTPUT_NOT_EXISTS = new ErrorCode(1_020_010_000, "年度所长考核产值记录不存在");
|
||||
ErrorCode EMPLOYEE_YEAR_LEADER_OUTPUT_DUPLICATE = new ErrorCode(1_020_010_001, "当前所长该年度考核产值已存在");
|
||||
|
||||
// ========== 项目成本测算快照 1-020-011-000 ==========
|
||||
ErrorCode PROJECT_COST_MEASURE_BUDGET_LOCKED = new ErrorCode(1_020_011_000, "目标责任书已下达,不能重复操作");
|
||||
ErrorCode PROJECT_COST_MEASURE_ACCOUNTING_LOCKED = new ErrorCode(1_020_011_001, "竣工验收已完成,不能重复操作");
|
||||
ErrorCode PROJECT_COST_MEASURE_ACCOUNTING_REQUIRED = new ErrorCode(1_020_011_002, "请先完成竣工验收,生成项目成本核算测算后再维护结算测算");
|
||||
ErrorCode PROJECT_COST_MEASURE_BUDGET_REQUIRED = new ErrorCode(1_020_011_003, "请先下达目标责任书,生成项目成本预算测算后再完成竣工验收");
|
||||
|
||||
}
|
||||
|
||||
@@ -15,55 +15,55 @@ import java.util.Map;
|
||||
*/
|
||||
public final class OutputSplitBizConstants {
|
||||
|
||||
public static final String SPECIALTY_PROJECT_LEAD = "project_lead";
|
||||
public static final String SPECIALTY_ARCH = "arch";
|
||||
public static final String SPECIALTY_DECOR = "decor";
|
||||
public static final String SPECIALTY_STRUCT = "struct";
|
||||
public static final String SPECIALTY_WATER = "water";
|
||||
public static final String SPECIALTY_ELEC = "elec";
|
||||
public static final String SPECIALTY_HVAC = "hvac";
|
||||
public static final String SPECIALTY_DIGITAL = "digital";
|
||||
public static final String SPECIALTY_PROJECT_LEAD = OutputSplitSpecialtyEnum.PROJECT_LEAD.getCode();
|
||||
public static final String SPECIALTY_ARCH = OutputSplitSpecialtyEnum.ARCH.getCode();
|
||||
public static final String SPECIALTY_DECOR = OutputSplitSpecialtyEnum.DECOR.getCode();
|
||||
public static final String SPECIALTY_STRUCT = OutputSplitSpecialtyEnum.STRUCT.getCode();
|
||||
public static final String SPECIALTY_WATER = OutputSplitSpecialtyEnum.WATER.getCode();
|
||||
public static final String SPECIALTY_ELEC = OutputSplitSpecialtyEnum.ELEC.getCode();
|
||||
public static final String SPECIALTY_HVAC = OutputSplitSpecialtyEnum.HVAC.getCode();
|
||||
public static final String SPECIALTY_DIGITAL = OutputSplitSpecialtyEnum.DIGITAL.getCode();
|
||||
|
||||
public static final String ROLE_DIRECTOR = "director";
|
||||
public static final String ROLE_CHECK = "check";
|
||||
public static final String ROLE_REVIEW = "review";
|
||||
public static final String ROLE_APPROVE = "approve";
|
||||
public static final String ROLE_DESIGN = "design";
|
||||
public static final String ROLE_PROJECT_MANAGER = "project_manager";
|
||||
public static final String ROLE_ENGINEERING_PRINCIPAL = "engineering_principal";
|
||||
public static final String ROLE_DIRECTOR = OutputSplitRoleEnum.DIRECTOR.getCode();
|
||||
public static final String ROLE_CHECK = OutputSplitRoleEnum.CHECK.getCode();
|
||||
public static final String ROLE_REVIEW = OutputSplitRoleEnum.REVIEW.getCode();
|
||||
public static final String ROLE_APPROVE = OutputSplitRoleEnum.APPROVE.getCode();
|
||||
public static final String ROLE_DESIGN = OutputSplitRoleEnum.DESIGN.getCode();
|
||||
public static final String ROLE_PROJECT_MANAGER = OutputSplitRoleEnum.PROJECT_MANAGER.getCode();
|
||||
public static final String ROLE_ENGINEERING_PRINCIPAL = OutputSplitRoleEnum.ENGINEERING_PRINCIPAL.getCode();
|
||||
|
||||
public static final List<SpecialtyItem> ASSIGNMENT_SPECIALTY_ITEMS = Arrays.asList(
|
||||
new SpecialtyItem(SPECIALTY_PROJECT_LEAD, "项目经理/工程负责人", 0),
|
||||
new SpecialtyItem(SPECIALTY_ARCH, "建筑", 1),
|
||||
new SpecialtyItem(SPECIALTY_DECOR, "装饰", 2),
|
||||
new SpecialtyItem(SPECIALTY_STRUCT, "结构", 3),
|
||||
new SpecialtyItem(SPECIALTY_WATER, "给排水", 4),
|
||||
new SpecialtyItem(SPECIALTY_ELEC, "电气", 5),
|
||||
new SpecialtyItem(SPECIALTY_HVAC, "暖通", 6),
|
||||
new SpecialtyItem(SPECIALTY_DIGITAL, "数字化设计", 7)
|
||||
new SpecialtyItem(SPECIALTY_PROJECT_LEAD, OutputSplitSpecialtyEnum.PROJECT_LEAD.getLabel(), 0),
|
||||
new SpecialtyItem(SPECIALTY_ARCH, OutputSplitSpecialtyEnum.ARCH.getLabel(), 1),
|
||||
new SpecialtyItem(SPECIALTY_DECOR, OutputSplitSpecialtyEnum.DECOR.getLabel(), 2),
|
||||
new SpecialtyItem(SPECIALTY_STRUCT, OutputSplitSpecialtyEnum.STRUCT.getLabel(), 3),
|
||||
new SpecialtyItem(SPECIALTY_WATER, OutputSplitSpecialtyEnum.WATER.getLabel(), 4),
|
||||
new SpecialtyItem(SPECIALTY_ELEC, OutputSplitSpecialtyEnum.ELEC.getLabel(), 5),
|
||||
new SpecialtyItem(SPECIALTY_HVAC, OutputSplitSpecialtyEnum.HVAC.getLabel(), 6),
|
||||
new SpecialtyItem(SPECIALTY_DIGITAL, OutputSplitSpecialtyEnum.DIGITAL.getLabel(), 7)
|
||||
);
|
||||
|
||||
public static final List<SpecialtyItem> SPECIALTY_ITEMS = Arrays.asList(
|
||||
new SpecialtyItem(SPECIALTY_ARCH, "建筑", 1),
|
||||
new SpecialtyItem(SPECIALTY_DECOR, "装饰", 2),
|
||||
new SpecialtyItem(SPECIALTY_STRUCT, "结构", 3),
|
||||
new SpecialtyItem(SPECIALTY_WATER, "给排水", 4),
|
||||
new SpecialtyItem(SPECIALTY_ELEC, "电气", 5),
|
||||
new SpecialtyItem(SPECIALTY_HVAC, "暖通", 6),
|
||||
new SpecialtyItem(SPECIALTY_DIGITAL, "数字化设计", 7)
|
||||
new SpecialtyItem(SPECIALTY_ARCH, OutputSplitSpecialtyEnum.ARCH.getLabel(), 1),
|
||||
new SpecialtyItem(SPECIALTY_DECOR, OutputSplitSpecialtyEnum.DECOR.getLabel(), 2),
|
||||
new SpecialtyItem(SPECIALTY_STRUCT, OutputSplitSpecialtyEnum.STRUCT.getLabel(), 3),
|
||||
new SpecialtyItem(SPECIALTY_WATER, OutputSplitSpecialtyEnum.WATER.getLabel(), 4),
|
||||
new SpecialtyItem(SPECIALTY_ELEC, OutputSplitSpecialtyEnum.ELEC.getLabel(), 5),
|
||||
new SpecialtyItem(SPECIALTY_HVAC, OutputSplitSpecialtyEnum.HVAC.getLabel(), 6),
|
||||
new SpecialtyItem(SPECIALTY_DIGITAL, OutputSplitSpecialtyEnum.DIGITAL.getLabel(), 7)
|
||||
);
|
||||
|
||||
public static final List<RoleItem> SPECIALTY_ROLE_ITEMS = Arrays.asList(
|
||||
new RoleItem(ROLE_DIRECTOR, "专业负责人", 1),
|
||||
new RoleItem(ROLE_CHECK, "校对", 2),
|
||||
new RoleItem(ROLE_REVIEW, "审核", 3),
|
||||
new RoleItem(ROLE_APPROVE, "审定", 4),
|
||||
new RoleItem(ROLE_DESIGN, "设计", 5)
|
||||
new RoleItem(ROLE_DIRECTOR, OutputSplitRoleEnum.DIRECTOR.getLabel(), 1),
|
||||
new RoleItem(ROLE_CHECK, OutputSplitRoleEnum.CHECK.getLabel(), 2),
|
||||
new RoleItem(ROLE_REVIEW, OutputSplitRoleEnum.REVIEW.getLabel(), 3),
|
||||
new RoleItem(ROLE_APPROVE, OutputSplitRoleEnum.APPROVE.getLabel(), 4),
|
||||
new RoleItem(ROLE_DESIGN, OutputSplitRoleEnum.DESIGN.getLabel(), 5)
|
||||
);
|
||||
|
||||
public static final List<RoleItem> PROJECT_LEAD_ROLE_ITEMS = Arrays.asList(
|
||||
new RoleItem(ROLE_PROJECT_MANAGER, "项目经理", 1),
|
||||
new RoleItem(ROLE_ENGINEERING_PRINCIPAL, "工程负责人", 2)
|
||||
new RoleItem(ROLE_PROJECT_MANAGER, OutputSplitRoleEnum.PROJECT_MANAGER.getLabel(), 1),
|
||||
new RoleItem(ROLE_ENGINEERING_PRINCIPAL, OutputSplitRoleEnum.ENGINEERING_PRINCIPAL.getLabel(), 2)
|
||||
);
|
||||
|
||||
private OutputSplitBizConstants() {
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 专业内/项目负责人角色编码枚举。
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum OutputSplitRoleEnum {
|
||||
|
||||
DIRECTOR("director", "专业负责人", 1, false),
|
||||
CHECK("check", "校对", 2, false),
|
||||
REVIEW("review", "审核", 3, false),
|
||||
APPROVE("approve", "审定", 4, false),
|
||||
DESIGN("design", "设计", 5, false),
|
||||
PROJECT_MANAGER("project_manager", "项目经理", 1, true),
|
||||
ENGINEERING_PRINCIPAL("engineering_principal", "工程负责人", 2, true);
|
||||
|
||||
private final String code;
|
||||
private final String label;
|
||||
private final Integer sortNo;
|
||||
private final boolean projectLeadRole;
|
||||
|
||||
public static OutputSplitRoleEnum of(String code) {
|
||||
return Arrays.stream(values())
|
||||
.filter(item -> item.getCode().equals(code))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static boolean contains(String code) {
|
||||
return of(code) != null;
|
||||
}
|
||||
|
||||
public static String labelOf(String code) {
|
||||
OutputSplitRoleEnum item = of(code);
|
||||
return item == null ? code : item.getLabel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 项目/专业分配专业编码枚举。
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum OutputSplitSpecialtyEnum {
|
||||
|
||||
PROJECT_LEAD("project_lead", "项目经理/工程负责人", 0, true),
|
||||
ARCH("arch", "建筑", 1, false),
|
||||
DECOR("decor", "装饰", 2, false),
|
||||
STRUCT("struct", "结构", 3, false),
|
||||
WATER("water", "给排水", 4, false),
|
||||
ELEC("elec", "电气", 5, false),
|
||||
HVAC("hvac", "暖通", 6, false),
|
||||
DIGITAL("digital", "数字化设计", 7, false);
|
||||
|
||||
private final String code;
|
||||
private final String label;
|
||||
private final Integer sortNo;
|
||||
private final boolean projectLead;
|
||||
|
||||
public static OutputSplitSpecialtyEnum of(String code) {
|
||||
return Arrays.stream(values())
|
||||
.filter(item -> item.getCode().equals(code))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static boolean contains(String code) {
|
||||
return of(code) != null;
|
||||
}
|
||||
|
||||
public static String labelOf(String code) {
|
||||
OutputSplitSpecialtyEnum item = of(code);
|
||||
return item == null ? code : item.getLabel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 项目成本测算快照类型
|
||||
*
|
||||
* @author Codex
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ProjectCostMeasureSnapshotTypeEnum {
|
||||
|
||||
BUDGET("budget", "项目成本预算测算"),
|
||||
ACCOUNTING("accounting", "项目成本核算测算"),
|
||||
SETTLEMENT("settlement", "项目成本结算测算");
|
||||
|
||||
private final String code;
|
||||
private final String label;
|
||||
|
||||
}
|
||||
@@ -1,70 +1,62 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.enums;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 合约规划业务类型常量
|
||||
* 合约规划业务类型常量。
|
||||
*
|
||||
* <p>数据库存储稳定 code,页面和 Excel 按 label 展示。</p>
|
||||
*
|
||||
* @author Codex
|
||||
*/
|
||||
public final class ProjectPlanningBizTypeConstants {
|
||||
|
||||
public static final String OWNERSHIP_TYPE_MAJOR = "专业所";
|
||||
public static final String OWNERSHIP_TYPE_COMPREHENSIVE = "综合所";
|
||||
public static final String OWNERSHIP_TYPE_SUBCONTRACT = "专业分包";
|
||||
public static final String DESIGN_PART_REAL_ESTATE = "地上部分";
|
||||
public static final String DESIGN_PART_UNDERGROUND = "地下部分";
|
||||
public static final String OWNERSHIP_TYPE_MAJOR = ProjectPlanningOwnershipTypeEnum.MAJOR.getCode();
|
||||
public static final String OWNERSHIP_TYPE_COMPREHENSIVE = ProjectPlanningOwnershipTypeEnum.COMPREHENSIVE.getCode();
|
||||
public static final String OWNERSHIP_TYPE_SPECIAL_SUBCONTRACT =
|
||||
ProjectPlanningOwnershipTypeEnum.SPECIAL_SUBCONTRACT_MAJOR.getCode();
|
||||
public static final String OWNERSHIP_TYPE_SOURCE_COOP_SUBCONTRACT =
|
||||
ProjectPlanningOwnershipTypeEnum.SPECIAL_SUBCONTRACT_SOURCE_COOP.getCode();
|
||||
public static final String OWNERSHIP_TYPE_COMPREHENSIVE_SUBCONTRACT =
|
||||
ProjectPlanningOwnershipTypeEnum.SPECIAL_SUBCONTRACT_COMPREHENSIVE.getCode();
|
||||
|
||||
public static final String CALCULATION_METHOD_GUIDANCE_PRICE = "指导价法";
|
||||
public static final String CALCULATION_METHOD_CONTRACT_PRICE = "合同价法";
|
||||
public static final String CALCULATION_METHOD_VIRTUAL_OUTPUT = "虚拟产值法";
|
||||
public static final String DESIGN_PART_REAL_ESTATE = ProjectPlanningDesignPartEnum.ABOVE_GROUND.getCode();
|
||||
public static final String DESIGN_PART_UNDERGROUND = ProjectPlanningDesignPartEnum.UNDERGROUND.getCode();
|
||||
public static final String DESIGN_PART_OTHER = ProjectPlanningDesignPartEnum.OTHER.getCode();
|
||||
|
||||
public static final String VIRTUAL_CALCULATION_METHOD_GUIDANCE_PRICE = "指导单价法";
|
||||
public static final String VIRTUAL_CALCULATION_METHOD_GUIDANCE_TOTAL_PRICE = "指导总价法";
|
||||
public static final String VIRTUAL_CALCULATION_METHOD_WORKING_DAY = "工日法";
|
||||
public static final String CALCULATION_METHOD_GUIDANCE_PRICE =
|
||||
ProjectPlanningCalculationMethodEnum.GUIDANCE_PRICE.getCode();
|
||||
public static final String CALCULATION_METHOD_CONTRACT_PRICE =
|
||||
ProjectPlanningCalculationMethodEnum.CONTRACT_PRICE.getCode();
|
||||
public static final String CALCULATION_METHOD_VIRTUAL_OUTPUT =
|
||||
ProjectPlanningCalculationMethodEnum.VIRTUAL_OUTPUT.getCode();
|
||||
|
||||
private static final Set<String> OWNERSHIP_TYPES = new HashSet<>(Arrays.asList(
|
||||
OWNERSHIP_TYPE_MAJOR,
|
||||
OWNERSHIP_TYPE_COMPREHENSIVE,
|
||||
OWNERSHIP_TYPE_SUBCONTRACT
|
||||
));
|
||||
|
||||
private static final Set<String> CALCULATION_METHODS = new HashSet<>(Arrays.asList(
|
||||
CALCULATION_METHOD_GUIDANCE_PRICE,
|
||||
CALCULATION_METHOD_CONTRACT_PRICE,
|
||||
CALCULATION_METHOD_VIRTUAL_OUTPUT
|
||||
));
|
||||
|
||||
private static final Set<String> DESIGN_PARTS = new HashSet<>(Arrays.asList(
|
||||
DESIGN_PART_REAL_ESTATE,
|
||||
DESIGN_PART_UNDERGROUND
|
||||
));
|
||||
|
||||
private static final Set<String> VIRTUAL_CALCULATION_METHODS = new HashSet<>(Arrays.asList(
|
||||
VIRTUAL_CALCULATION_METHOD_GUIDANCE_PRICE,
|
||||
VIRTUAL_CALCULATION_METHOD_GUIDANCE_TOTAL_PRICE,
|
||||
VIRTUAL_CALCULATION_METHOD_WORKING_DAY
|
||||
));
|
||||
public static final String VIRTUAL_CALCULATION_METHOD_GUIDANCE_PRICE =
|
||||
ProjectPlanningVirtualCalculationMethodEnum.GUIDANCE_PRICE.getCode();
|
||||
public static final String VIRTUAL_CALCULATION_METHOD_GUIDANCE_TOTAL_PRICE =
|
||||
ProjectPlanningVirtualCalculationMethodEnum.GUIDANCE_TOTAL_PRICE.getCode();
|
||||
public static final String VIRTUAL_CALCULATION_METHOD_WORKING_DAY =
|
||||
ProjectPlanningVirtualCalculationMethodEnum.WORKING_DAY.getCode();
|
||||
|
||||
private ProjectPlanningBizTypeConstants() {
|
||||
}
|
||||
|
||||
public static boolean isValidOwnershipType(String value) {
|
||||
return OWNERSHIP_TYPES.contains(value);
|
||||
return ProjectPlanningOwnershipTypeEnum.contains(value);
|
||||
}
|
||||
|
||||
public static boolean isValidCalculationMethod(String value) {
|
||||
return CALCULATION_METHODS.contains(value);
|
||||
return ProjectPlanningCalculationMethodEnum.contains(value);
|
||||
}
|
||||
|
||||
public static boolean isValidDesignStage(String value) {
|
||||
return ProjectPlanningDesignStageEnum.contains(value);
|
||||
}
|
||||
|
||||
public static boolean isValidDesignPart(String value) {
|
||||
return DESIGN_PARTS.contains(value);
|
||||
return ProjectPlanningDesignPartEnum.contains(value);
|
||||
}
|
||||
|
||||
public static boolean isValidVirtualCalculationMethod(String value) {
|
||||
return VIRTUAL_CALCULATION_METHODS.contains(value);
|
||||
return ProjectPlanningVirtualCalculationMethodEnum.contains(value);
|
||||
}
|
||||
|
||||
public static boolean isMajor(String value) {
|
||||
@@ -76,7 +68,19 @@ public final class ProjectPlanningBizTypeConstants {
|
||||
}
|
||||
|
||||
public static boolean isSubcontract(String value) {
|
||||
return OWNERSHIP_TYPE_SUBCONTRACT.equals(value);
|
||||
return isSpecialSubcontract(value) || isSourceCoopSubcontract(value) || isComprehensiveSubcontract(value);
|
||||
}
|
||||
|
||||
public static boolean isSpecialSubcontract(String value) {
|
||||
return OWNERSHIP_TYPE_SPECIAL_SUBCONTRACT.equals(value);
|
||||
}
|
||||
|
||||
public static boolean isSourceCoopSubcontract(String value) {
|
||||
return OWNERSHIP_TYPE_SOURCE_COOP_SUBCONTRACT.equals(value);
|
||||
}
|
||||
|
||||
public static boolean isComprehensiveSubcontract(String value) {
|
||||
return OWNERSHIP_TYPE_COMPREHENSIVE_SUBCONTRACT.equals(value);
|
||||
}
|
||||
|
||||
public static boolean isGuidancePrice(String value) {
|
||||
@@ -107,4 +111,24 @@ public final class ProjectPlanningBizTypeConstants {
|
||||
return VIRTUAL_CALCULATION_METHOD_GUIDANCE_TOTAL_PRICE.equals(value);
|
||||
}
|
||||
|
||||
public static String getOwnershipTypeLabel(String value) {
|
||||
return ProjectPlanningOwnershipTypeEnum.labelOf(value);
|
||||
}
|
||||
|
||||
public static String getCalculationMethodLabel(String value) {
|
||||
return ProjectPlanningCalculationMethodEnum.labelOf(value);
|
||||
}
|
||||
|
||||
public static String getDesignStageLabel(String value) {
|
||||
return ProjectPlanningDesignStageEnum.labelOf(value);
|
||||
}
|
||||
|
||||
public static String getDesignPartLabel(String value) {
|
||||
return ProjectPlanningDesignPartEnum.labelOf(value);
|
||||
}
|
||||
|
||||
public static String getVirtualCalculationMethodLabel(String value) {
|
||||
return ProjectPlanningVirtualCalculationMethodEnum.labelOf(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 合约规划产值计算方式枚举。
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ProjectPlanningCalculationMethodEnum {
|
||||
|
||||
GUIDANCE_PRICE("guidance_price", "指导价法"),
|
||||
CONTRACT_PRICE("contract_price", "合同价法"),
|
||||
VIRTUAL_OUTPUT("virtual_output", "虚拟产值法");
|
||||
|
||||
private final String code;
|
||||
private final String label;
|
||||
|
||||
public static ProjectPlanningCalculationMethodEnum of(String code) {
|
||||
return Arrays.stream(values())
|
||||
.filter(item -> item.getCode().equals(code))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static boolean contains(String code) {
|
||||
return of(code) != null;
|
||||
}
|
||||
|
||||
public static String labelOf(String code) {
|
||||
ProjectPlanningCalculationMethodEnum item = of(code);
|
||||
return item == null ? code : item.getLabel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 指导价法设计部位枚举。
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ProjectPlanningDesignPartEnum {
|
||||
|
||||
ABOVE_GROUND("above_ground", "地上部分"),
|
||||
UNDERGROUND("underground", "地下部分"),
|
||||
OTHER("other", "其他");
|
||||
|
||||
private final String code;
|
||||
private final String label;
|
||||
|
||||
public static ProjectPlanningDesignPartEnum of(String code) {
|
||||
return Arrays.stream(values())
|
||||
.filter(item -> item.getCode().equals(code))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static boolean contains(String code) {
|
||||
return of(code) != null;
|
||||
}
|
||||
|
||||
public static String labelOf(String code) {
|
||||
ProjectPlanningDesignPartEnum item = of(code);
|
||||
return item == null ? code : item.getLabel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 合约规划设计阶段枚举。
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ProjectPlanningDesignStageEnum {
|
||||
|
||||
SCHEME("scheme", "方案"),
|
||||
CONSTRUCTION_DRAWING("construction_drawing", "施工图"),
|
||||
SCHEME_AND_CONSTRUCTION_DRAWING("scheme_and_construction_drawing", "方案+施工图");
|
||||
|
||||
private final String code;
|
||||
private final String label;
|
||||
|
||||
public static ProjectPlanningDesignStageEnum of(String code) {
|
||||
return Arrays.stream(values())
|
||||
.filter(item -> item.getCode().equals(code))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static boolean contains(String code) {
|
||||
return of(code) != null;
|
||||
}
|
||||
|
||||
public static String labelOf(String code) {
|
||||
ProjectPlanningDesignStageEnum item = of(code);
|
||||
return item == null ? code : item.getLabel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 合约规划归属类型枚举。
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ProjectPlanningOwnershipTypeEnum {
|
||||
|
||||
MAJOR("major", "专业所"),
|
||||
COMPREHENSIVE("comprehensive", "综合所"),
|
||||
SPECIAL_SUBCONTRACT_MAJOR("special_subcontract_major", "专项分包-专业所"),
|
||||
SPECIAL_SUBCONTRACT_SOURCE_COOP("special_subcontract_source_coop", "专项分包-源头合作分包"),
|
||||
SPECIAL_SUBCONTRACT_COMPREHENSIVE("special_subcontract_comprehensive", "专项分包-综合所");
|
||||
|
||||
private final String code;
|
||||
private final String label;
|
||||
|
||||
public static ProjectPlanningOwnershipTypeEnum of(String code) {
|
||||
return Arrays.stream(values())
|
||||
.filter(item -> item.getCode().equals(code))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static boolean contains(String code) {
|
||||
return of(code) != null;
|
||||
}
|
||||
|
||||
public static String labelOf(String code) {
|
||||
ProjectPlanningOwnershipTypeEnum item = of(code);
|
||||
return item == null ? code : item.getLabel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 虚拟产值计算方式枚举。
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ProjectPlanningVirtualCalculationMethodEnum {
|
||||
|
||||
GUIDANCE_PRICE("guidance_price", "指导单价法"),
|
||||
GUIDANCE_TOTAL_PRICE("guidance_total_price", "指导总价法"),
|
||||
WORKING_DAY("working_day", "工日法");
|
||||
|
||||
private final String code;
|
||||
private final String label;
|
||||
|
||||
public static ProjectPlanningVirtualCalculationMethodEnum of(String code) {
|
||||
return Arrays.stream(values())
|
||||
.filter(item -> item.getCode().equals(code))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static boolean contains(String code) {
|
||||
return of(code) != null;
|
||||
}
|
||||
|
||||
public static String labelOf(String code) {
|
||||
ProjectPlanningVirtualCalculationMethodEnum item = of(code);
|
||||
return item == null ? code : item.getLabel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 项目状态枚举。
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ProjectStatusEnum {
|
||||
|
||||
IN_PROGRESS("in_progress", "进行中"),
|
||||
COMPLETED("completed", "完成"),
|
||||
PAUSED("paused", "暂停"),
|
||||
TERMINATED("terminated", "中止");
|
||||
|
||||
private final String code;
|
||||
private final String label;
|
||||
|
||||
public static ProjectStatusEnum of(String code) {
|
||||
return Arrays.stream(values())
|
||||
.filter(item -> item.getCode().equals(code))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static boolean contains(String code) {
|
||||
return of(code) != null;
|
||||
}
|
||||
|
||||
public static String labelOf(String code) {
|
||||
ProjectStatusEnum item = of(code);
|
||||
return item == null ? code : item.getLabel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,6 +24,7 @@ public interface EmployeeService {
|
||||
|
||||
PageResult<EmployeeRespVO> getEmployeePage(EmployeePageReqVO pageReqVO);
|
||||
|
||||
List<EmployeeSimpleRespVO> getEmployeeSimpleList(String keyword, Long officeId, String status, Boolean enabledFlag);
|
||||
List<EmployeeSimpleRespVO> getEmployeeSimpleList(String keyword, Long officeId, String status,
|
||||
Boolean enabledFlag, Boolean officeLeaderFlag);
|
||||
|
||||
}
|
||||
|
||||
@@ -2,21 +2,19 @@ package cn.iocoder.lyzsys.module.tjt.service.employee;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.lyzsys.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employee.vo.EmployeePageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employee.vo.EmployeeRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employee.vo.EmployeeSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employee.vo.EmployeeSimpleRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRolePersonSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employee.EmployeeDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.office.OfficeDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.specialtyrolesplit.SpecialtyRoleSplitDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employeeyearcostbudget.EmployeeYearCostBudgetMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employeeyearleaderoutput.EmployeeYearLeaderOutputMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employee.EmployeeMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.office.OfficeMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.projectroleperson.ProjectRolePersonMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.specialtyrolesplit.SpecialtyRoleSplitMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.specialtyrolesplitperson.SpecialtyRoleSplitPersonMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.office.OfficeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -43,9 +41,11 @@ public class EmployeeServiceImpl implements EmployeeService {
|
||||
@Resource
|
||||
private EmployeeYearCostBudgetMapper employeeYearCostBudgetMapper;
|
||||
@Resource
|
||||
private EmployeeYearLeaderOutputMapper employeeYearLeaderOutputMapper;
|
||||
@Resource
|
||||
private ProjectRolePersonMapper projectRolePersonMapper;
|
||||
@Resource
|
||||
private SpecialtyRoleSplitMapper specialtyRoleSplitMapper;
|
||||
private SpecialtyRoleSplitPersonMapper specialtyRoleSplitPersonMapper;
|
||||
@Resource
|
||||
private OfficeService officeService;
|
||||
|
||||
@@ -56,6 +56,9 @@ public class EmployeeServiceImpl implements EmployeeService {
|
||||
if (employee.getEnabledFlag() == null) {
|
||||
employee.setEnabledFlag(Boolean.TRUE);
|
||||
}
|
||||
if (employee.getOfficeLeaderFlag() == null) {
|
||||
employee.setOfficeLeaderFlag(Boolean.FALSE);
|
||||
}
|
||||
employeeMapper.insert(employee);
|
||||
return employee.getId();
|
||||
}
|
||||
@@ -64,13 +67,18 @@ public class EmployeeServiceImpl implements EmployeeService {
|
||||
public void updateEmployee(EmployeeSaveReqVO updateReqVO) {
|
||||
validateEmployeeExists(updateReqVO.getId());
|
||||
officeService.validateOfficeExists(updateReqVO.getOfficeId());
|
||||
employeeMapper.updateById(BeanUtils.toBean(updateReqVO, EmployeeDO.class));
|
||||
EmployeeDO employee = BeanUtils.toBean(updateReqVO, EmployeeDO.class);
|
||||
if (employee.getOfficeLeaderFlag() == null) {
|
||||
employee.setOfficeLeaderFlag(Boolean.FALSE);
|
||||
}
|
||||
employeeMapper.updateById(employee);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteEmployee(Long id) {
|
||||
validateEmployeeExists(id);
|
||||
if (employeeYearCostBudgetMapper.selectCountByEmployeeId(id) > 0
|
||||
|| employeeYearLeaderOutputMapper.selectCountByEmployeeId(id) > 0
|
||||
|| projectRolePersonMapper.selectCountByEmployeeId(id) > 0
|
||||
|| existsInSpecialtyRoleSplit(id)) {
|
||||
throw exception(EMPLOYEE_IN_USE);
|
||||
@@ -104,8 +112,10 @@ public class EmployeeServiceImpl implements EmployeeService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EmployeeSimpleRespVO> getEmployeeSimpleList(String keyword, Long officeId, String status, Boolean enabledFlag) {
|
||||
List<EmployeeDO> list = employeeMapper.selectSimpleList(keyword, officeId, status, enabledFlag == null ? Boolean.TRUE : enabledFlag);
|
||||
public List<EmployeeSimpleRespVO> getEmployeeSimpleList(String keyword, Long officeId, String status,
|
||||
Boolean enabledFlag, Boolean officeLeaderFlag) {
|
||||
List<EmployeeDO> list = employeeMapper.selectSimpleList(keyword, officeId, status,
|
||||
enabledFlag == null ? Boolean.TRUE : enabledFlag, officeLeaderFlag);
|
||||
Map<Long, OfficeDO> officeMap = getOfficeMap(CollectionUtils.convertSet(list, EmployeeDO::getOfficeId));
|
||||
return BeanUtils.toBean(list, EmployeeSimpleRespVO.class, respVO ->
|
||||
respVO.setOfficeName(officeMap.containsKey(respVO.getOfficeId())
|
||||
@@ -113,20 +123,7 @@ public class EmployeeServiceImpl implements EmployeeService {
|
||||
}
|
||||
|
||||
private boolean existsInSpecialtyRoleSplit(Long employeeId) {
|
||||
List<SpecialtyRoleSplitDO> candidateList = specialtyRoleSplitMapper.selectListByPersonsJsonKeyword("\"employeeId\":" + employeeId);
|
||||
for (SpecialtyRoleSplitDO item : candidateList) {
|
||||
List<SpecialtyRolePersonSaveReqVO> persons = JsonUtils.parseArray(item.getPersonsJson(), SpecialtyRolePersonSaveReqVO.class);
|
||||
if (persons == null) {
|
||||
continue;
|
||||
}
|
||||
boolean matched = persons.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.anyMatch(person -> Objects.equals(person.getEmployeeId(), employeeId));
|
||||
if (matched) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return specialtyRoleSplitPersonMapper.selectCountByEmployeeId(employeeId) > 0;
|
||||
}
|
||||
|
||||
private Map<Long, OfficeDO> getOfficeMap(Set<Long> officeIds) {
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.service.employeeyearcostbudget;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetPageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
@@ -11,6 +9,8 @@ public interface EmployeeYearCostBudgetService {
|
||||
|
||||
Long createEmployeeYearCostBudget(@Valid EmployeeYearCostBudgetSaveReqVO createReqVO);
|
||||
|
||||
EmployeeYearCostBudgetGenerateRespVO generateEmployeeYearCostBudget(@Valid EmployeeYearCostBudgetGenerateReqVO reqVO);
|
||||
|
||||
void updateEmployeeYearCostBudget(@Valid EmployeeYearCostBudgetSaveReqVO updateReqVO);
|
||||
|
||||
void deleteEmployeeYearCostBudget(Long id);
|
||||
|
||||
@@ -2,18 +2,22 @@ package cn.iocoder.lyzsys.module.tjt.service.employeeyearcostbudget;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetPageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.EmployeeYearCostBudgetSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearcostbudget.vo.*;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employee.EmployeeDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employeeyearcostbudget.EmployeeYearCostBudgetDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employee.EmployeeMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employeeyearcostbudget.EmployeeYearCostBudgetMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.employee.EmployeeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.EMPLOYEE_YEAR_COST_BUDGET_DUPLICATE;
|
||||
@@ -26,6 +30,8 @@ public class EmployeeYearCostBudgetServiceImpl implements EmployeeYearCostBudget
|
||||
@Resource
|
||||
private EmployeeYearCostBudgetMapper employeeYearCostBudgetMapper;
|
||||
@Resource
|
||||
private EmployeeMapper employeeMapper;
|
||||
@Resource
|
||||
private EmployeeService employeeService;
|
||||
|
||||
@Override
|
||||
@@ -41,6 +47,32 @@ public class EmployeeYearCostBudgetServiceImpl implements EmployeeYearCostBudget
|
||||
return budget.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmployeeYearCostBudgetGenerateRespVO generateEmployeeYearCostBudget(EmployeeYearCostBudgetGenerateReqVO reqVO) {
|
||||
BigDecimal expectedCostAmount = amount(reqVO.getExpectedCostAmount());
|
||||
List<EmployeeDO> enabledEmployees = employeeMapper.selectEnabledList();
|
||||
Set<Long> existingEmployeeIds = employeeYearCostBudgetMapper.selectListByBudgetYear(reqVO.getBudgetYear())
|
||||
.stream()
|
||||
.map(EmployeeYearCostBudgetDO::getEmployeeId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
List<EmployeeYearCostBudgetDO> createList = enabledEmployees.stream()
|
||||
.filter(employee -> !existingEmployeeIds.contains(employee.getId()))
|
||||
.map(employee -> buildInitialBudget(employee, reqVO.getBudgetYear(), expectedCostAmount))
|
||||
.collect(Collectors.toList());
|
||||
if (!createList.isEmpty()) {
|
||||
employeeYearCostBudgetMapper.insertBatch(createList);
|
||||
}
|
||||
|
||||
EmployeeYearCostBudgetGenerateRespVO respVO = new EmployeeYearCostBudgetGenerateRespVO();
|
||||
respVO.setBudgetYear(reqVO.getBudgetYear());
|
||||
respVO.setTotalEnabledEmployeeCount(enabledEmployees.size());
|
||||
respVO.setCreatedCount(createList.size());
|
||||
respVO.setSkippedCount(enabledEmployees.size() - createList.size());
|
||||
return respVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEmployeeYearCostBudget(EmployeeYearCostBudgetSaveReqVO updateReqVO) {
|
||||
validateExists(updateReqVO.getId());
|
||||
@@ -82,4 +114,21 @@ public class EmployeeYearCostBudgetServiceImpl implements EmployeeYearCostBudget
|
||||
}
|
||||
}
|
||||
|
||||
private EmployeeYearCostBudgetDO buildInitialBudget(EmployeeDO employee, Integer budgetYear, BigDecimal expectedCostAmount) {
|
||||
EmployeeYearCostBudgetDO budget = new EmployeeYearCostBudgetDO();
|
||||
budget.setEmployeeId(employee.getId());
|
||||
budget.setEmployeeName(employee.getEmployeeName());
|
||||
budget.setBudgetYear(budgetYear);
|
||||
budget.setExpectedCostAmount(expectedCostAmount);
|
||||
budget.setSortNo(employee.getSortNo() == null ? 0 : employee.getSortNo());
|
||||
budget.setEnabledFlag(Boolean.TRUE);
|
||||
budget.setRemark("");
|
||||
return budget;
|
||||
}
|
||||
|
||||
private BigDecimal amount(BigDecimal value) {
|
||||
return value == null ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
|
||||
: value.setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.service.employeeyearleaderoutput;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
public interface EmployeeYearLeaderOutputService {
|
||||
|
||||
Long createEmployeeYearLeaderOutput(@Valid EmployeeYearLeaderOutputSaveReqVO createReqVO);
|
||||
|
||||
EmployeeYearLeaderOutputGenerateRespVO generateEmployeeYearLeaderOutput(
|
||||
@Valid EmployeeYearLeaderOutputGenerateReqVO reqVO);
|
||||
|
||||
void updateEmployeeYearLeaderOutput(@Valid EmployeeYearLeaderOutputSaveReqVO updateReqVO);
|
||||
|
||||
void deleteEmployeeYearLeaderOutput(Long id);
|
||||
|
||||
EmployeeYearLeaderOutputRespVO getEmployeeYearLeaderOutput(Long id);
|
||||
|
||||
PageResult<EmployeeYearLeaderOutputRespVO> getEmployeeYearLeaderOutputPage(
|
||||
EmployeeYearLeaderOutputPageReqVO pageReqVO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.service.employeeyearleaderoutput;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.employeeyearleaderoutput.vo.*;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employee.EmployeeDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employeeyearleaderoutput.EmployeeYearLeaderOutputDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employee.EmployeeMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.employeeyearleaderoutput.EmployeeYearLeaderOutputMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.employee.EmployeeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.*;
|
||||
|
||||
@Service
|
||||
@Validated
|
||||
public class EmployeeYearLeaderOutputServiceImpl implements EmployeeYearLeaderOutputService {
|
||||
|
||||
@Resource
|
||||
private EmployeeYearLeaderOutputMapper employeeYearLeaderOutputMapper;
|
||||
@Resource
|
||||
private EmployeeMapper employeeMapper;
|
||||
@Resource
|
||||
private EmployeeService employeeService;
|
||||
|
||||
@Override
|
||||
public Long createEmployeeYearLeaderOutput(EmployeeYearLeaderOutputSaveReqVO createReqVO) {
|
||||
EmployeeDO employee = validateEmployeeIsOfficeLeader(createReqVO.getEmployeeId());
|
||||
validateDuplicate(null, createReqVO.getEmployeeId(), createReqVO.getOutputYear());
|
||||
EmployeeYearLeaderOutputDO output = BeanUtils.toBean(createReqVO, EmployeeYearLeaderOutputDO.class);
|
||||
output.setEmployeeName(employee.getEmployeeName());
|
||||
output.setLeaderOutputAmount(amount(output.getLeaderOutputAmount()));
|
||||
if (output.getEnabledFlag() == null) {
|
||||
output.setEnabledFlag(Boolean.TRUE);
|
||||
}
|
||||
employeeYearLeaderOutputMapper.insert(output);
|
||||
return output.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmployeeYearLeaderOutputGenerateRespVO generateEmployeeYearLeaderOutput(
|
||||
EmployeeYearLeaderOutputGenerateReqVO reqVO) {
|
||||
BigDecimal leaderOutputAmount = amount(reqVO.getLeaderOutputAmount());
|
||||
List<EmployeeDO> enabledLeaders = employeeMapper.selectEnabledLeaderList();
|
||||
Set<Long> existingEmployeeIds = employeeYearLeaderOutputMapper.selectListByOutputYear(reqVO.getOutputYear())
|
||||
.stream()
|
||||
.map(EmployeeYearLeaderOutputDO::getEmployeeId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
List<EmployeeYearLeaderOutputDO> createList = enabledLeaders.stream()
|
||||
.filter(employee -> !existingEmployeeIds.contains(employee.getId()))
|
||||
.map(employee -> buildInitialOutput(employee, reqVO.getOutputYear(), leaderOutputAmount))
|
||||
.collect(Collectors.toList());
|
||||
if (!createList.isEmpty()) {
|
||||
employeeYearLeaderOutputMapper.insertBatch(createList);
|
||||
}
|
||||
|
||||
EmployeeYearLeaderOutputGenerateRespVO respVO = new EmployeeYearLeaderOutputGenerateRespVO();
|
||||
respVO.setOutputYear(reqVO.getOutputYear());
|
||||
respVO.setTotalEnabledLeaderCount(enabledLeaders.size());
|
||||
respVO.setCreatedCount(createList.size());
|
||||
respVO.setSkippedCount(enabledLeaders.size() - createList.size());
|
||||
return respVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEmployeeYearLeaderOutput(EmployeeYearLeaderOutputSaveReqVO updateReqVO) {
|
||||
validateExists(updateReqVO.getId());
|
||||
EmployeeDO employee = validateEmployeeIsOfficeLeader(updateReqVO.getEmployeeId());
|
||||
validateDuplicate(updateReqVO.getId(), updateReqVO.getEmployeeId(), updateReqVO.getOutputYear());
|
||||
EmployeeYearLeaderOutputDO updateObj = BeanUtils.toBean(updateReqVO, EmployeeYearLeaderOutputDO.class);
|
||||
updateObj.setEmployeeName(employee.getEmployeeName());
|
||||
updateObj.setLeaderOutputAmount(amount(updateObj.getLeaderOutputAmount()));
|
||||
employeeYearLeaderOutputMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteEmployeeYearLeaderOutput(Long id) {
|
||||
validateExists(id);
|
||||
employeeYearLeaderOutputMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmployeeYearLeaderOutputRespVO getEmployeeYearLeaderOutput(Long id) {
|
||||
return BeanUtils.toBean(validateExists(id), EmployeeYearLeaderOutputRespVO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<EmployeeYearLeaderOutputRespVO> getEmployeeYearLeaderOutputPage(
|
||||
EmployeeYearLeaderOutputPageReqVO pageReqVO) {
|
||||
return BeanUtils.toBean(employeeYearLeaderOutputMapper.selectPage(pageReqVO),
|
||||
EmployeeYearLeaderOutputRespVO.class);
|
||||
}
|
||||
|
||||
private EmployeeYearLeaderOutputDO validateExists(Long id) {
|
||||
EmployeeYearLeaderOutputDO output = employeeYearLeaderOutputMapper.selectById(id);
|
||||
if (output == null) {
|
||||
throw exception(EMPLOYEE_YEAR_LEADER_OUTPUT_NOT_EXISTS);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private EmployeeDO validateEmployeeIsOfficeLeader(Long employeeId) {
|
||||
EmployeeDO employee = employeeService.validateEmployeeExists(employeeId);
|
||||
if (!Boolean.TRUE.equals(employee.getEnabledFlag()) || !Boolean.TRUE.equals(employee.getOfficeLeaderFlag())) {
|
||||
throw exception(EMPLOYEE_NOT_OFFICE_LEADER);
|
||||
}
|
||||
return employee;
|
||||
}
|
||||
|
||||
private void validateDuplicate(Long id, Long employeeId, Integer outputYear) {
|
||||
EmployeeYearLeaderOutputDO duplicate =
|
||||
employeeYearLeaderOutputMapper.selectByEmployeeIdAndOutputYear(employeeId, outputYear);
|
||||
if (duplicate != null && !Objects.equals(duplicate.getId(), id)) {
|
||||
throw exception(EMPLOYEE_YEAR_LEADER_OUTPUT_DUPLICATE);
|
||||
}
|
||||
}
|
||||
|
||||
private EmployeeYearLeaderOutputDO buildInitialOutput(EmployeeDO employee, Integer outputYear,
|
||||
BigDecimal leaderOutputAmount) {
|
||||
EmployeeYearLeaderOutputDO output = new EmployeeYearLeaderOutputDO();
|
||||
output.setEmployeeId(employee.getId());
|
||||
output.setEmployeeName(employee.getEmployeeName());
|
||||
output.setOutputYear(outputYear);
|
||||
output.setLeaderOutputAmount(leaderOutputAmount);
|
||||
output.setSortNo(employee.getSortNo() == null ? 0 : employee.getSortNo());
|
||||
output.setEnabledFlag(Boolean.TRUE);
|
||||
output.setRemark("");
|
||||
return output;
|
||||
}
|
||||
|
||||
private BigDecimal amount(BigDecimal value) {
|
||||
return value == null ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
|
||||
: value.setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.service.outputsplit;
|
||||
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.outputsplit.ProjectOutputSplitDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planning.ProjectPlanningDO;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
/**
|
||||
* 页面 4 拆分比例默认值构造器。
|
||||
*
|
||||
* <p>所有“没有拆分记录时的默认比例”都从这里生成,避免页面、专业内分配、报表之间规则漂移。</p>
|
||||
*
|
||||
* @author Codex
|
||||
*/
|
||||
public final class ProjectOutputSplitDefaults {
|
||||
|
||||
private static final int RATIO_SCALE = 4;
|
||||
private static final BigDecimal ZERO_RATIO = BigDecimal.ZERO.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
private static final BigDecimal ONE_RATIO = BigDecimal.ONE.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
|
||||
private ProjectOutputSplitDefaults() {
|
||||
}
|
||||
|
||||
public static ProjectOutputSplitDO build(ProjectPlanningDO planning) {
|
||||
return build(planning, 0);
|
||||
}
|
||||
|
||||
public static ProjectOutputSplitDO build(ProjectPlanningDO planning, Integer fallbackYear) {
|
||||
ProjectOutputSplitDO outputSplit = new ProjectOutputSplitDO();
|
||||
if (planning != null) {
|
||||
outputSplit.setProjectId(planning.getProjectId());
|
||||
outputSplit.setPlanningId(planning.getId());
|
||||
outputSplit.setYear(planning.getPlanningStartYear() == null ? fallbackYear : planning.getPlanningStartYear());
|
||||
}
|
||||
outputSplit.setProjectLeadRatio(ZERO_RATIO);
|
||||
outputSplit.setOfficeRatio(ONE_RATIO);
|
||||
outputSplit.setArchRatio(ONE_RATIO);
|
||||
outputSplit.setDecorRatio(ZERO_RATIO);
|
||||
outputSplit.setStructRatio(ZERO_RATIO);
|
||||
outputSplit.setWaterRatio(ZERO_RATIO);
|
||||
outputSplit.setElecRatio(ZERO_RATIO);
|
||||
outputSplit.setHvacRatio(ZERO_RATIO);
|
||||
outputSplit.setDigitalRatio(ZERO_RATIO);
|
||||
return outputSplit;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import cn.iocoder.lyzsys.module.tjt.dal.mysql.planning.ProjectPlanningMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.project.ProjectMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.projectroleperson.ProjectRolePersonMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.enums.OutputSplitBizConstants;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@@ -61,7 +62,7 @@ public class ProjectOutputSplitServiceImpl implements ProjectOutputSplitService
|
||||
ProjectDO project = validateProjectExists(planning.getProjectId());
|
||||
ProjectOutputSplitDO outputSplit = projectOutputSplitMapper.selectByPlanningId(planningId);
|
||||
if (outputSplit == null) {
|
||||
outputSplit = buildDefaultOutputSplit(planning);
|
||||
outputSplit = ProjectOutputSplitDefaults.build(planning);
|
||||
}
|
||||
return buildRespVO(outputSplit, planning, project);
|
||||
}
|
||||
@@ -76,7 +77,22 @@ public class ProjectOutputSplitServiceImpl implements ProjectOutputSplitService
|
||||
outputSplit.setProjectId(planning.getProjectId());
|
||||
outputSplit.setYear(getPlanningYear(planning));
|
||||
normalizeRatios(outputSplit);
|
||||
try {
|
||||
projectOutputSplitMapper.insert(outputSplit);
|
||||
} catch (DuplicateKeyException ex) {
|
||||
// 并发下可能已由自动创建流程插入,重新查询后继续更新用户提交的比例。
|
||||
outputSplit = projectOutputSplitMapper.selectByPlanningId(reqVO.getPlanningId());
|
||||
if (outputSplit == null) {
|
||||
throw ex;
|
||||
}
|
||||
ProjectOutputSplitDO updateObj = BeanUtils.toBean(reqVO, ProjectOutputSplitDO.class);
|
||||
updateObj.setId(outputSplit.getId());
|
||||
updateObj.setProjectId(planning.getProjectId());
|
||||
updateObj.setYear(getPlanningYear(planning));
|
||||
normalizeRatios(updateObj);
|
||||
projectOutputSplitMapper.updateById(updateObj);
|
||||
outputSplit = updateObj;
|
||||
}
|
||||
} else {
|
||||
ProjectOutputSplitDO updateObj = BeanUtils.toBean(reqVO, ProjectOutputSplitDO.class);
|
||||
updateObj.setId(outputSplit.getId());
|
||||
@@ -96,9 +112,18 @@ public class ProjectOutputSplitServiceImpl implements ProjectOutputSplitService
|
||||
if (outputSplit != null) {
|
||||
return outputSplit;
|
||||
}
|
||||
ProjectOutputSplitDO createObj = buildDefaultOutputSplit(planning);
|
||||
ProjectOutputSplitDO createObj = ProjectOutputSplitDefaults.build(planning);
|
||||
try {
|
||||
projectOutputSplitMapper.insert(createObj);
|
||||
return createObj;
|
||||
} catch (DuplicateKeyException ex) {
|
||||
// 唯一索引兜底并发创建,同一合约规划已存在时直接复用已有记录。
|
||||
ProjectOutputSplitDO existing = projectOutputSplitMapper.selectByPlanningId(planningId);
|
||||
if (existing != null) {
|
||||
return existing;
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -180,23 +205,6 @@ public class ProjectOutputSplitServiceImpl implements ProjectOutputSplitService
|
||||
return project;
|
||||
}
|
||||
|
||||
private ProjectOutputSplitDO buildDefaultOutputSplit(ProjectPlanningDO planning) {
|
||||
ProjectOutputSplitDO outputSplit = new ProjectOutputSplitDO();
|
||||
outputSplit.setProjectId(planning.getProjectId());
|
||||
outputSplit.setPlanningId(planning.getId());
|
||||
outputSplit.setYear(getPlanningYear(planning));
|
||||
outputSplit.setProjectLeadRatio(ZERO_RATIO);
|
||||
outputSplit.setOfficeRatio(ONE_RATIO);
|
||||
outputSplit.setArchRatio(ONE_RATIO);
|
||||
outputSplit.setDecorRatio(ZERO_RATIO);
|
||||
outputSplit.setStructRatio(ZERO_RATIO);
|
||||
outputSplit.setWaterRatio(ZERO_RATIO);
|
||||
outputSplit.setElecRatio(ZERO_RATIO);
|
||||
outputSplit.setHvacRatio(ZERO_RATIO);
|
||||
outputSplit.setDigitalRatio(ZERO_RATIO);
|
||||
return outputSplit;
|
||||
}
|
||||
|
||||
private Integer getPlanningYear(ProjectPlanningDO planning) {
|
||||
return planning.getPlanningStartYear() == null ? 0 : planning.getPlanningStartYear();
|
||||
}
|
||||
@@ -251,24 +259,28 @@ public class ProjectOutputSplitServiceImpl implements ProjectOutputSplitService
|
||||
}
|
||||
|
||||
private BigDecimal getSpecialtyRatio(ProjectOutputSplitDO outputSplit, String specialtyCode) {
|
||||
switch (specialtyCode) {
|
||||
case OutputSplitBizConstants.SPECIALTY_ARCH:
|
||||
if (OutputSplitBizConstants.SPECIALTY_ARCH.equals(specialtyCode)) {
|
||||
return ratio(outputSplit.getArchRatio());
|
||||
case OutputSplitBizConstants.SPECIALTY_DECOR:
|
||||
return ratio(outputSplit.getDecorRatio());
|
||||
case OutputSplitBizConstants.SPECIALTY_STRUCT:
|
||||
return ratio(outputSplit.getStructRatio());
|
||||
case OutputSplitBizConstants.SPECIALTY_WATER:
|
||||
return ratio(outputSplit.getWaterRatio());
|
||||
case OutputSplitBizConstants.SPECIALTY_ELEC:
|
||||
return ratio(outputSplit.getElecRatio());
|
||||
case OutputSplitBizConstants.SPECIALTY_HVAC:
|
||||
return ratio(outputSplit.getHvacRatio());
|
||||
case OutputSplitBizConstants.SPECIALTY_DIGITAL:
|
||||
return ratio(outputSplit.getDigitalRatio());
|
||||
default:
|
||||
return ZERO_RATIO;
|
||||
}
|
||||
if (OutputSplitBizConstants.SPECIALTY_DECOR.equals(specialtyCode)) {
|
||||
return ratio(outputSplit.getDecorRatio());
|
||||
}
|
||||
if (OutputSplitBizConstants.SPECIALTY_STRUCT.equals(specialtyCode)) {
|
||||
return ratio(outputSplit.getStructRatio());
|
||||
}
|
||||
if (OutputSplitBizConstants.SPECIALTY_WATER.equals(specialtyCode)) {
|
||||
return ratio(outputSplit.getWaterRatio());
|
||||
}
|
||||
if (OutputSplitBizConstants.SPECIALTY_ELEC.equals(specialtyCode)) {
|
||||
return ratio(outputSplit.getElecRatio());
|
||||
}
|
||||
if (OutputSplitBizConstants.SPECIALTY_HVAC.equals(specialtyCode)) {
|
||||
return ratio(outputSplit.getHvacRatio());
|
||||
}
|
||||
if (OutputSplitBizConstants.SPECIALTY_DIGITAL.equals(specialtyCode)) {
|
||||
return ratio(outputSplit.getDigitalRatio());
|
||||
}
|
||||
return ZERO_RATIO;
|
||||
}
|
||||
|
||||
private BigDecimal multiplyAmount(BigDecimal left, BigDecimal right) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import java.util.Objects;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_PLANNING_CALCULATION_METHOD_INVALID;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_PLANNING_DESIGN_STAGE_INVALID;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_PLANNING_NOT_EXISTS;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_PLANNING_OWNERSHIP_TYPE_IMMUTABLE;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_PLANNING_OWNERSHIP_TYPE_INVALID;
|
||||
@@ -156,18 +157,54 @@ public class ProjectPlanningServiceImpl implements ProjectPlanningService {
|
||||
if (planningIds == null || planningIds.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<ProjectPlanningQuarterDO> quarterList = projectPlanningQuarterMapper.selectListByPlanningIds(planningIds);
|
||||
List<Long> validPlanningIds = planningIds.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
if (validPlanningIds.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<Long, ProjectPlanningDO> planningMap = projectPlanningMapper.selectBatchIds(validPlanningIds).stream()
|
||||
.collect(java.util.stream.Collectors.toMap(ProjectPlanningDO::getId, item -> item, (a, b) -> a));
|
||||
List<ProjectPlanningQuarterDO> quarterList = projectPlanningQuarterMapper.selectListByPlanningIds(validPlanningIds);
|
||||
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap = quarterList.stream()
|
||||
.collect(java.util.stream.Collectors.groupingBy(ProjectPlanningQuarterDO::getPlanningId));
|
||||
Map<Long, BigDecimal> allocatedAmountMap = new HashMap<>();
|
||||
for (Long planningId : planningIds) {
|
||||
allocatedAmountMap.put(planningId, ZERO_RATIO);
|
||||
for (Long planningId : validPlanningIds) {
|
||||
allocatedAmountMap.put(planningId, calculateAllocatedRatio(
|
||||
planningMap.get(planningId),
|
||||
quarterMap.getOrDefault(planningId, Collections.emptyList())));
|
||||
}
|
||||
for (ProjectPlanningQuarterDO quarter : quarterList) {
|
||||
allocatedAmountMap.merge(quarter.getPlanningId(), ratio(quarter.getDistributionRatio()), BigDecimal::add);
|
||||
}
|
||||
allocatedAmountMap.replaceAll((key, value) -> ratio(value));
|
||||
return allocatedAmountMap;
|
||||
}
|
||||
|
||||
private BigDecimal calculateAllocatedRatio(ProjectPlanningDO planning, List<ProjectPlanningQuarterDO> quarterList) {
|
||||
if (quarterList == null || quarterList.isEmpty()) {
|
||||
return ZERO_RATIO;
|
||||
}
|
||||
boolean hasGuideDetailQuarter = quarterList.stream().anyMatch(item -> item.getGuideDetailId() != null);
|
||||
if (!hasGuideDetailQuarter) {
|
||||
BigDecimal allocatedRatio = ZERO_RATIO;
|
||||
for (ProjectPlanningQuarterDO quarter : quarterList) {
|
||||
allocatedRatio = allocatedRatio.add(ratio(quarter.getDistributionRatio()))
|
||||
.setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
}
|
||||
return allocatedRatio;
|
||||
}
|
||||
if (planning == null) {
|
||||
return ZERO_RATIO;
|
||||
}
|
||||
BigDecimal baseAmount = multiplyAmount(planning.getAssessmentOutputValue(), planning.getTotalDistributionAmount());
|
||||
if (baseAmount.compareTo(BigDecimal.ZERO) == 0) {
|
||||
return ZERO_RATIO;
|
||||
}
|
||||
BigDecimal allocatedAmount = ZERO_AMOUNT;
|
||||
for (ProjectPlanningQuarterDO quarter : quarterList) {
|
||||
allocatedAmount = allocatedAmount.add(amount(quarter.getDistributionAmount()))
|
||||
.setScale(AMOUNT_SCALE, RoundingMode.HALF_UP);
|
||||
}
|
||||
return allocatedAmount.divide(baseAmount, RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private void validateProjectPlanningForSave(ProjectPlanningSaveReqVO reqVO, ProjectPlanningDO dbPlanning) {
|
||||
if (!ProjectPlanningBizTypeConstants.isValidOwnershipType(reqVO.getOwnershipType())) {
|
||||
throw exception(PROJECT_PLANNING_OWNERSHIP_TYPE_INVALID);
|
||||
@@ -181,6 +218,10 @@ public class ProjectPlanningServiceImpl implements ProjectPlanningService {
|
||||
&& !ProjectPlanningBizTypeConstants.isValidVirtualCalculationMethod(reqVO.getVirtualCalculationMethod())) {
|
||||
throw exception(PROJECT_PLANNING_VIRTUAL_CALCULATION_METHOD_INVALID);
|
||||
}
|
||||
if (StrUtil.isNotBlank(reqVO.getDesignStage())
|
||||
&& !ProjectPlanningBizTypeConstants.isValidDesignStage(reqVO.getDesignStage())) {
|
||||
throw exception(PROJECT_PLANNING_DESIGN_STAGE_INVALID);
|
||||
}
|
||||
if (ProjectPlanningBizTypeConstants.isWorkingDay(reqVO.getVirtualCalculationMethod())) {
|
||||
if (reqVO.getWorkingDayCount() == null) {
|
||||
throw exception(PROJECT_PLANNING_WORKING_DAY_COUNT_REQUIRED);
|
||||
@@ -198,9 +239,6 @@ public class ProjectPlanningServiceImpl implements ProjectPlanningService {
|
||||
}
|
||||
|
||||
private void prepareProjectPlanning(ProjectPlanningDO planning, ProjectDO project) {
|
||||
if (planning.getSortNo() == null) {
|
||||
planning.setSortNo(0);
|
||||
}
|
||||
if (planning.getPlanningStartYear() == null) {
|
||||
planning.setPlanningStartYear(project.getProjectStartYear());
|
||||
}
|
||||
@@ -245,6 +283,7 @@ public class ProjectPlanningServiceImpl implements ProjectPlanningService {
|
||||
planning.setWorkingDayUnitPrice(amountNullable(planning.getWorkingDayUnitPrice()));
|
||||
planning.setGuidanceUnitPrice(amountNullable(planning.getGuidanceUnitPrice()));
|
||||
planning.setGuidanceTotalPrice(amountNullable(planning.getGuidanceTotalPrice()));
|
||||
planning.setContractUnitPrice(amountNullable(planning.getContractUnitPrice()));
|
||||
}
|
||||
|
||||
private void calculateProjectPlanning(ProjectPlanningDO planning) {
|
||||
@@ -253,7 +292,9 @@ public class ProjectPlanningServiceImpl implements ProjectPlanningService {
|
||||
planning.setProjectBudgetOutputValue(amount(planning.getPlanningAmount()
|
||||
.subtract(planning.getManagementFee())
|
||||
.subtract(planning.getVatAmount())));
|
||||
if (planning.getContractUnitPrice() == null) {
|
||||
planning.setContractUnitPrice(divideAmount(planning.getPlanningAmount(), planning.getPlanningArea()));
|
||||
}
|
||||
planning.setTotalAdjustmentFactor(ZERO_RATIO);
|
||||
planning.setAssessmentArea(ZERO_AMOUNT);
|
||||
planning.setVirtualOutputValue(ZERO_AMOUNT);
|
||||
|
||||
@@ -84,6 +84,7 @@ public class ProjectPlanningGuideDetailServiceImpl implements ProjectPlanningGui
|
||||
.filter(id -> !retainedIds.contains(id))
|
||||
.collect(Collectors.toList());
|
||||
if (!deletedIds.isEmpty()) {
|
||||
projectPlanningQuarterMapper.deleteBatch(ProjectPlanningQuarterDO::getGuideDetailId, deletedIds);
|
||||
projectPlanningGuideDetailMapper.deleteBatchIds(deletedIds);
|
||||
}
|
||||
|
||||
@@ -96,6 +97,7 @@ public class ProjectPlanningGuideDetailServiceImpl implements ProjectPlanningGui
|
||||
if (detail == null) {
|
||||
throw exception(PROJECT_PLANNING_GUIDE_DETAIL_NOT_EXISTS);
|
||||
}
|
||||
projectPlanningQuarterMapper.delete(ProjectPlanningQuarterDO::getGuideDetailId, id);
|
||||
projectPlanningGuideDetailMapper.deleteById(id);
|
||||
recalculatePlanningSummary(detail.getPlanningId());
|
||||
}
|
||||
@@ -122,6 +124,7 @@ public class ProjectPlanningGuideDetailServiceImpl implements ProjectPlanningGui
|
||||
if (planningId == null) {
|
||||
return;
|
||||
}
|
||||
projectPlanningQuarterMapper.delete(ProjectPlanningQuarterDO::getPlanningId, planningId);
|
||||
projectPlanningGuideDetailMapper.delete(ProjectPlanningGuideDetailDO::getPlanningId, planningId);
|
||||
}
|
||||
|
||||
@@ -130,6 +133,7 @@ public class ProjectPlanningGuideDetailServiceImpl implements ProjectPlanningGui
|
||||
if (planningIds == null || planningIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
projectPlanningQuarterMapper.deleteBatch(ProjectPlanningQuarterDO::getPlanningId, planningIds);
|
||||
projectPlanningGuideDetailMapper.deleteBatch(ProjectPlanningGuideDetailDO::getPlanningId, planningIds);
|
||||
}
|
||||
|
||||
@@ -175,7 +179,6 @@ public class ProjectPlanningGuideDetailServiceImpl implements ProjectPlanningGui
|
||||
ProjectPlanningDO updateObj = new ProjectPlanningDO();
|
||||
updateObj.setId(planningId);
|
||||
updateObj.setPlanningArea(totalDesignArea);
|
||||
updateObj.setContractUnitPrice(divideAmount(planning.getPlanningAmount(), totalDesignArea));
|
||||
updateObj.setTotalAdjustmentFactor(ZERO_RATIO);
|
||||
updateObj.setAssessmentArea(totalAssessmentArea);
|
||||
updateObj.setVirtualOutputValue(ZERO_AMOUNT);
|
||||
@@ -241,9 +244,22 @@ public class ProjectPlanningGuideDetailServiceImpl implements ProjectPlanningGui
|
||||
return;
|
||||
}
|
||||
List<ProjectPlanningQuarterDO> quarterList = projectPlanningQuarterMapper.selectListByPlanningId(planning.getId());
|
||||
Map<Long, ProjectPlanningGuideDetailDO> guideDetailMap = Collections.emptyMap();
|
||||
if (isGuideDetailScene(planning)) {
|
||||
guideDetailMap = CollectionUtils.convertMap(
|
||||
projectPlanningGuideDetailMapper.selectListByPlanningId(planning.getId()),
|
||||
ProjectPlanningGuideDetailDO::getId);
|
||||
}
|
||||
for (ProjectPlanningQuarterDO quarter : quarterList) {
|
||||
ProjectPlanningGuideDetailDO guideDetail = quarter.getGuideDetailId() == null
|
||||
? null : guideDetailMap.get(quarter.getGuideDetailId());
|
||||
BigDecimal assessmentOutputValue = guideDetail == null
|
||||
? planning.getAssessmentOutputValue() : guideDetail.getAssessmentOutputValue();
|
||||
if (guideDetail != null) {
|
||||
quarter.setGuideDetailSortNo(guideDetail.getSortNo());
|
||||
}
|
||||
quarter.setDistributionAmount(multiplyAmount(
|
||||
planning.getAssessmentOutputValue(),
|
||||
assessmentOutputValue,
|
||||
planning.getTotalDistributionAmount(),
|
||||
ratio(quarter.getDistributionRatio())
|
||||
));
|
||||
|
||||
@@ -3,9 +3,12 @@ package cn.iocoder.lyzsys.module.tjt.service.planningquarter;
|
||||
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.planningquarter.vo.ProjectPlanningQuarterSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planning.ProjectPlanningDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningguidedetail.ProjectPlanningGuideDetailDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningquarter.ProjectPlanningQuarterDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.planning.ProjectPlanningMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.planningguidedetail.ProjectPlanningGuideDetailMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.planningquarter.ProjectPlanningQuarterMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.enums.ProjectPlanningBizTypeConstants;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@@ -13,11 +16,16 @@ import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_PLANNING_QUARTER_DUPLICATE;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_PLANNING_QUARTER_GUIDE_DETAIL_INVALID;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_PLANNING_QUARTER_GUIDE_DETAIL_NOT_ALLOWED;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_PLANNING_QUARTER_GUIDE_DETAIL_REQUIRED;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_PLANNING_QUARTER_NOT_EXISTS;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_PLANNING_QUARTER_PLANNING_NOT_EXISTS;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_PLANNING_QUARTER_SCOPE_MIXED;
|
||||
|
||||
/**
|
||||
* 季度分配 Service 实现类
|
||||
@@ -35,6 +43,8 @@ public class ProjectPlanningQuarterServiceImpl implements ProjectPlanningQuarter
|
||||
private ProjectPlanningQuarterMapper projectPlanningQuarterMapper;
|
||||
@Resource
|
||||
private ProjectPlanningMapper projectPlanningMapper;
|
||||
@Resource
|
||||
private ProjectPlanningGuideDetailMapper projectPlanningGuideDetailMapper;
|
||||
|
||||
@Override
|
||||
public Long createProjectPlanningQuarter(ProjectPlanningQuarterSaveReqVO createReqVO) {
|
||||
@@ -42,10 +52,12 @@ public class ProjectPlanningQuarterServiceImpl implements ProjectPlanningQuarter
|
||||
if (isZeroQuarter(createReqVO)) {
|
||||
return null;
|
||||
}
|
||||
validateQuarterUnique(null, createReqVO.getPlanningId(),
|
||||
ProjectPlanningGuideDetailDO guideDetail = validateGuideDetailScope(planning, createReqVO.getGuideDetailId());
|
||||
validateScopeNotMixed(null, createReqVO.getPlanningId(), guideDetail);
|
||||
validateQuarterUnique(null, createReqVO.getPlanningId(), createReqVO.getGuideDetailId(),
|
||||
createReqVO.getDistributionYear(), createReqVO.getQuarterNo());
|
||||
ProjectPlanningQuarterDO quarter = BeanUtils.toBean(createReqVO, ProjectPlanningQuarterDO.class);
|
||||
prepareQuarter(quarter, planning);
|
||||
prepareQuarter(quarter, planning, guideDetail);
|
||||
projectPlanningQuarterMapper.insert(quarter);
|
||||
return quarter.getId();
|
||||
}
|
||||
@@ -58,10 +70,12 @@ public class ProjectPlanningQuarterServiceImpl implements ProjectPlanningQuarter
|
||||
projectPlanningQuarterMapper.deleteById(dbQuarter.getId());
|
||||
return;
|
||||
}
|
||||
validateQuarterUnique(updateReqVO.getId(), updateReqVO.getPlanningId(),
|
||||
ProjectPlanningGuideDetailDO guideDetail = validateGuideDetailScope(planning, updateReqVO.getGuideDetailId());
|
||||
validateScopeNotMixed(updateReqVO.getId(), updateReqVO.getPlanningId(), guideDetail);
|
||||
validateQuarterUnique(updateReqVO.getId(), updateReqVO.getPlanningId(), updateReqVO.getGuideDetailId(),
|
||||
updateReqVO.getDistributionYear(), updateReqVO.getQuarterNo());
|
||||
ProjectPlanningQuarterDO updateObj = BeanUtils.toBean(updateReqVO, ProjectPlanningQuarterDO.class);
|
||||
prepareQuarter(updateObj, planning);
|
||||
prepareQuarter(updateObj, planning, guideDetail);
|
||||
projectPlanningQuarterMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@@ -88,9 +102,13 @@ public class ProjectPlanningQuarterServiceImpl implements ProjectPlanningQuarter
|
||||
return projectPlanningQuarterMapper.selectListByPlanningId(planningId);
|
||||
}
|
||||
|
||||
private void validateQuarterUnique(Long id, Long planningId, Integer distributionYear, Integer quarterNo) {
|
||||
ProjectPlanningQuarterDO quarter = projectPlanningQuarterMapper.selectByPlanningIdAndDistributionYearAndQuarter(
|
||||
planningId, distributionYear, quarterNo);
|
||||
private void validateQuarterUnique(Long id, Long planningId, Long guideDetailId,
|
||||
Integer distributionYear, Integer quarterNo) {
|
||||
ProjectPlanningQuarterDO quarter = guideDetailId == null
|
||||
? projectPlanningQuarterMapper.selectParentByPlanningIdAndDistributionYearAndQuarter(
|
||||
planningId, distributionYear, quarterNo)
|
||||
: projectPlanningQuarterMapper.selectByPlanningIdAndGuideDetailIdAndDistributionYearAndQuarter(
|
||||
planningId, guideDetailId, distributionYear, quarterNo);
|
||||
if (quarter == null) {
|
||||
return;
|
||||
}
|
||||
@@ -115,14 +133,53 @@ public class ProjectPlanningQuarterServiceImpl implements ProjectPlanningQuarter
|
||||
return quarter;
|
||||
}
|
||||
|
||||
private ProjectPlanningGuideDetailDO validateGuideDetailScope(ProjectPlanningDO planning, Long guideDetailId) {
|
||||
boolean guideDetailMode = ProjectPlanningBizTypeConstants.isMajorGuidanceScene(
|
||||
planning.getOwnershipType(), planning.getCalculationMethod());
|
||||
if (!guideDetailMode) {
|
||||
if (guideDetailId != null) {
|
||||
throw exception(PROJECT_PLANNING_QUARTER_GUIDE_DETAIL_NOT_ALLOWED);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (guideDetailId == null) {
|
||||
throw exception(PROJECT_PLANNING_QUARTER_GUIDE_DETAIL_REQUIRED);
|
||||
}
|
||||
ProjectPlanningGuideDetailDO guideDetail = projectPlanningGuideDetailMapper.selectById(guideDetailId);
|
||||
if (guideDetail == null || !Objects.equals(guideDetail.getPlanningId(), planning.getId())) {
|
||||
throw exception(PROJECT_PLANNING_QUARTER_GUIDE_DETAIL_INVALID);
|
||||
}
|
||||
return guideDetail;
|
||||
}
|
||||
|
||||
private void validateScopeNotMixed(Long id, Long planningId, ProjectPlanningGuideDetailDO guideDetail) {
|
||||
boolean savingParentQuarter = guideDetail == null;
|
||||
boolean mixed = savingParentQuarter
|
||||
? projectPlanningQuarterMapper.existsGuideDetailQuarter(planningId, id)
|
||||
: projectPlanningQuarterMapper.existsParentQuarter(planningId, id);
|
||||
if (mixed) {
|
||||
throw exception(PROJECT_PLANNING_QUARTER_SCOPE_MIXED);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isZeroQuarter(ProjectPlanningQuarterSaveReqVO reqVO) {
|
||||
return ratio(reqVO.getDistributionRatio()).compareTo(BigDecimal.ZERO) == 0;
|
||||
}
|
||||
|
||||
private void prepareQuarter(ProjectPlanningQuarterDO quarter, ProjectPlanningDO planning) {
|
||||
private void prepareQuarter(ProjectPlanningQuarterDO quarter, ProjectPlanningDO planning,
|
||||
ProjectPlanningGuideDetailDO guideDetail) {
|
||||
quarter.setDistributionRatio(ratio(quarter.getDistributionRatio()));
|
||||
if (guideDetail == null) {
|
||||
quarter.setGuideDetailId(null);
|
||||
quarter.setGuideDetailSortNo(null);
|
||||
} else {
|
||||
quarter.setGuideDetailId(guideDetail.getId());
|
||||
quarter.setGuideDetailSortNo(guideDetail.getSortNo());
|
||||
}
|
||||
BigDecimal assessmentOutputValue = guideDetail == null
|
||||
? planning.getAssessmentOutputValue() : guideDetail.getAssessmentOutputValue();
|
||||
quarter.setDistributionAmount(multiplyAmount(
|
||||
planning.getAssessmentOutputValue(),
|
||||
assessmentOutputValue,
|
||||
planning.getTotalDistributionAmount(),
|
||||
quarter.getDistributionRatio()));
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package cn.iocoder.lyzsys.module.tjt.service.profit;
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.profit.vo.ProjectProfitPageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.profit.vo.ProjectProfitRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.profit.vo.ProjectProfitSettlementSaveReqVO;
|
||||
|
||||
/**
|
||||
* 项目盈亏 Service 接口
|
||||
@@ -15,4 +16,10 @@ public interface ProjectProfitService {
|
||||
|
||||
PageResult<ProjectProfitRespVO> getProjectProfitPage(ProjectProfitPageReqVO pageReqVO);
|
||||
|
||||
ProjectProfitRespVO lockBudgetSnapshot(Long projectId);
|
||||
|
||||
ProjectProfitRespVO lockAccountingSnapshot(Long projectId);
|
||||
|
||||
ProjectProfitRespVO saveSettlementSnapshot(ProjectProfitSettlementSaveReqVO saveReqVO);
|
||||
|
||||
}
|
||||
|
||||
@@ -2,17 +2,20 @@ package cn.iocoder.lyzsys.module.tjt.service.profit;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.lyzsys.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.lyzsys.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.lyzsys.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.profit.vo.ProjectProfitPageReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.profit.vo.ProjectProfitRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.profit.vo.ProjectProfitSettlementSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.profit.vo.ProjectProfitSnapshotRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planning.ProjectPlanningDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planningquarter.ProjectPlanningQuarterDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.profit.ProjectCostMeasureSnapshotDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.project.ProjectDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.yearkvalue.YearKValueDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.planning.ProjectPlanningMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.planningquarter.ProjectPlanningQuarterMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.profit.ProjectCostMeasureSnapshotMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.project.ProjectMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.yearkvalue.YearKValueMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.enums.ProjectCostMeasureSnapshotTypeEnum;
|
||||
import cn.iocoder.lyzsys.module.tjt.enums.ProjectPlanningBizTypeConstants;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -20,7 +23,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Collection;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -28,6 +31,10 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_COST_MEASURE_ACCOUNTING_LOCKED;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_COST_MEASURE_ACCOUNTING_REQUIRED;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_COST_MEASURE_BUDGET_LOCKED;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_COST_MEASURE_BUDGET_REQUIRED;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_NOT_EXISTS;
|
||||
|
||||
@Service
|
||||
@@ -36,25 +43,24 @@ public class ProjectProfitServiceImpl implements ProjectProfitService {
|
||||
|
||||
private static final BigDecimal ZERO_AMOUNT = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
|
||||
private static final BigDecimal ZERO_RATIO = BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP);
|
||||
private static final BigDecimal ONE_RATIO = BigDecimal.ONE.setScale(4, RoundingMode.HALF_UP);
|
||||
private static final BigDecimal DEFAULT_INNOVATION_OUTPUT_RATE = new BigDecimal("0.0100");
|
||||
private static final BigDecimal DEFAULT_YEAR_K_VALUE = new BigDecimal("0.4000");
|
||||
private static final BigDecimal ASSESSMENT_COEFFICIENT_EXCELLENT = new BigDecimal("1.0200");
|
||||
private static final BigDecimal ASSESSMENT_COEFFICIENT_QUALIFIED = new BigDecimal("1.0000");
|
||||
private static final BigDecimal ASSESSMENT_COEFFICIENT_NEEDS_IMPROVEMENT = new BigDecimal("0.9500");
|
||||
private static final BigDecimal VAT_INCLUDED_DIVISOR = new BigDecimal("1.06");
|
||||
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
@Resource
|
||||
private ProjectPlanningMapper projectPlanningMapper;
|
||||
@Resource
|
||||
private ProjectPlanningQuarterMapper projectPlanningQuarterMapper;
|
||||
@Resource
|
||||
private YearKValueMapper yearKValueMapper;
|
||||
private ProjectCostMeasureSnapshotMapper projectCostMeasureSnapshotMapper;
|
||||
|
||||
@Override
|
||||
public ProjectProfitRespVO getProjectProfit(Long projectId) {
|
||||
ProjectDO project = validateProjectExists(projectId);
|
||||
List<ProjectPlanningDO> planningList = projectPlanningMapper.selectList(ProjectPlanningDO::getProjectId,
|
||||
Collections.singleton(projectId));
|
||||
return buildProjectProfit(project, planningList);
|
||||
ProjectProfitRespVO respVO = buildCurrentProjectProfit(projectId);
|
||||
fillSnapshots(respVO);
|
||||
return respVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,48 +84,145 @@ public class ProjectProfitServiceImpl implements ProjectProfitService {
|
||||
return new PageResult<>(list, pageResult.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectProfitRespVO lockBudgetSnapshot(Long projectId) {
|
||||
ProjectProfitRespVO currentProfit = buildCurrentProjectProfit(projectId);
|
||||
if (projectCostMeasureSnapshotMapper.selectByProjectIdAndType(projectId,
|
||||
ProjectCostMeasureSnapshotTypeEnum.BUDGET.getCode()) != null) {
|
||||
throw exception(PROJECT_COST_MEASURE_BUDGET_LOCKED);
|
||||
}
|
||||
ProjectCostMeasureSnapshotDO snapshot = buildSnapshot(currentProfit, ProjectCostMeasureSnapshotTypeEnum.BUDGET.getCode());
|
||||
snapshot.setLockedFlag(Boolean.TRUE);
|
||||
fillActionInfo(snapshot);
|
||||
projectCostMeasureSnapshotMapper.insert(snapshot);
|
||||
return getProjectProfit(projectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectProfitRespVO lockAccountingSnapshot(Long projectId) {
|
||||
ProjectProfitRespVO currentProfit = buildCurrentProjectProfit(projectId);
|
||||
ProjectCostMeasureSnapshotDO budgetSnapshot = projectCostMeasureSnapshotMapper.selectByProjectIdAndType(projectId,
|
||||
ProjectCostMeasureSnapshotTypeEnum.BUDGET.getCode());
|
||||
if (budgetSnapshot == null || !Boolean.TRUE.equals(budgetSnapshot.getLockedFlag())) {
|
||||
throw exception(PROJECT_COST_MEASURE_BUDGET_REQUIRED);
|
||||
}
|
||||
if (projectCostMeasureSnapshotMapper.selectByProjectIdAndType(projectId,
|
||||
ProjectCostMeasureSnapshotTypeEnum.ACCOUNTING.getCode()) != null) {
|
||||
throw exception(PROJECT_COST_MEASURE_ACCOUNTING_LOCKED);
|
||||
}
|
||||
ProjectCostMeasureSnapshotDO snapshot = buildSnapshot(currentProfit, ProjectCostMeasureSnapshotTypeEnum.ACCOUNTING.getCode());
|
||||
snapshot.setLockedFlag(Boolean.TRUE);
|
||||
fillActionInfo(snapshot);
|
||||
projectCostMeasureSnapshotMapper.insert(snapshot);
|
||||
return getProjectProfit(projectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectProfitRespVO saveSettlementSnapshot(ProjectProfitSettlementSaveReqVO saveReqVO) {
|
||||
validateProjectExists(saveReqVO.getProjectId());
|
||||
ProjectCostMeasureSnapshotDO accountingSnapshot = projectCostMeasureSnapshotMapper.selectByProjectIdAndType(
|
||||
saveReqVO.getProjectId(), ProjectCostMeasureSnapshotTypeEnum.ACCOUNTING.getCode());
|
||||
if (accountingSnapshot == null || !Boolean.TRUE.equals(accountingSnapshot.getLockedFlag())) {
|
||||
throw exception(PROJECT_COST_MEASURE_ACCOUNTING_REQUIRED);
|
||||
}
|
||||
|
||||
ProjectCostMeasureSnapshotDO settlementSnapshot = projectCostMeasureSnapshotMapper.selectByProjectIdAndType(
|
||||
saveReqVO.getProjectId(), ProjectCostMeasureSnapshotTypeEnum.SETTLEMENT.getCode());
|
||||
boolean create = settlementSnapshot == null;
|
||||
if (create) {
|
||||
settlementSnapshot = new ProjectCostMeasureSnapshotDO();
|
||||
}
|
||||
copySnapshotValues(accountingSnapshot, settlementSnapshot);
|
||||
settlementSnapshot.setProjectId(saveReqVO.getProjectId());
|
||||
settlementSnapshot.setSnapshotType(ProjectCostMeasureSnapshotTypeEnum.SETTLEMENT.getCode());
|
||||
settlementSnapshot.setLockedFlag(Boolean.FALSE);
|
||||
settlementSnapshot.setAssessmentResult(saveReqVO.getAssessmentResult());
|
||||
settlementSnapshot.setAssessmentCoefficient(getAssessmentCoefficient(saveReqVO.getAssessmentResult()));
|
||||
settlementSnapshot.setRemark(saveReqVO.getRemark());
|
||||
|
||||
BigDecimal comprehensiveAccountingOutputValue = amount(accountingSnapshot.getComprehensivePlanningAmount());
|
||||
BigDecimal majorAccountingOutputValue = amount(accountingSnapshot.getMajorOutputValue());
|
||||
settlementSnapshot.setComprehensiveAccountingOutputValue(comprehensiveAccountingOutputValue);
|
||||
settlementSnapshot.setMajorAccountingOutputValue(majorAccountingOutputValue);
|
||||
settlementSnapshot.setComprehensiveSettlementOutputValue(
|
||||
multiplyAmount(comprehensiveAccountingOutputValue, settlementSnapshot.getAssessmentCoefficient()));
|
||||
settlementSnapshot.setMajorSettlementOutputValue(
|
||||
multiplyAmount(majorAccountingOutputValue, settlementSnapshot.getAssessmentCoefficient()));
|
||||
fillActionInfo(settlementSnapshot);
|
||||
|
||||
if (create) {
|
||||
projectCostMeasureSnapshotMapper.insert(settlementSnapshot);
|
||||
} else {
|
||||
projectCostMeasureSnapshotMapper.updateById(settlementSnapshot);
|
||||
}
|
||||
return getProjectProfit(saveReqVO.getProjectId());
|
||||
}
|
||||
|
||||
private ProjectProfitRespVO buildCurrentProjectProfit(Long projectId) {
|
||||
ProjectDO project = validateProjectExists(projectId);
|
||||
List<ProjectPlanningDO> planningList = projectPlanningMapper.selectList(ProjectPlanningDO::getProjectId,
|
||||
Collections.singleton(projectId));
|
||||
return buildProjectProfit(project, planningList);
|
||||
}
|
||||
|
||||
private ProjectProfitRespVO buildProjectProfit(ProjectDO project, List<ProjectPlanningDO> planningList) {
|
||||
List<ProjectPlanningDO> safePlanningList = planningList == null ? Collections.emptyList() : planningList;
|
||||
BigDecimal comprehensivePlanningAmount = ZERO_AMOUNT;
|
||||
BigDecimal subcontractPlanningAmount = ZERO_AMOUNT;
|
||||
BigDecimal specialSubcontractPlanningAmount = ZERO_AMOUNT;
|
||||
BigDecimal sourceCoopSubcontractPlanningAmount = ZERO_AMOUNT;
|
||||
BigDecimal comprehensiveSubcontractPlanningAmount = ZERO_AMOUNT;
|
||||
BigDecimal majorExpectedPerformance = ZERO_AMOUNT;
|
||||
BigDecimal majorOutputValue = ZERO_AMOUNT;
|
||||
List<ProjectPlanningDO> majorPlanningList = safePlanningList.stream()
|
||||
.filter(planning -> ProjectPlanningBizTypeConstants.isMajor(planning.getOwnershipType()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (ProjectPlanningDO planning : safePlanningList) {
|
||||
BigDecimal planningBudgetOutputValue = amount(planning.getProjectBudgetOutputValue());
|
||||
if (ProjectPlanningBizTypeConstants.isComprehensive(planning.getOwnershipType())) {
|
||||
comprehensivePlanningAmount = comprehensivePlanningAmount.add(amount(planning.getPlanningAmount()));
|
||||
comprehensivePlanningAmount = comprehensivePlanningAmount.add(planningBudgetOutputValue);
|
||||
continue;
|
||||
}
|
||||
if (ProjectPlanningBizTypeConstants.isSubcontract(planning.getOwnershipType())) {
|
||||
subcontractPlanningAmount = subcontractPlanningAmount.add(amount(planning.getPlanningAmount()));
|
||||
if (ProjectPlanningBizTypeConstants.isSpecialSubcontract(planning.getOwnershipType())) {
|
||||
specialSubcontractPlanningAmount = specialSubcontractPlanningAmount.add(planningBudgetOutputValue);
|
||||
continue;
|
||||
}
|
||||
if (ProjectPlanningBizTypeConstants.isSourceCoopSubcontract(planning.getOwnershipType())) {
|
||||
sourceCoopSubcontractPlanningAmount = sourceCoopSubcontractPlanningAmount.add(planningBudgetOutputValue);
|
||||
continue;
|
||||
}
|
||||
if (ProjectPlanningBizTypeConstants.isComprehensiveSubcontract(planning.getOwnershipType())) {
|
||||
comprehensiveSubcontractPlanningAmount = comprehensiveSubcontractPlanningAmount.add(planningBudgetOutputValue);
|
||||
continue;
|
||||
}
|
||||
if (ProjectPlanningBizTypeConstants.isMajor(planning.getOwnershipType())) {
|
||||
majorExpectedPerformance = majorExpectedPerformance.add(planningBudgetOutputValue);
|
||||
majorOutputValue = majorOutputValue.add(amount(planning.getAssessmentOutputValue()));
|
||||
}
|
||||
}
|
||||
|
||||
BigDecimal majorExpectedPerformance = calculateMajorExpectedPerformance(majorPlanningList);
|
||||
BigDecimal contractAmount = amount(project.getContractAmount());
|
||||
BigDecimal contractAmountWithoutVat = taxExcludedAmount(contractAmount);
|
||||
BigDecimal finalSettlementAmount = amount(project.getFinalSettlementAmount());
|
||||
BigDecimal effectiveContractSettlementAmount = finalSettlementAmount.compareTo(BigDecimal.ZERO) > 0
|
||||
? finalSettlementAmount : contractAmount;
|
||||
BigDecimal taxExcludedSettlementAmount = taxExcludedAmount(effectiveContractSettlementAmount);
|
||||
BigDecimal innovationOutputRate = project.getInnovationOutputRate() == null
|
||||
? DEFAULT_INNOVATION_OUTPUT_RATE : ratio(project.getInnovationOutputRate());
|
||||
BigDecimal innovationOutputValue = contractAmount.compareTo(BigDecimal.ZERO) <= 0
|
||||
? ZERO_AMOUNT
|
||||
: contractAmount.multiply(innovationOutputRate).setScale(2, RoundingMode.HALF_UP);
|
||||
BigDecimal otherCost = amount(project.getOtherCost());
|
||||
BigDecimal profitLossValue = finalSettlementAmount
|
||||
BigDecimal subcontractPlanningAmount = specialSubcontractPlanningAmount
|
||||
.add(sourceCoopSubcontractPlanningAmount)
|
||||
.add(comprehensiveSubcontractPlanningAmount);
|
||||
BigDecimal profitLossValue = taxExcludedSettlementAmount
|
||||
.subtract(comprehensivePlanningAmount)
|
||||
.subtract(subcontractPlanningAmount)
|
||||
.subtract(majorExpectedPerformance)
|
||||
.subtract(innovationOutputValue)
|
||||
.subtract(otherCost)
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
BigDecimal profitLossRate = finalSettlementAmount.compareTo(BigDecimal.ZERO) == 0
|
||||
BigDecimal profitLossRate = taxExcludedSettlementAmount.compareTo(BigDecimal.ZERO) == 0
|
||||
? ZERO_RATIO
|
||||
: profitLossValue.divide(finalSettlementAmount, 4, RoundingMode.HALF_UP);
|
||||
: profitLossValue.divide(taxExcludedSettlementAmount, 4, RoundingMode.HALF_UP);
|
||||
|
||||
ProjectProfitRespVO respVO = new ProjectProfitRespVO();
|
||||
respVO.setProjectId(project.getId());
|
||||
@@ -128,10 +231,15 @@ public class ProjectProfitServiceImpl implements ProjectProfitService {
|
||||
respVO.setContractSignedFlag(project.getContractSignedFlag());
|
||||
respVO.setContractAmount(contractAmount);
|
||||
respVO.setFinalSettlementAmount(finalSettlementAmount);
|
||||
// 历史字段名沿用 effectiveSettlementAmount,当前业务含义为“合同产值(不含增值税)”。
|
||||
respVO.setEffectiveSettlementAmount(contractAmountWithoutVat);
|
||||
respVO.setComprehensivePlanningAmount(comprehensivePlanningAmount.setScale(2, RoundingMode.HALF_UP));
|
||||
respVO.setSubcontractPlanningAmount(subcontractPlanningAmount.setScale(2, RoundingMode.HALF_UP));
|
||||
respVO.setSpecialSubcontractPlanningAmount(specialSubcontractPlanningAmount.setScale(2, RoundingMode.HALF_UP));
|
||||
respVO.setSourceCoopSubcontractPlanningAmount(sourceCoopSubcontractPlanningAmount.setScale(2, RoundingMode.HALF_UP));
|
||||
respVO.setComprehensiveSubcontractPlanningAmount(comprehensiveSubcontractPlanningAmount.setScale(2, RoundingMode.HALF_UP));
|
||||
respVO.setMajorOutputValue(majorOutputValue.setScale(2, RoundingMode.HALF_UP));
|
||||
respVO.setMajorExpectedPerformance(majorExpectedPerformance);
|
||||
respVO.setMajorExpectedPerformance(majorExpectedPerformance.setScale(2, RoundingMode.HALF_UP));
|
||||
respVO.setInnovationOutputRate(innovationOutputRate);
|
||||
respVO.setInnovationOutputValue(innovationOutputValue);
|
||||
respVO.setOtherCost(otherCost);
|
||||
@@ -142,41 +250,66 @@ public class ProjectProfitServiceImpl implements ProjectProfitService {
|
||||
return respVO;
|
||||
}
|
||||
|
||||
private BigDecimal calculateMajorExpectedPerformance(List<ProjectPlanningDO> majorPlanningList) {
|
||||
if (majorPlanningList == null || majorPlanningList.isEmpty()) {
|
||||
return ZERO_AMOUNT;
|
||||
private void fillSnapshots(ProjectProfitRespVO respVO) {
|
||||
Map<String, ProjectCostMeasureSnapshotDO> snapshotMap = projectCostMeasureSnapshotMapper
|
||||
.selectListByProjectId(respVO.getProjectId())
|
||||
.stream()
|
||||
.collect(Collectors.toMap(ProjectCostMeasureSnapshotDO::getSnapshotType, item -> item, (a, b) -> b));
|
||||
respVO.setBudgetSnapshot(toSnapshotRespVO(snapshotMap.get(ProjectCostMeasureSnapshotTypeEnum.BUDGET.getCode())));
|
||||
respVO.setAccountingSnapshot(toSnapshotRespVO(snapshotMap.get(ProjectCostMeasureSnapshotTypeEnum.ACCOUNTING.getCode())));
|
||||
respVO.setSettlementSnapshot(toSnapshotRespVO(snapshotMap.get(ProjectCostMeasureSnapshotTypeEnum.SETTLEMENT.getCode())));
|
||||
}
|
||||
List<Long> planningIds = majorPlanningList.stream().map(ProjectPlanningDO::getId).collect(Collectors.toList());
|
||||
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap = CollectionUtils.convertMultiMap(
|
||||
projectPlanningQuarterMapper.selectListByPlanningIds(planningIds), ProjectPlanningQuarterDO::getPlanningId);
|
||||
Set<Integer> years = quarterMap.values().stream()
|
||||
.flatMap(Collection::stream)
|
||||
.map(ProjectPlanningQuarterDO::getDistributionYear)
|
||||
.collect(Collectors.toSet());
|
||||
Map<Integer, BigDecimal> yearKValueMap = yearKValueMapper.selectEnabledListByYears(years).stream()
|
||||
.collect(Collectors.toMap(YearKValueDO::getKYear, item -> ratio(item.getKValue()), (a, b) -> b));
|
||||
|
||||
BigDecimal total = ZERO_AMOUNT;
|
||||
for (ProjectPlanningDO planning : majorPlanningList) {
|
||||
BigDecimal assessmentOutputValue = amount(planning.getAssessmentOutputValue());
|
||||
Map<Integer, BigDecimal> yearRatioMap = quarterMap.getOrDefault(planning.getId(), Collections.emptyList()).stream()
|
||||
.collect(Collectors.groupingBy(ProjectPlanningQuarterDO::getDistributionYear,
|
||||
Collectors.reducing(ZERO_RATIO,
|
||||
item -> ratio(item.getDistributionRatio()),
|
||||
BigDecimal::add)));
|
||||
BigDecimal allocatedRatio = ZERO_RATIO;
|
||||
for (Map.Entry<Integer, BigDecimal> entry : yearRatioMap.entrySet()) {
|
||||
BigDecimal yearRatio = ratio(entry.getValue());
|
||||
allocatedRatio = allocatedRatio.add(yearRatio).setScale(4, RoundingMode.HALF_UP);
|
||||
BigDecimal kValue = yearKValueMap.getOrDefault(entry.getKey(), DEFAULT_YEAR_K_VALUE);
|
||||
total = total.add(multiplyAmount(assessmentOutputValue, yearRatio, kValue));
|
||||
private ProjectCostMeasureSnapshotDO buildSnapshot(ProjectProfitRespVO profit, String snapshotType) {
|
||||
ProjectCostMeasureSnapshotDO snapshot = new ProjectCostMeasureSnapshotDO();
|
||||
snapshot.setProjectId(profit.getProjectId());
|
||||
snapshot.setSnapshotType(snapshotType);
|
||||
snapshot.setContractAmount(amount(profit.getContractAmount()));
|
||||
snapshot.setFinalSettlementAmount(amount(profit.getFinalSettlementAmount()));
|
||||
snapshot.setEffectiveSettlementAmount(amount(profit.getEffectiveSettlementAmount()));
|
||||
snapshot.setComprehensivePlanningAmount(amount(profit.getComprehensivePlanningAmount()));
|
||||
snapshot.setSubcontractPlanningAmount(amount(profit.getSubcontractPlanningAmount()));
|
||||
snapshot.setSpecialSubcontractPlanningAmount(amount(profit.getSpecialSubcontractPlanningAmount()));
|
||||
snapshot.setSourceCoopSubcontractPlanningAmount(amount(profit.getSourceCoopSubcontractPlanningAmount()));
|
||||
snapshot.setComprehensiveSubcontractPlanningAmount(amount(profit.getComprehensiveSubcontractPlanningAmount()));
|
||||
snapshot.setMajorOutputValue(amount(profit.getMajorOutputValue()));
|
||||
snapshot.setMajorExpectedPerformance(amount(profit.getMajorExpectedPerformance()));
|
||||
snapshot.setInnovationOutputRate(ratio(profit.getInnovationOutputRate()));
|
||||
snapshot.setInnovationOutputValue(amount(profit.getInnovationOutputValue()));
|
||||
snapshot.setOtherCost(amount(profit.getOtherCost()));
|
||||
snapshot.setProfitLossValue(amount(profit.getProfitLossValue()));
|
||||
snapshot.setProfitLossRate(ratio(profit.getProfitLossRate()));
|
||||
return snapshot;
|
||||
}
|
||||
BigDecimal unallocatedRatio = ONE_RATIO.subtract(allocatedRatio).setScale(4, RoundingMode.HALF_UP);
|
||||
if (unallocatedRatio.compareTo(ZERO_RATIO) > 0) {
|
||||
total = total.add(multiplyAmount(assessmentOutputValue, unallocatedRatio, DEFAULT_YEAR_K_VALUE));
|
||||
|
||||
private void copySnapshotValues(ProjectCostMeasureSnapshotDO source, ProjectCostMeasureSnapshotDO target) {
|
||||
target.setContractAmount(amount(source.getContractAmount()));
|
||||
target.setFinalSettlementAmount(amount(source.getFinalSettlementAmount()));
|
||||
target.setEffectiveSettlementAmount(amount(source.getEffectiveSettlementAmount()));
|
||||
target.setComprehensivePlanningAmount(amount(source.getComprehensivePlanningAmount()));
|
||||
target.setSubcontractPlanningAmount(amount(source.getSubcontractPlanningAmount()));
|
||||
target.setSpecialSubcontractPlanningAmount(amount(source.getSpecialSubcontractPlanningAmount()));
|
||||
target.setSourceCoopSubcontractPlanningAmount(amount(source.getSourceCoopSubcontractPlanningAmount()));
|
||||
target.setComprehensiveSubcontractPlanningAmount(amount(source.getComprehensiveSubcontractPlanningAmount()));
|
||||
target.setMajorOutputValue(amount(source.getMajorOutputValue()));
|
||||
target.setMajorExpectedPerformance(amount(source.getMajorExpectedPerformance()));
|
||||
target.setInnovationOutputRate(ratio(source.getInnovationOutputRate()));
|
||||
target.setInnovationOutputValue(amount(source.getInnovationOutputValue()));
|
||||
target.setOtherCost(amount(source.getOtherCost()));
|
||||
target.setProfitLossValue(amount(source.getProfitLossValue()));
|
||||
target.setProfitLossRate(ratio(source.getProfitLossRate()));
|
||||
}
|
||||
|
||||
private void fillActionInfo(ProjectCostMeasureSnapshotDO snapshot) {
|
||||
Long userId = SecurityFrameworkUtils.getLoginUserId();
|
||||
String nickname = SecurityFrameworkUtils.getLoginUserNickname();
|
||||
snapshot.setActionUserId(userId);
|
||||
snapshot.setActionUserName(nickname == null ? "" : nickname);
|
||||
snapshot.setActionTime(LocalDateTime.now());
|
||||
}
|
||||
return total.setScale(2, RoundingMode.HALF_UP);
|
||||
|
||||
private ProjectProfitSnapshotRespVO toSnapshotRespVO(ProjectCostMeasureSnapshotDO snapshot) {
|
||||
return snapshot == null ? null : BeanUtils.toBean(snapshot, ProjectProfitSnapshotRespVO.class);
|
||||
}
|
||||
|
||||
private ProjectDO validateProjectExists(Long projectId) {
|
||||
@@ -195,6 +328,24 @@ public class ProjectProfitServiceImpl implements ProjectProfitService {
|
||||
return value == null ? ZERO_RATIO : value.setScale(4, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private BigDecimal taxExcludedAmount(BigDecimal amount) {
|
||||
BigDecimal value = amount(amount);
|
||||
if (value.compareTo(BigDecimal.ZERO) == 0) {
|
||||
return ZERO_AMOUNT;
|
||||
}
|
||||
return value.divide(VAT_INCLUDED_DIVISOR, 2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private BigDecimal getAssessmentCoefficient(String assessmentResult) {
|
||||
if ("优秀".equals(assessmentResult)) {
|
||||
return ASSESSMENT_COEFFICIENT_EXCELLENT;
|
||||
}
|
||||
if ("待改进".equals(assessmentResult)) {
|
||||
return ASSESSMENT_COEFFICIENT_NEEDS_IMPROVEMENT;
|
||||
}
|
||||
return ASSESSMENT_COEFFICIENT_QUALIFIED;
|
||||
}
|
||||
|
||||
private BigDecimal multiplyAmount(BigDecimal... values) {
|
||||
BigDecimal result = BigDecimal.ONE;
|
||||
for (BigDecimal value : values) {
|
||||
|
||||
@@ -18,6 +18,8 @@ import cn.iocoder.lyzsys.module.tjt.dal.mysql.planning.ProjectPlanningMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.planningquarter.ProjectPlanningQuarterMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.project.ProjectMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.projectroleperson.ProjectRolePersonMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.enums.OutputSplitBizConstants;
|
||||
import cn.iocoder.lyzsys.module.tjt.enums.ProjectStatusEnum;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.employee.EmployeeService;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.outputsplit.ProjectOutputSplitService;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.planningguidedetail.ProjectPlanningGuideDetailService;
|
||||
@@ -37,6 +39,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_NOT_EXISTS;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_STATUS_INVALID;
|
||||
|
||||
/**
|
||||
* 项目 Service 实现类
|
||||
@@ -47,14 +50,12 @@ import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_NOT_
|
||||
@Validated
|
||||
public class ProjectServiceImpl implements ProjectService {
|
||||
|
||||
private static final String ROLE_CODE_PROJECT_MANAGER = "project_manager";
|
||||
private static final String ROLE_CODE_ENGINEERING_PRINCIPAL = "engineering_principal";
|
||||
private static final String ROLE_NAME_PROJECT_MANAGER = "项目经理";
|
||||
private static final String ROLE_NAME_ENGINEERING_PRINCIPAL = "工程负责人";
|
||||
private static final String STATUS_IN_PROGRESS = "进行中";
|
||||
private static final String STATUS_COMPLETED = "完成";
|
||||
private static final String STATUS_PAUSED = "暂停";
|
||||
private static final String STATUS_TERMINATED = "中止";
|
||||
private static final String ROLE_CODE_PROJECT_MANAGER = OutputSplitBizConstants.ROLE_PROJECT_MANAGER;
|
||||
private static final String ROLE_CODE_ENGINEERING_PRINCIPAL = OutputSplitBizConstants.ROLE_ENGINEERING_PRINCIPAL;
|
||||
private static final String STATUS_IN_PROGRESS = ProjectStatusEnum.IN_PROGRESS.getCode();
|
||||
private static final String STATUS_COMPLETED = ProjectStatusEnum.COMPLETED.getCode();
|
||||
private static final String STATUS_PAUSED = ProjectStatusEnum.PAUSED.getCode();
|
||||
private static final String STATUS_TERMINATED = ProjectStatusEnum.TERMINATED.getCode();
|
||||
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
@@ -141,14 +142,17 @@ public class ProjectServiceImpl implements ProjectService {
|
||||
if (project.getProjectStatus() == null || project.getProjectStatus().trim().isEmpty()) {
|
||||
project.setProjectStatus(dbProject == null ? STATUS_IN_PROGRESS : dbProject.getProjectStatus());
|
||||
}
|
||||
if (!ProjectStatusEnum.contains(project.getProjectStatus())) {
|
||||
throw exception(PROJECT_STATUS_INVALID);
|
||||
}
|
||||
if (project.getArchiveFlag() == null) {
|
||||
project.setArchiveFlag(dbProject != null && Boolean.TRUE.equals(dbProject.getArchiveFlag()));
|
||||
}
|
||||
if (project.getArchiveTime() == null && dbProject != null) {
|
||||
project.setArchiveTime(dbProject.getArchiveTime());
|
||||
}
|
||||
if (project.getSortNo() == null) {
|
||||
project.setSortNo(dbProject == null || dbProject.getSortNo() == null ? 0 : dbProject.getSortNo());
|
||||
if (project.getSortNo() == null && dbProject != null) {
|
||||
project.setSortNo(dbProject.getSortNo());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,10 +207,10 @@ public class ProjectServiceImpl implements ProjectService {
|
||||
|
||||
private String getRoleName(String roleCode) {
|
||||
if (Objects.equals(roleCode, ROLE_CODE_PROJECT_MANAGER)) {
|
||||
return ROLE_NAME_PROJECT_MANAGER;
|
||||
return OutputSplitBizConstants.getRoleName(roleCode);
|
||||
}
|
||||
if (Objects.equals(roleCode, ROLE_CODE_ENGINEERING_PRINCIPAL)) {
|
||||
return ROLE_NAME_ENGINEERING_PRINCIPAL;
|
||||
return OutputSplitBizConstants.getRoleName(roleCode);
|
||||
}
|
||||
return roleCode;
|
||||
}
|
||||
@@ -265,11 +269,8 @@ public class ProjectServiceImpl implements ProjectService {
|
||||
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap = CollectionUtils.convertMultiMap(
|
||||
projectPlanningQuarterMapper.selectListByPlanningIds(planningIds), ProjectPlanningQuarterDO::getPlanningId);
|
||||
for (ProjectPlanningDO planning : planningList) {
|
||||
java.math.BigDecimal allocatedRatio = quarterMap.getOrDefault(planning.getId(), Collections.emptyList()).stream()
|
||||
.map(ProjectPlanningQuarterDO::getDistributionRatio)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(java.math.BigDecimal.ZERO, java.math.BigDecimal::add)
|
||||
.setScale(4, java.math.RoundingMode.HALF_UP);
|
||||
java.math.BigDecimal allocatedRatio = resolveAllocatedRatio(
|
||||
planning, quarterMap.getOrDefault(planning.getId(), Collections.emptyList()));
|
||||
java.math.BigDecimal totalDistributionAmount = planning.getTotalDistributionAmount() == null
|
||||
? java.math.BigDecimal.ONE.setScale(4, java.math.RoundingMode.HALF_UP)
|
||||
: planning.getTotalDistributionAmount().setScale(4, java.math.RoundingMode.HALF_UP);
|
||||
@@ -280,6 +281,39 @@ public class ProjectServiceImpl implements ProjectService {
|
||||
return true;
|
||||
}
|
||||
|
||||
private java.math.BigDecimal resolveAllocatedRatio(ProjectPlanningDO planning, List<ProjectPlanningQuarterDO> quarterList) {
|
||||
if (quarterList == null || quarterList.isEmpty()) {
|
||||
return java.math.BigDecimal.ZERO.setScale(4, java.math.RoundingMode.HALF_UP);
|
||||
}
|
||||
boolean hasGuideDetailQuarter = quarterList.stream().anyMatch(item -> item.getGuideDetailId() != null);
|
||||
if (!hasGuideDetailQuarter) {
|
||||
return quarterList.stream()
|
||||
.map(ProjectPlanningQuarterDO::getDistributionRatio)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(java.math.BigDecimal.ZERO, java.math.BigDecimal::add)
|
||||
.setScale(4, java.math.RoundingMode.HALF_UP);
|
||||
}
|
||||
java.math.BigDecimal totalDistributionAmount = planning.getTotalDistributionAmount() == null
|
||||
? java.math.BigDecimal.ONE.setScale(4, java.math.RoundingMode.HALF_UP)
|
||||
: planning.getTotalDistributionAmount().setScale(4, java.math.RoundingMode.HALF_UP);
|
||||
java.math.BigDecimal baseAmount = amount(planning.getAssessmentOutputValue())
|
||||
.multiply(totalDistributionAmount)
|
||||
.setScale(2, java.math.RoundingMode.HALF_UP);
|
||||
if (baseAmount.compareTo(java.math.BigDecimal.ZERO) == 0) {
|
||||
return java.math.BigDecimal.ZERO.setScale(4, java.math.RoundingMode.HALF_UP);
|
||||
}
|
||||
java.math.BigDecimal allocatedAmount = quarterList.stream()
|
||||
.map(ProjectPlanningQuarterDO::getDistributionAmount)
|
||||
.map(this::amount)
|
||||
.reduce(java.math.BigDecimal.ZERO.setScale(2, java.math.RoundingMode.HALF_UP), java.math.BigDecimal::add);
|
||||
return allocatedAmount.divide(baseAmount, 4, java.math.RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private java.math.BigDecimal amount(java.math.BigDecimal value) {
|
||||
return value == null ? java.math.BigDecimal.ZERO.setScale(2, java.math.RoundingMode.HALF_UP)
|
||||
: value.setScale(2, java.math.RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private void deleteProjectDependencies(Collection<Long> projectIds) {
|
||||
if (projectIds == null || projectIds.isEmpty()) {
|
||||
return;
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.service.report;
|
||||
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.EmployeeOutputSummaryExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectBudgetExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectLeadQuarterOutputExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectOverviewExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.ProjectQuarterOutputExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.SpecialtyPersonOutputExportReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.report.vo.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
@@ -15,19 +10,31 @@ public interface ProjectOutputReportService {
|
||||
void exportProjectBudgetExcel(HttpServletResponse response, ProjectBudgetExportReqVO reqVO)
|
||||
throws IOException;
|
||||
|
||||
ProjectBudgetPreviewRespVO getProjectBudgetPreview(ProjectBudgetExportReqVO reqVO);
|
||||
|
||||
void exportProjectQuarterOutputExcel(HttpServletResponse response, ProjectQuarterOutputExportReqVO reqVO)
|
||||
throws IOException;
|
||||
|
||||
ProjectQuarterOutputPreviewRespVO getProjectQuarterOutputPreview(ProjectQuarterOutputExportReqVO reqVO);
|
||||
|
||||
void exportProjectLeadQuarterOutputExcel(HttpServletResponse response,
|
||||
ProjectLeadQuarterOutputExportReqVO reqVO)
|
||||
throws IOException;
|
||||
|
||||
ProjectLeadQuarterOutputPreviewRespVO getProjectLeadQuarterOutputPreview(ProjectLeadQuarterOutputExportReqVO reqVO);
|
||||
|
||||
void exportSpecialtyPersonOutputExcel(HttpServletResponse response, SpecialtyPersonOutputExportReqVO reqVO)
|
||||
throws IOException;
|
||||
|
||||
SpecialtyPersonOutputPreviewRespVO getSpecialtyPersonOutputPreview(SpecialtyPersonOutputPreviewReqVO reqVO);
|
||||
|
||||
ProjectOverviewPreviewRespVO getProjectOverviewPreview(ProjectOverviewExportReqVO reqVO);
|
||||
|
||||
void exportProjectOverviewExcel(HttpServletResponse response, ProjectOverviewExportReqVO reqVO)
|
||||
throws IOException;
|
||||
|
||||
EmployeeOutputSummaryPreviewRespVO getEmployeeOutputSummaryPreview(EmployeeOutputSummaryExportReqVO reqVO);
|
||||
|
||||
void exportEmployeeOutputSummaryExcel(HttpServletResponse response, EmployeeOutputSummaryExportReqVO reqVO)
|
||||
throws IOException;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,7 @@ public class EmployeeOutputSummaryExcelBuilder extends AbstractProjectOutputExce
|
||||
private static final String TITLE_PREFIX = "7.1.6 ";
|
||||
private static final String TITLE_SUFFIX = " 年设计中心员工个人考核产值汇总,全公司产值人员汇总表";
|
||||
private static final String SUBTITLE_SUFFIX = " 年设计中心员工个人考核产值汇总(单位:万元)";
|
||||
private static final int LAST_COL = 12;
|
||||
private static final int LAST_COL = 13;
|
||||
private static final int DETAIL_START_ROW_NUM = 4;
|
||||
|
||||
public Workbook build(ExportData data) {
|
||||
@@ -36,7 +36,7 @@ public class EmployeeOutputSummaryExcelBuilder extends AbstractProjectOutputExce
|
||||
|
||||
private void buildSheet(Workbook workbook, ExportData data) {
|
||||
Sheet sheet = createSheet(workbook, SHEET_NAME, SHEET_NAME);
|
||||
setColumnWidths(sheet, 8, 14, 12, 12, 12, 12, 12, 14, 14, 18, 14, 14, 14);
|
||||
setColumnWidths(sheet, 8, 16, 14, 12, 12, 12, 12, 12, 14, 14, 18, 14, 14, 14);
|
||||
|
||||
CellStyle subtitleStyle = createDerivedStyle(workbook, createInfoStyle(workbook),
|
||||
null, HorizontalAlignment.CENTER, true, (short) 11);
|
||||
@@ -80,7 +80,7 @@ public class EmployeeOutputSummaryExcelBuilder extends AbstractProjectOutputExce
|
||||
|
||||
private int writeHeaderRow(Sheet sheet, int rowIndex, CellStyle style) {
|
||||
writeRow(sheet, rowIndex, style,
|
||||
"序号", "姓名", "第一季度", "第二季度", "第三季度", "第四季度", "年度合计",
|
||||
"序号", "专业所", "姓名", "第一季度", "第二季度", "第三季度", "第四季度", "年度合计",
|
||||
"所长 / BIM 考核产值", "年度考核产值合计", "1~12 月份预计发生成本(含预计精神文明奖)",
|
||||
"基本考核产值", "剩余产值", "预估年底绩效");
|
||||
return rowIndex + 1;
|
||||
@@ -92,19 +92,20 @@ public class EmployeeOutputSummaryExcelBuilder extends AbstractProjectOutputExce
|
||||
Row row = sheet.createRow(rowIndex);
|
||||
int excelRowNum = rowIndex + 1;
|
||||
setText(row, 0, rowData == null || rowData.getSerialNo() == null ? "" : rowData.getSerialNo(), cellStyle);
|
||||
setText(row, 1, rowData == null ? "" : safeText(rowData.getEmployeeName()), leftCellStyle);
|
||||
setNumericCell(row, 2, rowData == null ? null : rowData.getQuarterOneAmount(), amountStyle);
|
||||
setNumericCell(row, 3, rowData == null ? null : rowData.getQuarterTwoAmount(), amountStyle);
|
||||
setNumericCell(row, 4, rowData == null ? null : rowData.getQuarterThreeAmount(), amountStyle);
|
||||
setNumericCell(row, 5, rowData == null ? null : rowData.getQuarterFourAmount(), amountStyle);
|
||||
setNumericCell(row, 6, rowData == null ? null : rowData.getAnnualTotalAmount(), amountStyle);
|
||||
setNumericCell(row, 7, rowData == null ? null : rowData.getOfficeLeaderOrBimAmount(), amountStyle);
|
||||
setNumericCell(row, 8, rowData == null ? null : rowData.getTotalAssessmentOutputAmount(), amountStyle);
|
||||
setNumericCell(row, 9, rowData == null ? null : rowData.getExpectedCostAmount(), amountStyle);
|
||||
setText(row, 1, rowData == null ? "" : safeText(rowData.getOfficeName()), leftCellStyle);
|
||||
setText(row, 2, rowData == null ? "" : safeText(rowData.getEmployeeName()), leftCellStyle);
|
||||
setNumericCell(row, 3, rowData == null ? null : rowData.getQuarterOneAmount(), amountStyle);
|
||||
setNumericCell(row, 4, rowData == null ? null : rowData.getQuarterTwoAmount(), amountStyle);
|
||||
setNumericCell(row, 5, rowData == null ? null : rowData.getQuarterThreeAmount(), amountStyle);
|
||||
setNumericCell(row, 6, rowData == null ? null : rowData.getQuarterFourAmount(), amountStyle);
|
||||
setNumericCell(row, 7, rowData == null ? null : rowData.getAnnualTotalAmount(), amountStyle);
|
||||
setNumericCell(row, 8, rowData == null ? null : rowData.getOfficeLeaderOrBimAmount(), amountStyle);
|
||||
setNumericCell(row, 9, rowData == null ? null : rowData.getTotalAssessmentOutputAmount(), amountStyle);
|
||||
setNumericCell(row, 10, rowData == null ? null : rowData.getExpectedCostAmount(), amountStyle);
|
||||
|
||||
setFormulaCell(row, 10, buildBasicAssessmentFormula(excelRowNum, data), formulaStyle);
|
||||
setFormulaCell(row, 11, buildRemainingOutputFormula(excelRowNum), formulaStyle);
|
||||
setFormulaCell(row, 12, buildPerformanceFormula(excelRowNum, data), formulaStyle);
|
||||
setFormulaCell(row, 11, buildBasicAssessmentFormula(excelRowNum, data), formulaStyle);
|
||||
setFormulaCell(row, 12, buildRemainingOutputFormula(excelRowNum), formulaStyle);
|
||||
setFormulaCell(row, 13, buildPerformanceFormula(excelRowNum, data), formulaStyle);
|
||||
}
|
||||
|
||||
private void writeTotalRow(Sheet sheet, int rowIndex, List<EmployeeOutputSummaryExcelRespVO> rows, ExportData data,
|
||||
@@ -115,8 +116,9 @@ public class EmployeeOutputSummaryExcelBuilder extends AbstractProjectOutputExce
|
||||
int detailEndRowNum = DETAIL_START_ROW_NUM + rows.size() - 1;
|
||||
|
||||
setText(row, 0, "", totalCellStyle);
|
||||
setText(row, 1, "合计", totalLeftCellStyle);
|
||||
for (int col = 2; col <= LAST_COL; col++) {
|
||||
setText(row, 1, "", totalLeftCellStyle);
|
||||
setText(row, 2, "合计", totalLeftCellStyle);
|
||||
for (int col = 3; col <= LAST_COL; col++) {
|
||||
if (rows.isEmpty()) {
|
||||
setNumericCell(row, col, BigDecimal.ZERO, totalStyle);
|
||||
continue;
|
||||
@@ -126,9 +128,9 @@ public class EmployeeOutputSummaryExcelBuilder extends AbstractProjectOutputExce
|
||||
}
|
||||
// Ensure total-row formulas survive even if Excel recalculation is disabled.
|
||||
if (!rows.isEmpty()) {
|
||||
row.getCell(10).setCellFormula(buildTotalBasicAssessmentFormula(totalExcelRowNum));
|
||||
row.getCell(11).setCellFormula(buildTotalRemainingOutputFormula(totalExcelRowNum));
|
||||
row.getCell(12).setCellFormula(buildTotalPerformanceFormula(totalExcelRowNum, data));
|
||||
row.getCell(11).setCellFormula(buildTotalBasicAssessmentFormula(totalExcelRowNum));
|
||||
row.getCell(12).setCellFormula(buildTotalRemainingOutputFormula(totalExcelRowNum));
|
||||
row.getCell(13).setCellFormula(buildTotalPerformanceFormula(totalExcelRowNum, data));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,11 +139,11 @@ public class EmployeeOutputSummaryExcelBuilder extends AbstractProjectOutputExce
|
||||
if (kValue.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
return "0";
|
||||
}
|
||||
return "ROUND(J" + excelRowNum + "/" + kValue.stripTrailingZeros().toPlainString() + ",2)";
|
||||
return "ROUND(K" + excelRowNum + "/" + kValue.stripTrailingZeros().toPlainString() + ",2)";
|
||||
}
|
||||
|
||||
private String buildRemainingOutputFormula(int excelRowNum) {
|
||||
return "ROUND(I" + excelRowNum + "-K" + excelRowNum + ",2)";
|
||||
return "ROUND(J" + excelRowNum + "-L" + excelRowNum + ",2)";
|
||||
}
|
||||
|
||||
private String buildPerformanceFormula(int excelRowNum, ExportData data) {
|
||||
@@ -149,21 +151,21 @@ public class EmployeeOutputSummaryExcelBuilder extends AbstractProjectOutputExce
|
||||
if (kValue.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
return "0";
|
||||
}
|
||||
return "ROUND(L" + excelRowNum + "*" + kValue.stripTrailingZeros().toPlainString() + ",2)";
|
||||
return "ROUND(M" + excelRowNum + "*" + kValue.stripTrailingZeros().toPlainString() + ",2)";
|
||||
}
|
||||
|
||||
private String buildTotalBasicAssessmentFormula(int excelRowNum) {
|
||||
return "SUM(K" + DETAIL_START_ROW_NUM + ":K" + (excelRowNum - 1) + ")";
|
||||
}
|
||||
|
||||
private String buildTotalRemainingOutputFormula(int excelRowNum) {
|
||||
return "SUM(L" + DETAIL_START_ROW_NUM + ":L" + (excelRowNum - 1) + ")";
|
||||
}
|
||||
|
||||
private String buildTotalPerformanceFormula(int excelRowNum, ExportData data) {
|
||||
private String buildTotalRemainingOutputFormula(int excelRowNum) {
|
||||
return "SUM(M" + DETAIL_START_ROW_NUM + ":M" + (excelRowNum - 1) + ")";
|
||||
}
|
||||
|
||||
private String buildTotalPerformanceFormula(int excelRowNum, ExportData data) {
|
||||
return "SUM(N" + DETAIL_START_ROW_NUM + ":N" + (excelRowNum - 1) + ")";
|
||||
}
|
||||
|
||||
private String safeYear(ExportData data) {
|
||||
return data == null || data.getYear() == null ? "" : String.valueOf(data.getYear());
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ProjectBudgetExcelBuilder extends AbstractProjectOutputExcelBuilder
|
||||
|
||||
private void buildBudgetSheet(Workbook workbook, ExportData data) {
|
||||
Sheet sheet = createSheet(workbook, BUDGET_SHEET_NAME, BUDGET_SHEET_FALLBACK_NAME);
|
||||
setColumnWidths(sheet, 16, 14, 18, 16, 18, 14, 12, 12, 12, 18, 12, 14, 16);
|
||||
setColumnWidths(sheet, 16, 14, 22, 16, 18, 14, 12, 12, 12, 18, 12, 14, 16);
|
||||
|
||||
CellStyle titleStyle = createTitleStyle(workbook);
|
||||
CellStyle infoStyle = createInfoStyle(workbook);
|
||||
@@ -110,7 +110,7 @@ public class ProjectBudgetExcelBuilder extends AbstractProjectOutputExcelBuilder
|
||||
setMergedRegionText(sheet, firstRow + 1, firstRow + 1, 7, 9, "调整系数", headerStyle);
|
||||
|
||||
writeRow(sheet, firstRow + 2, headerStyle, (Object[]) new String[]{
|
||||
"规划内容", "设计部位", "建筑类型", "", "", "栋数 / 户型数",
|
||||
"规划内容", "设计部位", "设计内容/设计类型", "", "", "栋数 / 户型数",
|
||||
"套图系数", "规模系数", "修改系数", "复杂系数 / 复杂等级", "", "", ""
|
||||
});
|
||||
return rowIndex + 3;
|
||||
|
||||
@@ -21,14 +21,16 @@ public class ProjectLeadQuarterOutputExcelBuilder extends AbstractProjectOutputE
|
||||
private static final String SHEET1_NAME = "工作量分配";
|
||||
private static final String SHEET2_NAME = "季度考核产值";
|
||||
private static final String SHEET1_TITLE = "项目经理/专业负责人人员工作量分配";
|
||||
private static final String SHEET2_TITLE = "项目经理/工程负责人年度/季度项目考核产值";
|
||||
private static final String SHEET2_TITLE = "工程负责人年度表";
|
||||
private static final String DEFAULT_PROJECT_MANAGER_HEADER = "项目经理人员";
|
||||
private static final String DEFAULT_ENGINEERING_HEADER = "工程负责人人员";
|
||||
private static final String DEFAULT_CENTER_SIGNER = "设计中心相关负责人(签名):";
|
||||
private static final String DEFAULT_PROJECT_SIGNER = "项目经理/工程负责人(签名):";
|
||||
private static final List<String> OUTPUT_TYPE_ORDER = Arrays.asList(
|
||||
"六大专业考核产值",
|
||||
"专业分包产值",
|
||||
"专项分包-专业所产值",
|
||||
"专项分包-源头合作分包产值",
|
||||
"专项分包-综合所产值",
|
||||
"内部协作产值",
|
||||
"其他产值"
|
||||
);
|
||||
|
||||
@@ -22,8 +22,8 @@ import java.util.Map;
|
||||
@Component
|
||||
public class ProjectQuarterOutputExcelBuilder extends AbstractProjectOutputExcelBuilder {
|
||||
|
||||
private static final String SHEET1_NAME = "专业间项目考核产值年度季度计取表";
|
||||
private static final String SHEET1_FALLBACK_NAME = "项目级年度季度计取表";
|
||||
private static final String SHEET1_NAME = "专业间年度表";
|
||||
private static final String SHEET1_FALLBACK_NAME = "专业间年度表";
|
||||
|
||||
private static final String SHEET2_NAME = "专业维度统计表";
|
||||
private static final String SHEET2_FALLBACK_NAME = "专业维度统计";
|
||||
@@ -36,14 +36,18 @@ public class ProjectQuarterOutputExcelBuilder extends AbstractProjectOutputExcel
|
||||
|
||||
private static final List<String> OUTPUT_TYPE_ORDER = Arrays.asList(
|
||||
"六大专业考核产值",
|
||||
"专业分包产值",
|
||||
"专项分包-专业所产值",
|
||||
"专项分包-源头合作分包产值",
|
||||
"专项分包-综合所产值",
|
||||
"内部协作产值",
|
||||
"其他产值"
|
||||
);
|
||||
|
||||
private static final List<String> FIXED_OUTPUT_TYPES = Arrays.asList(
|
||||
"六大专业考核产值",
|
||||
"专业分包产值",
|
||||
"专项分包-专业所产值",
|
||||
"专项分包-源头合作分包产值",
|
||||
"专项分包-综合所产值",
|
||||
"内部协作产值"
|
||||
);
|
||||
|
||||
|
||||
@@ -534,12 +534,18 @@ public class SpecialtyPersonOutputExcelBuilder extends AbstractProjectOutputExce
|
||||
if (Objects.equals(current, "六大专业考核产值")) {
|
||||
return 1;
|
||||
}
|
||||
if (Objects.equals(current, "专业分包产值")) {
|
||||
if (Objects.equals(current, "专项分包-专业所产值")) {
|
||||
return 2;
|
||||
}
|
||||
if (Objects.equals(current, "内部协作产值")) {
|
||||
if (Objects.equals(current, "专项分包-源头合作分包产值")) {
|
||||
return 3;
|
||||
}
|
||||
if (Objects.equals(current, "专项分包-综合所产值")) {
|
||||
return 4;
|
||||
}
|
||||
if (Objects.equals(current, "内部协作产值")) {
|
||||
return 5;
|
||||
}
|
||||
return 9;
|
||||
}
|
||||
|
||||
@@ -637,10 +643,15 @@ public class SpecialtyPersonOutputExcelBuilder extends AbstractProjectOutputExce
|
||||
|
||||
@Data
|
||||
public static class PersonAmountValue {
|
||||
private BigDecimal quarterOneRatio;
|
||||
private BigDecimal quarterOneAmountWan;
|
||||
private BigDecimal quarterTwoRatio;
|
||||
private BigDecimal quarterTwoAmountWan;
|
||||
private BigDecimal quarterThreeRatio;
|
||||
private BigDecimal quarterThreeAmountWan;
|
||||
private BigDecimal quarterFourRatio;
|
||||
private BigDecimal quarterFourAmountWan;
|
||||
private BigDecimal yearTotalRatio;
|
||||
private BigDecimal yearTotalAmountWan;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ package cn.iocoder.lyzsys.module.tjt.service.specialtyrolesplit;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRoleSplitBatchSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRoleSplitRespVO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 页面5角色比例 Service 接口
|
||||
@@ -14,6 +16,12 @@ public interface SpecialtyRoleSplitService {
|
||||
|
||||
List<SpecialtyRoleSplitRespVO> getSpecialtyRoleSplitListByPlanningId(Long planningId);
|
||||
|
||||
Map<Long, List<SpecialtyRoleSplitRespVO>> getSpecialtyRoleSplitListMapByPlanningIds(Collection<Long> planningIds);
|
||||
|
||||
Map<Long, List<SpecialtyRoleSplitRespVO>> getExistingSpecialtyRoleSplitListMapByPlanningIds(Collection<Long> planningIds);
|
||||
|
||||
Map<Long, List<SpecialtyRoleSplitRespVO>> getReadonlySpecialtyRoleSplitListMapByPlanningIds(Collection<Long> planningIds);
|
||||
|
||||
void saveSpecialtyRoleSplitBatch(SpecialtyRoleSplitBatchSaveReqVO reqVO);
|
||||
|
||||
void deleteByOutputSplitId(Long outputSplitId);
|
||||
|
||||
@@ -1,48 +1,35 @@
|
||||
package cn.iocoder.lyzsys.module.tjt.service.specialtyrolesplit;
|
||||
|
||||
import cn.iocoder.lyzsys.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.lyzsys.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRolePersonRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRolePersonSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRoleSplitBatchSaveReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRoleSplitRespVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.SpecialtyRoleSplitSaveItemReqVO;
|
||||
import cn.iocoder.lyzsys.module.tjt.controller.admin.specialtyrolesplit.vo.*;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.employee.EmployeeDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.outputsplit.ProjectOutputSplitDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.planning.ProjectPlanningDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.project.ProjectDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.projectroleperson.ProjectRolePersonDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.specialtyrolesplit.SpecialtyRoleSplitDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.dataobject.specialtyrolesplitperson.SpecialtyRoleSplitPersonDO;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.planning.ProjectPlanningMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.project.ProjectMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.projectroleperson.ProjectRolePersonMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.specialtyrolesplit.SpecialtyRoleSplitMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.dal.mysql.specialtyrolesplitperson.SpecialtyRoleSplitPersonMapper;
|
||||
import cn.iocoder.lyzsys.module.tjt.enums.OutputSplitBizConstants;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.employee.EmployeeService;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.outputsplit.ProjectOutputSplitDefaults;
|
||||
import cn.iocoder.lyzsys.module.tjt.service.outputsplit.ProjectOutputSplitService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.lyzsys.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_NOT_EXISTS;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.PROJECT_OUTPUT_SPLIT_PLANNING_NOT_EXISTS;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.SPECIALTY_ROLE_SPLIT_DESIGN_PERSON_REQUIRED;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.SPECIALTY_ROLE_SPLIT_PERSON_INVALID;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.SPECIALTY_ROLE_SPLIT_PERSON_RATIO_INVALID;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.SPECIALTY_ROLE_SPLIT_ROLE_INVALID;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.SPECIALTY_ROLE_SPLIT_ROLE_RATIO_INVALID;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.SPECIALTY_ROLE_SPLIT_SPECIALTY_INVALID;
|
||||
import static cn.iocoder.lyzsys.module.tjt.enums.ErrorCodeConstants.*;
|
||||
|
||||
@Service
|
||||
@Validated
|
||||
@@ -58,6 +45,8 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
@Resource
|
||||
private SpecialtyRoleSplitMapper specialtyRoleSplitMapper;
|
||||
@Resource
|
||||
private SpecialtyRoleSplitPersonMapper specialtyRoleSplitPersonMapper;
|
||||
@Resource
|
||||
private ProjectOutputSplitService projectOutputSplitService;
|
||||
@Resource
|
||||
private ProjectPlanningMapper projectPlanningMapper;
|
||||
@@ -71,28 +60,141 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
@Override
|
||||
public List<SpecialtyRoleSplitRespVO> getSpecialtyRoleSplitListByPlanningId(Long planningId) {
|
||||
ProjectPlanningDO planning = validatePlanningExists(planningId);
|
||||
ProjectDO project = validateProjectExists(planning.getProjectId());
|
||||
ProjectOutputSplitDO outputSplit = projectOutputSplitService.getOrCreateProjectOutputSplit(planningId);
|
||||
List<SpecialtyRoleSplitDO> dbList = specialtyRoleSplitMapper.selectListByOutputSplitId(outputSplit.getId());
|
||||
Map<String, SpecialtyRoleSplitDO> dbMap = dbList.stream().collect(Collectors.toMap(
|
||||
item -> item.getSpecialtyCode() + ":" + item.getRoleCode(), item -> item, (a, b) -> b));
|
||||
Map<String, List<ProjectRolePersonDO>> projectRolePersonMap = projectRolePersonMapper
|
||||
.selectListByProjectId(project.getId()).stream()
|
||||
.collect(Collectors.groupingBy(ProjectRolePersonDO::getRoleCode, LinkedHashMap::new, Collectors.toList()));
|
||||
validateProjectExists(planning.getProjectId());
|
||||
return getSpecialtyRoleSplitListMapByPlanningIds(Collections.singletonList(planningId))
|
||||
.getOrDefault(planningId, Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, List<SpecialtyRoleSplitRespVO>> getSpecialtyRoleSplitListMapByPlanningIds(Collection<Long> planningIds) {
|
||||
return getSpecialtyRoleSplitListMapByPlanningIds(planningIds, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, List<SpecialtyRoleSplitRespVO>> getExistingSpecialtyRoleSplitListMapByPlanningIds(Collection<Long> planningIds) {
|
||||
return getSpecialtyRoleSplitListMapByPlanningIds(planningIds, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, List<SpecialtyRoleSplitRespVO>> getReadonlySpecialtyRoleSplitListMapByPlanningIds(Collection<Long> planningIds) {
|
||||
return getSpecialtyRoleSplitListMapByPlanningIds(planningIds, false, true);
|
||||
}
|
||||
|
||||
private Map<Long, List<SpecialtyRoleSplitRespVO>> getSpecialtyRoleSplitListMapByPlanningIds(
|
||||
Collection<Long> planningIds, boolean createMissingOutputSplit, boolean defaultMissingOutputSplit) {
|
||||
if (planningIds == null || planningIds.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<Long> normalizedPlanningIds = planningIds.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (normalizedPlanningIds.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Map<Long, ProjectPlanningDO> planningMap = projectPlanningMapper.selectBatchIds(normalizedPlanningIds).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(ProjectPlanningDO::getId, item -> item, (a, b) -> a, LinkedHashMap::new));
|
||||
if (planningMap.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Set<Long> projectIds = planningMap.values().stream()
|
||||
.map(ProjectPlanningDO::getProjectId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
Map<Long, ProjectDO> projectMap = projectIds.isEmpty()
|
||||
? Collections.emptyMap()
|
||||
: projectMapper.selectBatchIds(projectIds).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(ProjectDO::getId, item -> item, (a, b) -> a, LinkedHashMap::new));
|
||||
|
||||
Map<Long, ProjectOutputSplitDO> outputSplitMap = new LinkedHashMap<>(
|
||||
projectOutputSplitService.getProjectOutputSplitMap(planningMap.keySet()));
|
||||
if (createMissingOutputSplit) {
|
||||
for (ProjectPlanningDO planning : planningMap.values()) {
|
||||
if (!outputSplitMap.containsKey(planning.getId())) {
|
||||
outputSplitMap.put(planning.getId(),
|
||||
projectOutputSplitService.getOrCreateProjectOutputSplit(planning.getId()));
|
||||
}
|
||||
}
|
||||
} else if (defaultMissingOutputSplit) {
|
||||
for (ProjectPlanningDO planning : planningMap.values()) {
|
||||
if (!outputSplitMap.containsKey(planning.getId())) {
|
||||
outputSplitMap.put(planning.getId(), ProjectOutputSplitDefaults.build(planning));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Long> outputSplitIds = outputSplitMap.values().stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(ProjectOutputSplitDO::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
Map<Long, List<SpecialtyRoleSplitDO>> roleSplitMap = specialtyRoleSplitMapper
|
||||
.selectListByOutputSplitIds(outputSplitIds).stream()
|
||||
.collect(Collectors.groupingBy(SpecialtyRoleSplitDO::getOutputSplitId,
|
||||
LinkedHashMap::new, Collectors.toList()));
|
||||
List<Long> roleSplitIds = roleSplitMap.values().stream()
|
||||
.flatMap(Collection::stream)
|
||||
.map(SpecialtyRoleSplitDO::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
Map<Long, List<SpecialtyRoleSplitPersonDO>> personMap = specialtyRoleSplitPersonMapper
|
||||
.selectListByRoleSplitIds(roleSplitIds)
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(SpecialtyRoleSplitPersonDO::getRoleSplitId,
|
||||
LinkedHashMap::new, Collectors.toList()));
|
||||
|
||||
Map<Long, Map<String, List<ProjectRolePersonDO>>> projectRolePersonMap = projectRolePersonMapper
|
||||
.selectListByProjectIds(projectIds).stream()
|
||||
.collect(Collectors.groupingBy(ProjectRolePersonDO::getProjectId, LinkedHashMap::new,
|
||||
Collectors.groupingBy(ProjectRolePersonDO::getRoleCode, LinkedHashMap::new, Collectors.toList())));
|
||||
|
||||
Map<Long, List<SpecialtyRoleSplitRespVO>> result = new LinkedHashMap<>();
|
||||
for (Long planningId : normalizedPlanningIds) {
|
||||
ProjectPlanningDO planning = planningMap.get(planningId);
|
||||
if (planning == null) {
|
||||
continue;
|
||||
}
|
||||
ProjectOutputSplitDO outputSplit = outputSplitMap.get(planningId);
|
||||
if (outputSplit == null) {
|
||||
continue;
|
||||
}
|
||||
ProjectDO project = projectMap.get(planning.getProjectId());
|
||||
List<SpecialtyRoleSplitDO> roleList = roleSplitMap.getOrDefault(outputSplit.getId(), Collections.emptyList());
|
||||
Map<String, List<ProjectRolePersonDO>> projectPersons = projectRolePersonMap
|
||||
.getOrDefault(planning.getProjectId(), Collections.emptyMap());
|
||||
result.put(planningId, buildRoleSplitRespList(planning, project, outputSplit, roleList, projectPersons, personMap));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<SpecialtyRoleSplitRespVO> buildRoleSplitRespList(ProjectPlanningDO planning,
|
||||
ProjectDO project,
|
||||
ProjectOutputSplitDO outputSplit,
|
||||
List<SpecialtyRoleSplitDO> dbList,
|
||||
Map<String, List<ProjectRolePersonDO>> projectRolePersonMap,
|
||||
Map<Long, List<SpecialtyRoleSplitPersonDO>> personMap) {
|
||||
List<SpecialtyRoleSplitDO> safeDbList = dbList == null ? Collections.emptyList() : dbList;
|
||||
Map<String, SpecialtyRoleSplitDO> dbMap = safeDbList.stream().collect(Collectors.toMap(
|
||||
item -> item.getSpecialtyCode() + ":" + item.getRoleCode(), item -> item, (a, b) -> b));
|
||||
List<SpecialtyRoleSplitRespVO> result = new ArrayList<>();
|
||||
BigDecimal assessmentOutputValue = planning.getAssessmentOutputValue();
|
||||
boolean useDefaultProjectLeadRoleRatio = shouldUseDefaultProjectLeadRoleRatio(dbMap, projectRolePersonMap);
|
||||
for (OutputSplitBizConstants.SpecialtyItem specialtyItem : OutputSplitBizConstants.ASSIGNMENT_SPECIALTY_ITEMS) {
|
||||
BigDecimal specialtyAmount = getSpecialtyAmount(outputSplit, assessmentOutputValue, specialtyItem.getCode());
|
||||
Map<String, BigDecimal> defaultRoleRatioMap = buildDefaultRoleRatioMap(
|
||||
specialtyItem.getCode(), projectRolePersonMap);
|
||||
for (OutputSplitBizConstants.RoleItem roleItem : OutputSplitBizConstants.getRoleItems(specialtyItem.getCode())) {
|
||||
SpecialtyRoleSplitDO dbItem = dbMap.get(specialtyItem.getCode() + ":" + roleItem.getCode());
|
||||
BigDecimal roleRatio = getStoredRoleRatio(
|
||||
dbItem, specialtyItem.getCode(), roleItem.getCode(), defaultRoleRatioMap);
|
||||
BigDecimal roleRatio = useDefaultProjectLeadRoleRatio
|
||||
&& OutputSplitBizConstants.SPECIALTY_PROJECT_LEAD.equals(specialtyItem.getCode())
|
||||
? ratio(defaultRoleRatioMap.get(roleItem.getCode()))
|
||||
: getStoredRoleRatio(dbItem, specialtyItem.getCode(), roleItem.getCode(), defaultRoleRatioMap);
|
||||
BigDecimal roleAmount = multiplyAmount(specialtyAmount, roleRatio);
|
||||
List<SpecialtyRolePersonRespVO> persons = buildRespPersons(
|
||||
dbItem, specialtyItem.getCode(), roleItem.getCode(), roleAmount, roleRatio, projectRolePersonMap);
|
||||
dbItem, specialtyItem.getCode(), roleItem.getCode(), roleAmount, projectRolePersonMap, personMap);
|
||||
SpecialtyRoleSplitRespVO respVO = dbItem == null
|
||||
? new SpecialtyRoleSplitRespVO()
|
||||
: BeanUtils.toBean(dbItem, SpecialtyRoleSplitRespVO.class);
|
||||
@@ -102,7 +204,7 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
+ OutputSplitBizConstants.getRoleSortNo(roleItem.getCode()));
|
||||
}
|
||||
respVO.setPlanningId(planning.getId());
|
||||
respVO.setProjectName(project.getProjectName());
|
||||
respVO.setProjectName(project == null ? "" : project.getProjectName());
|
||||
respVO.setPlanningContent(planning.getPlanningContent());
|
||||
respVO.setSpecialtyCode(specialtyItem.getCode());
|
||||
respVO.setSpecialtyName(specialtyItem.getName());
|
||||
@@ -118,7 +220,35 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
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
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveSpecialtyRoleSplitBatch(SpecialtyRoleSplitBatchSaveReqVO reqVO) {
|
||||
ProjectPlanningDO planning = validatePlanningExists(reqVO.getPlanningId());
|
||||
ProjectOutputSplitDO outputSplit = projectOutputSplitService.getOrCreateProjectOutputSplit(reqVO.getPlanningId());
|
||||
@@ -127,8 +257,23 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
item -> item.getSpecialtyCode() + ":" + item.getRoleCode(), item -> item, (a, b) -> b));
|
||||
Map<String, Map<String, SpecialtyRoleSplitSaveItemReqVO>> groupedMap = buildGroupedInput(reqVO.getItems());
|
||||
BigDecimal assessmentOutputValue = planning.getAssessmentOutputValue();
|
||||
boolean temporarySave = Boolean.TRUE.equals(reqVO.getTemporarySave());
|
||||
|
||||
saveSpecialtyRoleSplits(outputSplit, dbMap, groupedMap, assessmentOutputValue, !temporarySave);
|
||||
}
|
||||
|
||||
/**
|
||||
* 专业人员分配共用保存流程:正式保存执行强校验,临时保存仅做基础格式处理后落库。
|
||||
*/
|
||||
private void saveSpecialtyRoleSplits(ProjectOutputSplitDO outputSplit,
|
||||
Map<String, SpecialtyRoleSplitDO> dbMap,
|
||||
Map<String, Map<String, SpecialtyRoleSplitSaveItemReqVO>> groupedMap,
|
||||
BigDecimal assessmentOutputValue,
|
||||
boolean strictValidate) {
|
||||
for (OutputSplitBizConstants.SpecialtyItem specialtyItem : OutputSplitBizConstants.ASSIGNMENT_SPECIALTY_ITEMS) {
|
||||
if (!groupedMap.containsKey(specialtyItem.getCode())) {
|
||||
continue;
|
||||
}
|
||||
Map<String, SpecialtyRoleSplitSaveItemReqVO> roleMap = groupedMap.getOrDefault(
|
||||
specialtyItem.getCode(), new LinkedHashMap<>());
|
||||
BigDecimal roleTotal = ZERO_RATIO;
|
||||
@@ -137,28 +282,35 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
BigDecimal roleRatio = getSaveRoleRatio(roleMap, specialtyItem.getCode(), roleItem.getCode());
|
||||
BigDecimal roleAmount = multiplyAmount(specialtyAmount, roleRatio);
|
||||
List<SpecialtyRolePersonSaveReqVO> persons = normalizePersons(
|
||||
getSavePersons(roleMap, roleItem.getCode()));
|
||||
getSavePersons(roleMap, roleItem.getCode()), strictValidate);
|
||||
if (strictValidate) {
|
||||
validateRolePersons(roleItem.getCode(), roleAmount, persons);
|
||||
roleTotal = roleTotal.add(roleRatio).setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
upsertRole(dbMap, outputSplit.getId(), specialtyItem.getCode(), specialtyItem.getName(),
|
||||
roleItem.getCode(), roleRatio,
|
||||
OutputSplitBizConstants.SPECIALTY_PROJECT_LEAD.equals(specialtyItem.getCode())
|
||||
? null : toPersonJson(persons));
|
||||
}
|
||||
roleTotal = roleTotal.add(roleRatio).setScale(RATIO_SCALE, RoundingMode.HALF_UP);
|
||||
SpecialtyRoleSplitDO role = upsertRole(dbMap, outputSplit.getId(), specialtyItem.getCode(),
|
||||
specialtyItem.getName(), roleItem.getCode(), roleRatio);
|
||||
refreshRolePersons(role, outputSplit, persons);
|
||||
}
|
||||
if (strictValidate) {
|
||||
validateRoleTotal(roleTotal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteByOutputSplitId(Long outputSplitId) {
|
||||
specialtyRoleSplitPersonMapper.deleteByOutputSplitId(outputSplitId);
|
||||
specialtyRoleSplitMapper.delete(SpecialtyRoleSplitDO::getOutputSplitId, outputSplitId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteByOutputSplitIds(List<Long> outputSplitIds) {
|
||||
if (outputSplitIds == null || outputSplitIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
specialtyRoleSplitPersonMapper.deleteByOutputSplitIds(outputSplitIds);
|
||||
specialtyRoleSplitMapper.delete(new cn.iocoder.lyzsys.framework.mybatis.core.query.LambdaQueryWrapperX<SpecialtyRoleSplitDO>()
|
||||
.in(SpecialtyRoleSplitDO::getOutputSplitId, outputSplitIds));
|
||||
}
|
||||
@@ -181,8 +333,9 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
return result;
|
||||
}
|
||||
|
||||
private void upsertRole(Map<String, SpecialtyRoleSplitDO> dbMap, Long outputSplitId, String specialtyCode,
|
||||
String specialtyName, String roleCode, BigDecimal roleRatio, String personsJson) {
|
||||
private SpecialtyRoleSplitDO upsertRole(Map<String, SpecialtyRoleSplitDO> dbMap, Long outputSplitId,
|
||||
String specialtyCode, String specialtyName, String roleCode,
|
||||
BigDecimal roleRatio) {
|
||||
String key = specialtyCode + ":" + roleCode;
|
||||
SpecialtyRoleSplitDO dbItem = dbMap.get(key);
|
||||
Integer sortNo = dbItem != null && dbItem.getSortNo() != null
|
||||
@@ -197,10 +350,10 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
createObj.setRoleCode(roleCode);
|
||||
createObj.setRoleName(OutputSplitBizConstants.getRoleName(roleCode));
|
||||
createObj.setRoleRatio(ratio(roleRatio));
|
||||
createObj.setPersonsJson(personsJson);
|
||||
createObj.setSortNo(sortNo);
|
||||
specialtyRoleSplitMapper.insert(createObj);
|
||||
return;
|
||||
dbMap.put(key, createObj);
|
||||
return createObj;
|
||||
}
|
||||
SpecialtyRoleSplitDO updateObj = new SpecialtyRoleSplitDO();
|
||||
updateObj.setId(dbItem.getId());
|
||||
@@ -210,9 +363,46 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
updateObj.setRoleCode(roleCode);
|
||||
updateObj.setRoleName(OutputSplitBizConstants.getRoleName(roleCode));
|
||||
updateObj.setRoleRatio(ratio(roleRatio));
|
||||
updateObj.setPersonsJson(personsJson);
|
||||
updateObj.setSortNo(sortNo);
|
||||
specialtyRoleSplitMapper.updateById(updateObj);
|
||||
dbMap.put(key, updateObj);
|
||||
return updateObj;
|
||||
}
|
||||
|
||||
private void refreshRolePersons(SpecialtyRoleSplitDO role, ProjectOutputSplitDO outputSplit,
|
||||
List<SpecialtyRolePersonSaveReqVO> persons) {
|
||||
if (role == null || role.getId() == null) {
|
||||
return;
|
||||
}
|
||||
specialtyRoleSplitPersonMapper.deleteByRoleSplitId(role.getId());
|
||||
if (OutputSplitBizConstants.SPECIALTY_PROJECT_LEAD.equals(role.getSpecialtyCode())
|
||||
|| persons == null || persons.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<SpecialtyRoleSplitPersonDO> createList = new ArrayList<>();
|
||||
for (int i = 0; i < persons.size(); i++) {
|
||||
SpecialtyRolePersonSaveReqVO person = persons.get(i);
|
||||
if (person == null || person.getEmployeeId() == null) {
|
||||
continue;
|
||||
}
|
||||
SpecialtyRoleSplitPersonDO createObj = new SpecialtyRoleSplitPersonDO();
|
||||
createObj.setRoleSplitId(role.getId());
|
||||
createObj.setOutputSplitId(outputSplit.getId());
|
||||
createObj.setProjectId(outputSplit.getProjectId());
|
||||
createObj.setPlanningId(outputSplit.getPlanningId());
|
||||
createObj.setSpecialtyCode(role.getSpecialtyCode());
|
||||
createObj.setSpecialtyName(role.getSpecialtyName());
|
||||
createObj.setRoleCode(role.getRoleCode());
|
||||
createObj.setRoleName(role.getRoleName());
|
||||
createObj.setEmployeeId(person.getEmployeeId());
|
||||
createObj.setEmployeeName(person.getEmployeeName());
|
||||
createObj.setPersonRatio(ratio(person.getPersonRatio()));
|
||||
createObj.setSortNo(i + 1);
|
||||
createList.add(createObj);
|
||||
}
|
||||
if (!createList.isEmpty()) {
|
||||
specialtyRoleSplitPersonMapper.insertBatch(createList);
|
||||
}
|
||||
}
|
||||
|
||||
private List<SpecialtyRolePersonSaveReqVO> getSavePersons(Map<String, SpecialtyRoleSplitSaveItemReqVO> roleMap,
|
||||
@@ -234,7 +424,8 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
return roleRatio;
|
||||
}
|
||||
|
||||
private List<SpecialtyRolePersonSaveReqVO> normalizePersons(List<SpecialtyRolePersonSaveReqVO> persons) {
|
||||
private List<SpecialtyRolePersonSaveReqVO> normalizePersons(List<SpecialtyRolePersonSaveReqVO> persons,
|
||||
boolean strictValidate) {
|
||||
List<SpecialtyRolePersonSaveReqVO> result = new ArrayList<>();
|
||||
if (persons == null || persons.isEmpty()) {
|
||||
return result;
|
||||
@@ -250,14 +441,18 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
if (!hasEmployee && !hasRatio) {
|
||||
continue;
|
||||
}
|
||||
if (!hasEmployee || !hasRatio) {
|
||||
if (!strictValidate && !hasEmployee) {
|
||||
// 临时保存允许半成品输入,没有选员工的行不落库。
|
||||
continue;
|
||||
}
|
||||
if (strictValidate && (!hasEmployee || !hasRatio)) {
|
||||
throw exception(SPECIALTY_ROLE_SPLIT_PERSON_INVALID);
|
||||
}
|
||||
EmployeeDO employee = employeeService.validateEmployeeExists(employeeId);
|
||||
SpecialtyRolePersonSaveReqVO normalized = new SpecialtyRolePersonSaveReqVO();
|
||||
normalized.setEmployeeId(employeeId);
|
||||
normalized.setEmployeeName(employee.getEmployeeName());
|
||||
BigDecimal normalizedRatio = ratio(personRatio);
|
||||
BigDecimal normalizedRatio = ratio(strictValidate ? personRatio : (personRatio == null ? ZERO_RATIO : personRatio));
|
||||
if (normalizedRatio.compareTo(ZERO_RATIO) < 0 || normalizedRatio.compareTo(ONE_RATIO) > 0) {
|
||||
throw exception(SPECIALTY_ROLE_SPLIT_PERSON_RATIO_INVALID);
|
||||
}
|
||||
@@ -298,13 +493,13 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
|
||||
private List<SpecialtyRolePersonRespVO> buildRespPersons(SpecialtyRoleSplitDO dbItem, String specialtyCode,
|
||||
String roleCode, BigDecimal roleAmount,
|
||||
BigDecimal roleRatio,
|
||||
Map<String, List<ProjectRolePersonDO>> projectRolePersonMap) {
|
||||
Map<String, List<ProjectRolePersonDO>> projectRolePersonMap,
|
||||
Map<Long, List<SpecialtyRoleSplitPersonDO>> personMap) {
|
||||
List<SpecialtyRolePersonSaveReqVO> sourcePersons;
|
||||
if (OutputSplitBizConstants.SPECIALTY_PROJECT_LEAD.equals(specialtyCode)) {
|
||||
sourcePersons = buildDefaultProjectLeadPersons(projectRolePersonMap.get(roleCode));
|
||||
} else {
|
||||
sourcePersons = parseStoredPersons(dbItem);
|
||||
sourcePersons = buildStoredPersons(dbItem, personMap);
|
||||
}
|
||||
List<SpecialtyRolePersonRespVO> result = new ArrayList<>();
|
||||
for (SpecialtyRolePersonSaveReqVO person : sourcePersons) {
|
||||
@@ -318,12 +513,13 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<SpecialtyRolePersonSaveReqVO> parseStoredPersons(SpecialtyRoleSplitDO dbItem) {
|
||||
if (dbItem == null || dbItem.getPersonsJson() == null || dbItem.getPersonsJson().trim().isEmpty()) {
|
||||
private List<SpecialtyRolePersonSaveReqVO> buildStoredPersons(SpecialtyRoleSplitDO dbItem,
|
||||
Map<Long, List<SpecialtyRoleSplitPersonDO>> personMap) {
|
||||
if (dbItem == null || dbItem.getId() == null || personMap == null || personMap.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<SpecialtyRolePersonSaveReqVO> persons = JsonUtils.parseArray(dbItem.getPersonsJson(), SpecialtyRolePersonSaveReqVO.class);
|
||||
if (persons == null) {
|
||||
List<SpecialtyRoleSplitPersonDO> persons = personMap.get(dbItem.getId());
|
||||
if (persons == null || persons.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return persons.stream()
|
||||
@@ -401,10 +597,6 @@ public class SpecialtyRoleSplitServiceImpl implements SpecialtyRoleSplitService
|
||||
return projectOutputSplitService.getSpecialtyAmount(outputSplit, assessmentOutputValue, specialtyCode);
|
||||
}
|
||||
|
||||
private String toPersonJson(List<SpecialtyRolePersonSaveReqVO> persons) {
|
||||
return persons == null || persons.isEmpty() ? null : JsonUtils.toJsonString(persons);
|
||||
}
|
||||
|
||||
private BigDecimal sumPersonRatios(List<SpecialtyRolePersonSaveReqVO> persons) {
|
||||
BigDecimal sum = ZERO_RATIO;
|
||||
if (persons == null || persons.isEmpty()) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user