Browse Source

1. 完善公共工时分配逻辑
2. 修复部门修改时的报错

QuYueTing 1 month ago
parent
commit
03f774f644

+ 9 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/FinanceMonthlyWorktimeController.java

@@ -31,8 +31,15 @@ public class FinanceMonthlyWorktimeController {
     }
 
     @RequestMapping("/getByMonth")
-    public HttpRespMsg getByMonth(Integer companyId, String ymonth, HttpServletRequest request) {
-        return financeMonthlyWorktimeService.getByMonth(companyId, ymonth,request);
+    public HttpRespMsg getByMonth(Integer companyId, String ymonth, @RequestParam(required = false, defaultValue = "0" ) Integer reGenerate,HttpServletRequest request) {
+        try {
+            return financeMonthlyWorktimeService.getByMonth(companyId, ymonth,reGenerate, request);
+        } catch (Exception e) {
+            e.printStackTrace();
+            HttpRespMsg msg = new HttpRespMsg();
+            msg.setError(e.getMessage());
+            return msg;
+        }
     }
 
     @RequestMapping("/setTimesheetDate")

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/FinanceMonthlyWorktimeService.java

@@ -18,7 +18,7 @@ public interface FinanceMonthlyWorktimeService extends IService<FinanceMonthlyWo
 
     HttpRespMsg send(String fmwId, String timesheetDate, HttpServletRequest request);
 
-    HttpRespMsg getByMonth(Integer companyId, String ymonth, HttpServletRequest request);
+    HttpRespMsg getByMonth(Integer companyId, String ymonth, Integer reGenerate, HttpServletRequest request) throws Exception;
 
     HttpRespMsg setTimesheetDate(Integer id, String timesheetDate, HttpServletRequest request);
 }

+ 4 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java

