Browse Source

预估工时设置

seyason 1 year ago
parent
commit
b4e543a00c

+ 44 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java

@@ -98,6 +98,8 @@ public class ReportController {
     private UserFvTimeService userFvTimeService;
     @Resource
     private LeaveSheetService leaveSheetService;
+    @Resource
+    private EstimateTimeSettingMapper estimateTimeSettingMapper;
 
     //获取任务相关的日报列表
     @RequestMapping("/getTaskReportList")
@@ -1131,12 +1133,23 @@ public class ReportController {
         }
 
         //如果开启了项目人天
+        String warningPercentProjects = "";
+        String warningLackProjects = "";
+        EstimateTimeSetting estimateTimeSetting = null;
         if(comTimeType.getProjectManDay()==1){
             Collection<Integer> projectIds = reportList.stream().map(Report::getProjectId).distinct().collect(Collectors.toList());
             List<Report> needCheckReportList = reportMapper.selectList(new QueryWrapper<Report>().in("project_id", projectIds).and(wrapper->wrapper.eq("state",0).or().eq("state",1).or().eq("state",3)));
             List<Project> targetProjectList = projectList.stream().filter(pl -> projectIds.contains(pl.getId())).collect(Collectors.toList());
+            estimateTimeSetting = estimateTimeSettingMapper.selectById(company.getId());
+            //如果没有设置过项目人天,就初始化一下
+            if (estimateTimeSetting == null) {
+                estimateTimeSetting = new EstimateTimeSetting();
+                estimateTimeSetting.setCompanyId(company.getId());
+                estimateTimeSettingMapper.insert(estimateTimeSetting);
+                estimateTimeSetting = estimateTimeSettingMapper.selectById(company.getId());
+            }
             for (Report report : reportList) {
-                    HttpRespMsg httpRespMsg = new HttpRespMsg();
+                HttpRespMsg httpRespMsg = new HttpRespMsg();
                 Optional<Project> first = targetProjectList.stream().filter(tl -> tl.getId().equals(report.getProjectId())).findFirst();
                 if(first.isPresent()){
                     double nowReport = reportList.stream().filter(rl -> rl.getCreateDate().equals(report.getCreateDate()) && rl.getCreatorId().equals(report.getCreatorId())).mapToDouble(Report::getWorkingTime).sum();
@@ -1151,12 +1164,24 @@ public class ReportController {
                         BigDecimal hasReport = new BigDecimal(sum).add(new BigDecimal(nowReport));
                         BigDecimal multiply = new BigDecimal(first.get().getManDay()).multiply(new BigDecimal(comTimeType.getAllday()));
                         if(hasReport.doubleValue()>multiply.doubleValue()){
-                            httpRespMsg.setError("超过当前项目["+first.get().getProjectName()+"]预算工时,无法继续提交工时");
-                            return httpRespMsg;
+                            if (estimateTimeSetting.getProjectFronzeOnLack() == 1) {
+                                httpRespMsg.setError("超过当前项目["+first.get().getProjectName()+"]预算工时,无法继续提交工时");
+                                return httpRespMsg;
+                            } else {
+                                //仅提醒
+                                warningLackProjects += first.get().getProjectName() + ",";
+                            }
+                        } else {
+                            //检查是否超过预设的提醒百分比;设置的数值是剩余的百分比
+                            if (hasReport.divide(multiply, 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).compareTo(new BigDecimal(100-estimateTimeSetting.getProjectWarningPercent()))>0) {
+                                warningPercentProjects += first.get().getProjectName() + ",";
+                            }
                         }
                     }
                 }
             }
+
+
         }
 
         //如果锁定工作时长上限的话,需要校验每日的合计工作时长
@@ -1510,6 +1535,22 @@ public class ReportController {
                 approveReport(rIds, 0, request, null);
             }
         }
+
+        String estimateWarningMsg = "";
+        if (estimateTimeSetting != null) {
+            if (!StringUtils.isEmpty(warningLackProjects)) {
+                warningLackProjects = warningLackProjects.substring(0, warningLackProjects.length() -1);
+                estimateWarningMsg += "提交成功,项目["+warningLackProjects+"]预估工时不足,请联系项目经理。";
+            }
+            if (!StringUtils.isEmpty(warningPercentProjects)) {
+                warningPercentProjects = warningPercentProjects.substring(0, warningPercentProjects.length() -1);
+                estimateWarningMsg += "提交成功,项目["+warningPercentProjects+"]预估工时剩余小于"+estimateTimeSetting.getProjectWarningPercent()+"%,请联系项目经理。";
+            }
+            if (!StringUtils.isEmpty(estimateWarningMsg)) {
+                httpRespMsg.setMsg(estimateWarningMsg);
+            }
+        }
+
         return httpRespMsg;
     }
 

+ 9 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Project.java

@@ -25,7 +25,7 @@ import org.springframework.format.annotation.DateTimeFormat;
  * </p>
  *
  * @author Seyason
- * @since 2023-04-20
+ * @since 2023-11-19
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -340,7 +340,7 @@ public class Project extends Model<Project> {
 
     @TableField(exist = false)
     List<TaskGroup> taskGroupList;
-    
+
     @TableField(exist = false)
     private String levelString;
 
@@ -452,6 +452,13 @@ public class Project extends Model<Project> {
     @TableField(exist = false)
     private List<SubProject> subProjectList;
 
+    /**
+     * 是否是从外部系统同步的项目
+     */
+    @TableField("from_outside")
+    private Integer fromOutside;
+
+
     @Override
     protected Serializable pkVal() {
         return this.id;

File diff suppressed because it is too large
+ 74 - 73
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml


+ 107 - 8
fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue

@@ -72,14 +72,9 @@
                             <el-dropdown-item v-if="user.company.packageProject == 1 && permissions.projectCostOfItems">
                                 <el-link type="primary" :underline="false" @click="showBaseCostItemDialog">{{ $t('baselinecostitem') }}</el-link>
                             </el-dropdown-item>
-                            <!-- <el-dropdown-item v-if="user.company.packageProject == 1 && user.companyId == '936'"> -->
-                            <!-- <el-dropdown-item >
-                                <el-link type="primary" :underline="false" @click="keyNodesIsShow = true">关键节点项</el-link>
-                            </el-dropdown-item> -->
                             <el-dropdown-item v-if="permissions.projectClassification">
                                 <el-link type="primary" :underline="false" @click="showClfDialog = true">{{ $t('classificationmanagement') }}</el-link>
                             </el-dropdown-item>
-                            <!-- <el-dropdown-item v-if="user.timeType.mainProjectState == 1 && !permissions.projectClassification"> -->
                             <el-dropdown-item v-if="user.timeType.mainProjectState == 1">
                                 <el-link type="primary" :underline="false" @click="mainProjectDialog = true">{{ $t('masterprojectmanagement') }}</el-link>
                             </el-dropdown-item>
@@ -95,6 +90,9 @@
                             <el-dropdown-item v-if="user.companyId==3385 && permissions.projectClassification">
                                 <el-link type="primary" :underline="false" @click="functionalDivisionDig=true,getFunctionalList()">{{'职能分工设置'}}</el-link>
                             </el-dropdown-item>
+                            <el-dropdown-item v-if="user.timeType.projectManDay == 1 && permissions.projectClassification">
+                                <el-link type="primary" :underline="false" @click="projectManDaySettingDialog = true;getManDaySetting()">{{ '预估工时配置' }}</el-link>
+                            </el-dropdown-item>
                         </el-dropdown-menu>
                         </el-dropdown>
                 </el-form-item>
@@ -622,7 +620,8 @@
                     </el-form-item>
 
                     <!-- 增加项目人天字段 绎维固定字段 -->
-                    <el-form-item label="项目人天" v-if="user.timeType.projectManDay == 1">
+                    <el-form-item  v-if="user.timeType.projectManDay == 1">
+                        <template slot="label"><span v-if="manDaySetting.projectManDayFillMode == 2 || (manDaySetting.projectManDayFillMode == 1 && addForm.fromOutside == 0)" style="padding:5px;color:red;">*</span>项目人天</template>
                         <el-input v-model.number="addForm.manDay" :placeholder="$t('peaseenterthe')" @input="jisuanEstimatedWorkTime(addForm.manDay)"  style="width: 100px"></el-input><span style="margin-left:10px;position:absolute;">人天(预估工时:{{this.estimatedWorkTime}}h)</span>
                         <el-tooltip effect="dark" :content="$t('根据系统基础设置每日正常工作时长计算,1人天为一个每日正常工作时长')" placement="top-start" style="margin-left:180px">
                                         <i class="el-icon-question" style="color:#606266"></i>
@@ -1070,6 +1069,43 @@
             </div>
         </el-dialog>
 
+        
+        <el-dialog title="项目预估工时配置" show-header="false" v-if="projectManDaySettingDialog" :visible.sync="projectManDaySettingDialog" :close-on-click-modal="false" customClass="customWidth" width="600px">
+            <el-form label-width="200px" :form="manDaySetting">
+                <el-form-item :label="'预估工时是否必填'"  >
+                    <el-select v-model="manDaySetting.projectManDayFillMode" :placeholder="$t('defaultText.pleaseChoose')"  >
+                        <el-option label="非必填" :value="0"></el-option>
+                        <el-option label="工时系统创建的项目必填" :value="1"></el-option>
+                        <el-option label="工时系统和外部同步的项目都必填" :value="2"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item :label="'项目工时提醒百分比'"  >
+                    <el-input v-model="manDaySetting.projectWarningPercent" type="number" style="width:200px;">
+                    </el-input>%
+                </el-form-item>
+                <el-form-item :label="'项目工时不足时'"  >
+                    <el-select v-model="manDaySetting.projectFronzeOnLack" :placeholder="$t('defaultText.pleaseChoose')"  >
+                        <el-option label="禁止填报" :value="1"></el-option>
+                        <el-option label="可以填报,仅提醒" :value="0"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item :label="'分组工时提醒百分比'"  v-if="user.company.packageProject == 1">
+                    <el-input v-model="manDaySetting.groupWarningPercent" type="number" style="width:200px;">
+                    </el-input>%
+                </el-form-item>
+                <el-form-item :label="'分组工时不足时'"  v-if="user.company.packageProject == 1" >
+                    <el-select v-model="manDaySetting.groupFronzeOnLack" :placeholder="$t('defaultText.pleaseChoose')"  >
+                        <el-option label="禁止填报" :value="1"></el-option>
+                        <el-option label="可以填报,仅提醒" :value="0"></el-option>
+                    </el-select>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="default" @click="projectManDaySettingDialog = false" >{{ $t('Shutdown') }}</el-button>
+                <el-button type="primary" @click="saveProjectManDaySetting()" >保存</el-button>
+            </div>
+        </el-dialog>
+
         <!-- 导出任务分组 -->
         <el-dialog :title="'导出任务分组'" show-header="false" v-if="groupTaskDialog" :visible.sync="groupTaskDialog" :close-on-click-modal="false" customClass="customWidth" width="600px">
             <el-form>
@@ -1629,6 +1665,8 @@ a {
         },
         data() {
             return {
+                manDaySetting:{},
+                projectManDaySettingDialog: false,
                 projectListPageComponentKey: 1,
                 isDeleting: false,
                 forSubProjectlist:[],
@@ -1924,6 +1962,47 @@ a {
             })
         },
         methods: {
+            saveProjectManDaySetting() {
+                this.http.post('/estimate-time-setting/save', this.manDaySetting,
+                res => {
+                    if (res.code == "ok") {
+                        this.projectManDaySettingDialog = false;
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
+            //获取项目预估工时配置数据
+            getManDaySetting() {
+                this.http.post('/estimate-time-setting/get', {
+                    companyId: this.user.companyId
+                },
+                res => {
+                    if (res.code == "ok") {
+                        this.manDaySetting = res.data;
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
             submitCopySubProject() {
                 //获取选中的项目
                 if (this.checkedPForSubArr.length == 0) {
@@ -4397,7 +4476,8 @@ a {
                         projectMainId: '',
                         outputValue: '',
                         bu: [],
-                        manDay:0
+                        manDay:0,
+                        fromOutside: 0,
                         // deptId: []
                     }
                     this.estimatedWorkTime=''
@@ -4534,7 +4614,8 @@ a {
                         bu: buascaderList,
                         manDay:item.manDay==null?0:item.manDay,
                         manDayStartDate:item.manDayStartDate,
-                        manDayDisable:item.manDay
+                        manDayDisable:item.manDay,
+                        fromOutside:item.fromOutside
                     }
                     for(var i in this.dataList) {
                         var str = 'plate' + (+i + 1)
@@ -4634,6 +4715,9 @@ a {
                     // this.findUserInTree()
                 }
                 this.addFormVisible = true;
+                if (this.user.timeType.projectManDay == 1) {
+                    this.getManDaySetting();
+                }
                 if (this.user.company.packageEngineering == 1) {
                     if (this.professionList.length == 0) {
                         this.getProfessionList();
@@ -4874,6 +4958,7 @@ a {
                         if (this.user.timeType.outputValueStatus == 1){
                             formData.append("outputValue",this.addForm.outputValue ? this.addForm.outputValue : 0)
                         }
+                        
                         var listId = []
                         var listName = []
                         for(var i in this.auseList) {
@@ -4944,6 +5029,17 @@ a {
                         }
                         formData.append("buId", this.addForm.bu ? this.addForm.bu : '');
                         if(this.user.timeType.projectManDay){
+                            //检验预估人天的必填属性
+                            if (this.manDaySetting.projectManDayFillMode == 2 || (this.manDaySetting.projectManDayFillMode == 1 && this.addForm.fromOutside == 0)) {
+                                if (!this.addForm.manDay) {
+                                    this.$message({
+                                        message: '预估工时不能为0',
+                                        type: "error"
+                                    });
+                                    this.addLoading = false;
+                                    return;
+                                }
+                            }
                             formData.append("manDay", this.addForm.manDay ? this.addForm.manDay : '');
                             formData.append("manDayStartDate", this.addForm.manDayStartDate ? this.addForm.manDayStartDate : '');
                         }
@@ -5547,6 +5643,9 @@ a {
             if(this.user.companyId == '936') {
                 this.getkeyNodes()
             }
+            if (this.user.timeType.projectManDay == 1) {
+                this.getManDaySetting();
+            }
         }
     };
 </script>