@@ -259,6 +259,10 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
                 //修改任务文件审核人
                 List<Integer> taskFileIds = taskFilesMapper.getTaskFilesByCreatorDeptId(departmentId);
                 if(CollectionUtils.isNotEmpty(taskFileIds)){
+                    System.out.println("managerId="+managerId);
+                    taskFileIds.forEach(id->{
+                        System.out.println(id);
+                    });
                     taskFilesMapper.update(null,new LambdaUpdateWrapper<TaskFiles>()
                             .set(TaskFiles::getChargeOneId,managerId)
                             .in(TaskFiles::getId,taskFileIds)

+ 147 - 12
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceMonthlyWorktimeServiceImpl.java

@@ -25,6 +25,8 @@ import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 
 /**
  * <p>
@@ -55,6 +57,8 @@ public class FinanceMonthlyWorktimeServiceImpl extends ServiceImpl<FinanceMonthl
     private ProjectMapper projectMapper;
     @Autowired
     private FmwDetailService fmwDetailService;
+    @Resource
+    private ErpOrderInfoMapper erpOrderInfoMapper;
 
     @Override
     public HttpRespMsg send(String fmwId, String timesheetDate, HttpServletRequest request) {
@@ -118,22 +122,37 @@ public class FinanceMonthlyWorktimeServiceImpl extends ServiceImpl<FinanceMonthl
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public HttpRespMsg getByMonth(Integer companyId, String ymonth, HttpServletRequest request) {
+    public HttpRespMsg getByMonth(Integer companyId, String ymonth, Integer reGenerate, HttpServletRequest request) throws Exception {
         //获取该月份的数据,如果没有自动生成
         String token = request.getHeader("token");
         User user = userMapper.selectById(token);
         FinanceMonthlyWorktime financeMonthlyWorktime = financeMonthlyWorktimeMapper.selectOne(new LambdaQueryWrapper<FinanceMonthlyWorktime>().eq(FinanceMonthlyWorktime::getCompanyId, companyId).eq(FinanceMonthlyWorktime::getYmonth, ymonth));
-        if(null != financeMonthlyWorktime){
-            //生成数据
-            financeMonthlyWorktime = new FinanceMonthlyWorktime();
-            financeMonthlyWorktime.setCompanyId(companyId);
-            financeMonthlyWorktime.setYmonth(ymonth);
-            financeMonthlyWorktime.setStatus(0);
-            //数据日期就是当前日期
-            financeMonthlyWorktime.setTimesheetDate(LocalDate.now());
-            financeMonthlyWorktime.setUserId(user.getId());
-            financeMonthlyWorktimeMapper.insert(financeMonthlyWorktime);
-
+        Integer detailCount = 0;
+        if (financeMonthlyWorktime != null) {
+            if (reGenerate== 1) {
+                //删除明细数据
+                fmwDetailMapper.delete(new LambdaQueryWrapper<FmwDetail>().eq(FmwDetail::getFmwId, financeMonthlyWorktime.getId()));
+            } else {
+                detailCount = fmwDetailMapper.selectCount(new QueryWrapper<FmwDetail>().eq("fmw_id", financeMonthlyWorktime.getId()));
+            }
+        }
+        if(null == financeMonthlyWorktime || detailCount == 0){
+            if (null == financeMonthlyWorktime) {
+                //生成数据
+                financeMonthlyWorktime = new FinanceMonthlyWorktime();
+                financeMonthlyWorktime.setCompanyId(companyId);
+                financeMonthlyWorktime.setYmonth(ymonth);
+                financeMonthlyWorktime.setStatus(0);
+                //数据日期就是当前日期
+                financeMonthlyWorktime.setTimesheetDate(LocalDate.now());
+                financeMonthlyWorktime.setUserId(user.getId());
+                financeMonthlyWorktimeMapper.insert(financeMonthlyWorktime);
+            } else {
+                //更新数据日期为当前日期
+                financeMonthlyWorktime.setTimesheetDate(LocalDate.now());
+                financeMonthlyWorktime.setUserId(user.getId());
+                financeMonthlyWorktimeMapper.updateById(financeMonthlyWorktime);
+            }
             //生成明细数据
             //获取当月的第一天和最后一天
             LocalDate firstDayOfMonth = LocalDate.parse(ymonth + "-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
@@ -141,6 +160,8 @@ public class FinanceMonthlyWorktimeServiceImpl extends ServiceImpl<FinanceMonthl
             //查询日报数据
             List<Department> departmentList = departmentMapper.selectList(new LambdaQueryWrapper<Department>().eq(Department::getCompanyId, user.getCompanyId()));
             List<Project> projectList = projectMapper.selectList(new LambdaQueryWrapper<Project>().eq(Project::getCompanyId, user.getCompanyId()));
+            List<Project> publicProjectList = projectList.stream().filter(p -> p.getIsPublic() == 1).collect(Collectors.toList());
+            List<ErpOrderInfo> erpOrderInfoList = erpOrderInfoMapper.selectList(new LambdaQueryWrapper<ErpOrderInfo>());
             List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().select(User::getId, User::getName, User::getDepartmentId).eq(User::getCompanyId, user.getCompanyId()));
             List<String> groupNameList = new ArrayList<>();
             groupNameList.add("组装/维修工时");
@@ -159,6 +180,11 @@ public class FinanceMonthlyWorktimeServiceImpl extends ServiceImpl<FinanceMonthl
                     setFmwTime(fmwDetail, report);
                 } else {
                     FmwDetail fmwDetail = new FmwDetail();
+                    fmwDetail.setMaintanceTime(0.0);
+                    fmwDetail.setDebugTime(0.0);
+                    fmwDetail.setWaitingTime(0.0);
+                    fmwDetail.setAssistTime(0.0);
+
                     fmwDetail.setFmwId(financeMonthlyWorktime.getId());
                     fmwDetail.setProjectId(report.getProjectId());
                     projectList.stream().filter(p->p.getId().equals(report.getProjectId())).findFirst().ifPresent(project -> {
@@ -170,6 +196,10 @@ public class FinanceMonthlyWorktimeServiceImpl extends ServiceImpl<FinanceMonthl
                     departmentList.stream().filter(d->d.getDepartmentId().equals(report.getDeptId())).findFirst().ifPresent(d->{
                         fmwDetail.setDeptCode(d.getDeptCode());
                         fmwDetail.setDeptName(d.getDepartmentName());
+                        //为提高可读性,从erpOrderInfo表中获取部门名称
+                        erpOrderInfoList.stream().filter(e->e.getDeptId().equals(d.getDeptCode())).findFirst().ifPresent(e->{
+                            fmwDetail.setDeptName(e.getDeptName());
+                        });
                     });
                     setFmwTime(fmwDetail, report);
                     //从assistList中获取协作工时
@@ -181,6 +211,111 @@ public class FinanceMonthlyWorktimeServiceImpl extends ServiceImpl<FinanceMonthl
                 }
             }
             System.out.println("插入数据大小=="+insertDataList.size());
+
+            // 处理公共项目工时分摊
+            List<Integer> publicProjectIds = publicProjectList.stream()
+                    .map(Project::getId)
+                    .collect(Collectors.toList());
+
+            if (!publicProjectIds.isEmpty()) {
+                // 查询公共项目工时
+                //TODO: 需确认,员工填报公共项目工时的时候,会选择到工单吗?
+                List<Report> publicReportList = reportMapper.selectList(
+                        new LambdaQueryWrapper<Report>().select(Report::getCreatorId, Report::getDeptId, Report::getWorkingTime).eq(Report::getState, 1)
+                                .in(Report::getProjectId, publicProjectIds).between(Report::getCreateDate, firstDayOfMonth, lastDayOfMonth));
+                //按照人员所在的部门进行分组,汇总,如果公共项目没有工单,此步骤可以省略
+                publicReportList.forEach(report -> {
+                    User reportOwner = userList.stream().filter(u -> u.getId().equals(report.getCreatorId())).findFirst().orElse(null);
+                    if (reportOwner != null) {
+                        report.setDeptId(reportOwner.getDepartmentId());
+                    }
+                });
+                //分组,合计部门公共工时
+                Map<Integer, Double> map = publicReportList.stream().collect(Collectors.groupingBy(Report::getDeptId, Collectors.summingDouble(Report::getWorkingTime)));
+                //将map按照List形式重新组合
+                publicReportList = map.entrySet().stream()
+                        .map(e -> {
+                            Report report = new Report();
+                            report.setDeptId(e.getKey());
+                            report.setWorkingTime(e.getValue());
+                            return report;
+                        })
+                        .collect(Collectors.toList());
+                if (!publicReportList.isEmpty()) {
+                    //处理每个部门的公共项目工时分摊
+                    for (Report publicReportDeptItem : publicReportList) {
+                        Integer deptId = publicReportDeptItem.getDeptId();
+                        List<FmwDetail> deptAllReportList = insertDataList.stream().filter(r -> r.getDeptId().equals(deptId)).collect(Collectors.toList());
+                        double totalDeptTime = deptAllReportList.stream().reduce(0.0, (a, b) -> a + b.getMaintanceTime() + b.getDebugTime() + b.getWaitingTime(), Double::sum);
+                        System.out.println("处理公共工时分摊,总工时=="+totalDeptTime);
+                        if (totalDeptTime > 0) {
+                            //计算总工时: 用维修组装工时,调试工时和等料工时相加
+                            insertDataList.forEach(fmwDetail -> {
+                                //计算每一个项目的部门内部工时占比,按比例分摊公共工时
+                                if (fmwDetail.getDeptId().equals(deptId)) {
+                                    double curProjectTime = fmwDetail.getMaintanceTime() + fmwDetail.getDebugTime() + fmwDetail.getWaitingTime();
+                                    double assignTime = curProjectTime / totalDeptTime * publicReportDeptItem.getWorkingTime();
+                                    //理论上不会出现fmwDetail.getPublicTime()有值的情况,但是为了保险起见做个叠加计算吧
+                                    fmwDetail.setPublicTime(fmwDetail.getPublicTime() == null ? assignTime : fmwDetail.getPublicTime() + assignTime);
+                                }
+                            });
+                        } else {
+                            //该部门没有部门内部工时,按照填报部门找协作工时
+                            // 查找该部门的员工都协作了哪些部门
+                            List<User> deptUserList = userList.stream().filter(u -> u.getDepartmentId().equals(deptId)).collect(Collectors.toList());
+                            List<String> deptUserIds = deptUserList.stream().map(User::getId).collect(Collectors.toList());
+                            List<Report> assistDeptListByUser = reportMapper.selectList(new QueryWrapper<Report>().select("dept_id, sum(working_time) working_time").eq("is_assist", 1)
+                                    .in("creator_id", deptUserIds).between("create_date", firstDayOfMonth, lastDayOfMonth).groupBy("dept_id"));
+                            //按协作的工时占比来分配
+                            if (!assistDeptListByUser.isEmpty()) {
+                                double totalAssistTime = assistDeptListByUser.stream().mapToDouble(Report::getWorkingTime).sum();
+                                if (totalAssistTime > 0) {
+                                    for (Report assistDeptItem : assistDeptListByUser) {
+                                        //处理部门公共工时的分摊,先按协作的其他部门的占比,分到其他部门
+                                        double curAssistTime = assistDeptItem.getWorkingTime();
+                                        double assignToDeptTime = curAssistTime / totalAssistTime * publicReportDeptItem.getWorkingTime();
+                                        //按目标部门的部门内部工时占比进行二次分配
+                                        Integer assignToDeptId = assistDeptItem.getDeptId();
+                                        List<FmwDetail> targetDeptReportList = insertDataList.stream().filter(r -> r.getDeptId().equals(assignToDeptId)).collect(Collectors.toList());
+                                        double totalTargetDeptTime = targetDeptReportList.stream().reduce(0.0, (a, b) -> a + b.getMaintanceTime() + b.getDebugTime() + b.getWaitingTime(), Double::sum);
+                                        if (totalTargetDeptTime > 0) {
+                                            //计算总工时: 用维修组装工时,调试工时和等料工时相加
+                                            insertDataList.forEach(fmwDetail -> {
+                                                //计算每一个项目的部门内部工时占比,按比例分摊公共工时
+                                                if (fmwDetail.getDeptId().equals(assignToDeptId)) {
+                                                    double curProjectTime = fmwDetail.getMaintanceTime() + fmwDetail.getDebugTime() + fmwDetail.getWaitingTime();
+                                                    double assignTime = curProjectTime / totalTargetDeptTime * assignToDeptTime;
+                                                    //可能之前已经有其他部门的分摊过来了,需要叠加
+                                                    fmwDetail.setPublicTime(fmwDetail.getPublicTime() == null ? assignTime : fmwDetail.getPublicTime() +assignTime);
+                                                }
+                                            });
+                                        } else {
+                                            throw new Exception("存在目标部门没有内部工时,导致公共工时无法分摊:targetDeptId=="+assignToDeptId);
+                                        }
+                                    }
+                                }
+                            }
+
+                            List<FmwDetail> fmwDetails = insertDataList.stream().filter(fmwDetail -> fmwDetail.getDeptId().equals(deptId)).collect(Collectors.toList());
+                            double assistDeptTotalTime = fmwDetails.stream().reduce(0.0, (a, b) -> a + b.getMaintanceTime() + b.getDebugTime() + b.getWaitingTime(), Double::sum);
+                            if (assistDeptTotalTime > 0) {
+                                //计算总工时: 用维修组装工时,调试工时和等料工时相加
+                                insertDataList.forEach(fmwDetail -> {
+                                    //计算每一个项目的部门内部工时占比,按比例分摊公共工时
+                                    if (fmwDetail.getProjectId().equals(publicReportDeptItem.getProjectId())) {
+                                        double curProjectTime = fmwDetail.getMaintanceTime() + fmwDetail.getDebugTime() + fmwDetail.getWaitingTime();
+                                        double assignTime = curProjectTime / assistDeptTotalTime * publicReportDeptItem.getWorkingTime();
+                                        fmwDetail.setPublicTime(assignTime);
+                                    }
+                                });
+                            } else {
+                                throw new Exception("存在部门公共工时无法分配,来源deptId=="+deptId);
+                            }
+                        }
+                    }
+                }
+            }
+
             if (insertDataList.size() > 0) {
                 fmwDetailService.saveBatch(insertDataList);
             }

+ 2 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/FmwDetailMapper.xml

@@ -2,7 +2,7 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="com.management.platform.mapper.FmwDetailMapper">
-<!-- 通用查询映射结果 -->
+    <!-- 閫氱敤鏌ヨ�鏄犲皠缁撴灉 -->
     <resultMap id="BaseResultMap" type="com.management.platform.entity.FmwDetail">
         <id column="id" property="id" />
         <result column="fmw_id" property="fmwId" />
@@ -20,7 +20,7 @@
         <result column="public_time" property="publicTime" />
     </resultMap>
 
-    <!-- 通用查询结果列 -->
+    <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
         id, fmw_id, dept_id, dept_name, dept_code, project_id, project_code, extra_field4, extra_field5, maintance_time, debug_time, waiting_time, assist_time, public_time
     </sql>

+ 4 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml

@@ -1548,23 +1548,23 @@
         </foreach>
     </update>
     <select id="getReportProjectGroupDetailList" resultType="com.management.platform.entity.Report">
-        select id, creator_id, project_id,create_date,group_id,task_group.name as group_name, dept_id,sum(working_time) as working_time, extra_field4, extra_field5
+        select report.project_id,group_id,task_group.name as group_name, dept_id,sum(working_time) as working_time, extra_field4, extra_field5
         from report left join task_group on task_group.id = report.group_id
         where company_id = #{companyId} and create_date between #{startDate} and #{endDate}
         and state = 1 and task_group.name in
-        <foreach collection="groupNameList" open="(" close=")" separator=",">
+        <foreach collection="groupNameList" open="(" close=")" separator="," item="item">
             #{item}
         </foreach>
         group by project_id, extra_field4,extra_field5, group_id
     </select>
 
     <select id="getReportProjectAssistTime" resultType="com.management.platform.entity.Report">
-        select id, creator_id, project_id,create_date,dept_id,sum(working_time) as working_time, extra_field4, extra_field5
+        select report.project_id,sum(working_time) as working_time, extra_field4, extra_field5
         from report left join task_group on task_group.id = report.group_id
         where company_id = #{companyId} and create_date between #{startDate} and #{endDate}
         and state = 1 and is_assist = 1
         and task_group.name in
-        <foreach collection="groupNameList" open="(" close=")" separator=",">
+        <foreach collection="groupNameList" open="(" close=")" separator="," item="item">
             #{item}
         </foreach>
         group by project_id, extra_field4,extra_field5

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TaskFilesMapper.xml

@@ -56,7 +56,7 @@
                   when 2 then charge_two_id = #{userId} and charge_two_status = 0
             end
     </select>
-    <select id="getTaskFilesByCreatorDeptId" resultType="com.management.platform.entity.TaskFiles">
+    <select id="getTaskFilesByCreatorDeptId" resultType="java.lang.Integer">
         select tf.id
         from task_files tf
                  left join user on tf.creator_id = user.id