From af6bafbb985e1972f938aef9bfedbe6549f749ad Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期一, 07 九月 2026 16:46:48 +0800
Subject: [PATCH] feat(mes): 生产报工按工单工序顺序控制,上一道报满后才能报下一道
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java | 261 +++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 217 insertions(+), 44 deletions(-)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
index d5401e9..48db7a0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
@@ -4,6 +4,7 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.*;
@@ -11,6 +12,7 @@
import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackTypeEnum;
import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderBomDO;
@@ -23,11 +25,13 @@
import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum;
import cn.iocoder.yudao.module.mes.enums.pro.MesProTaskStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
+import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService;
import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderBomService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderProcessService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
+import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderParamRecordService;
import cn.iocoder.yudao.module.mes.service.wm.itemconsume.MesWmItemConsumeService;
import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceLineService;
import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceService;
@@ -50,6 +54,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -62,6 +67,7 @@
*/
@Service
@Validated
+@lombok.extern.slf4j.Slf4j
public class MesProFeedbackServiceImpl implements MesProFeedbackService {
@Resource
@@ -70,7 +76,12 @@
@Resource
private MesProWorkOrderService workOrderService;
@Resource
+ @Lazy
+ private MesProWorkOrderParamRecordService paramRecordService;
+ @Resource
private MesProRouteProcessService routeProcessService;
+ @Resource
+ private MesProProcessService processService;
@Resource
private MesProWorkOrderBomService workOrderBomService;
@Resource
@@ -94,8 +105,11 @@
private MesMdmItemService mdmItemService;
@Resource
private MdmItemBatchConfigApi itemBatchConfigApi;
+ @Resource
+ private cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi processInstanceApi;
@Override
+ @Transactional(rollbackFor = Exception.class)
public Long createFeedback(MesProFeedbackSaveReqVO createReqVO) {
// 1. 鏍¢獙
MesProTaskDO task = validateFeedbackData(createReqVO);
@@ -105,10 +119,13 @@
.setStatus(MesProFeedbackStatusEnum.PREPARE.getStatus())
.setItemId(task.getItemId());
feedbackMapper.insert(feedback);
+ // 3. 淇濆瓨鍙傛暟鍊硷紱蹇呭~鍙傛暟鏍¢獙澶辫触鏃舵暣浣撳洖婊氾紝閬垮厤娈嬬暀鑽夌
+ saveParamValues(task.getId(), createReqVO.getParamValues());
return feedback.getId();
}
@Override
+ @Transactional(rollbackFor = Exception.class)
public void updateFeedback(MesProFeedbackSaveReqVO updateReqVO) {
// 1.1 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
validateFeedbackStatusPrepare(updateReqVO.getId());
@@ -119,6 +136,19 @@
MesProFeedbackDO updateObj = BeanUtils.toBean(updateReqVO, MesProFeedbackDO.class)
.setItemId(task.getItemId());
feedbackMapper.updateById(updateObj);
+ // 3. 淇濆瓨鍙傛暟鍊硷紱蹇呭~鍙傛暟鏍¢獙澶辫触鏃舵暣浣撳洖婊�
+ saveParamValues(task.getId(), updateReqVO.getParamValues());
+ }
+
+ private void saveParamValues(Long taskId, List<MesProFeedbackSaveReqVO.ParamValue> paramValues) {
+ // 鍗充娇鍙傛暟涓虹┖涔熻皟鐢ㄦ洿鏂帮紝浠ヤ究瑙﹀彂蹇呭~鍙傛暟鏍¢獙锛堜换鍔$粦瀹氫簡鍙傛暟鏃跺繀椤诲~鍐欙級
+ if (CollUtil.isEmpty(paramValues)) {
+ paramRecordService.updateTaskParamValues(taskId, null, null);
+ return;
+ }
+ paramRecordService.updateTaskParamValues(taskId,
+ paramValues.stream().map(MesProFeedbackSaveReqVO.ParamValue::getDetailId).toList(),
+ paramValues.stream().map(MesProFeedbackSaveReqVO.ParamValue::getValue).toList());
}
@Override
@@ -154,13 +184,83 @@
}
@Override
- public void submitFeedback(Long id) {
+ @Transactional(rollbackFor = Exception.class)
+ public void submitFeedback(MesProFeedbackSubmitReqVO reqVO) {
+ Long id = reqVO.getId();
// 1. 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
- validateFeedbackStatusPrepare(id);
+ MesProFeedbackDO feedback = validateFeedbackStatusPrepare(id);
+ // 1.1 椤哄簭鎶ュ伐鏍¢獙锛氬悓涓�鐢熶骇宸ュ崟鍐咃紝涓婁竴閬撳伐搴忓繀椤诲凡鎶ュ伐瀹屾垚锛屽惁鍒欎笉鍏佽鎻愪氦
+ if (feedback.getTaskId() != null) {
+ MesProTaskDO submitTask = taskService.getTask(feedback.getTaskId());
+ if (submitTask != null) {
+ validatePreviousProcessFinished(submitTask);
+ }
+ }
- // 2. 鏇存柊鐘舵�佷负瀹℃壒涓紙鎶ュ伐浜哄拰鎶ュ伐鏃堕棿鐢辫〃鍗曚繚瀛樻椂纭畾锛屾彁浜や笉瑕嗙洊锛�
- feedbackMapper.updateById(new MesProFeedbackDO().setId(id)
- .setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus()));
+ MesProWorkOrderDO workOrder = workOrderService.getWorkOrder(feedback.getWorkOrderId());
+
+ if (workOrder != null && Boolean.TRUE.equals(workOrder.getFeedbackApprove()) && cn.hutool.core.util.StrUtil.isNotBlank(workOrder.getProcessDefinitionKey())) {
+ // 2. 鏇存柊鐘舵�佷负瀹℃壒涓紝骞跺惎鍔ㄦ祦绋�
+ String processInstanceId = processInstanceApi.createProcessInstance(cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId(),
+ new cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO()
+ .setProcessDefinitionKey(workOrder.getProcessDefinitionKey())
+ .setBusinessKey(String.valueOf(id)));
+
+ feedbackMapper.updateById(new MesProFeedbackDO().setId(id)
+ .setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus())
+ .setProcessDefinitionKey(workOrder.getProcessDefinitionKey())
+ .setProcessInstanceId(processInstanceId));
+ } else {
+ // 2. 鍒ゆ柇杩欎釜鎶ュ伐闇�涓嶉渶瑕佹壒娆″彿
+ MesProFeedbackBatchCheckRespVO mesProFeedbackBatchCheckRespVO = checkBatchRequirements(id);
+ if (mesProFeedbackBatchCheckRespVO.getNeedBatchInput()) {
+ if (StrUtil.isBlank(reqVO.getLotNumber())) {
+ throw exception(MD_ITEM_BATCH_CONFIG_AT_LEAST_ONE_APPROVE_FLAG);
+ }
+ }
+
+ // 3. 鏇存柊鐘舵�佷负瀹℃壒涓紝鐒跺悗鐩存帴閫氳繃瀹℃壒
+ feedbackMapper.updateById(new MesProFeedbackDO().setId(id)
+ .setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus()));
+ MesProFeedbackApproveReqVO approveReqVO = cn.iocoder.yudao.framework.common.util.object.BeanUtils.toBean(reqVO, MesProFeedbackApproveReqVO.class);
+ approveFeedback(approveReqVO);
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void handleBpmProcessResult(Long id, Integer bpmResult,String reason) {
+ // 1. 鏌旀�ф牎楠岋細鑾峰彇鎶ュ伐鍗曞苟鍒ゆ柇鐘舵��
+ MesProFeedbackDO feedback = feedbackMapper.selectById(id);
+ if (feedback == null) {
+ log.warn("[handleBpmProcessResult] 鐢熶骇鎶ュ伐({}) 涓嶅瓨鍦�", id);
+ return;
+ }
+ if (!MesProFeedbackStatusEnum.APPROVING.getStatus().equals(feedback.getStatus())) {
+ log.warn("[handleBpmProcessResult] 鐢熶骇鎶ュ伐({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵�侊細{}", id, feedback.getStatus());
+ return;
+ }
+
+ // 2. 鏍规嵁瀹℃壒缁撴灉杩涜澶勭悊
+ if (cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
+ MesProFeedbackApproveReqVO reqVO = new MesProFeedbackApproveReqVO();
+ reqVO.setId(id);
+ // 鍒ゆ柇杩欎釜鎶ュ伐闇�涓嶉渶瑕佹壒娆″彿
+ MesProFeedbackBatchCheckRespVO mesProFeedbackBatchCheckRespVO = checkBatchRequirements(id);
+ if (mesProFeedbackBatchCheckRespVO.getNeedBatchInput()){
+ if (StrUtil.isBlank(reason)){
+ // 鎶ラ敊 璇峰湪瀹℃壒鎰忚閲屽~鍐欐壒娆″彿
+ throw exception(MD_ITEM_BATCH_CONFIG_AT_LEAST_ONE_APPROVE_FLAG);
+ }else {
+ BeanUtils.copyProperties(mesProFeedbackBatchCheckRespVO,reqVO);
+ reqVO.setLotNumber(reason);
+ }
+ }
+ approveFeedback(reqVO);
+ } else if (cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.REJECT.getStatus().equals(bpmResult) ||
+ cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
+ rejectFeedback(id);
+ }
}
@Override
@@ -191,23 +291,34 @@
feedback.getRouteId(), feedback.getProcessId());
boolean keyFlag = routeProcess != null && Boolean.TRUE.equals(routeProcess.getKeyFlag());
boolean checkFlag = routeProcess != null && Boolean.TRUE.equals(routeProcess.getCheckFlag());
- // 2.2 闈炶川妫�宸ュ簭锛氫粛鏈夊緟妫�鏁伴噺鏃朵笉鑳藉鎵癸紙璐ㄦ宸ュ簭鐨� uncheckQuantity > 0 鏄甯哥姸鎬侊紝涓嶅仛鎷︽埅锛�
+ // 2.2 闈炶川妫�宸ュ簭锛氬悎鏍煎搧/涓嶈壇鍝佹暟閲忕敱璐ㄦ纭畾锛涙湰宸ュ簭涓嶇粡杩囪川妫�锛屾姤宸ユ湭濉啓鏃堕粯璁ゅ叏閮ㄤ负鍚堟牸鍝�
+ if (!checkFlag
+ && feedback.getQualifiedQuantity() == null
+ && feedback.getUnqualifiedQuantity() == null) {
+ feedback.setQualifiedQuantity(feedback.getFeedbackQuantity());
+ feedback.setUnqualifiedQuantity(BigDecimal.ZERO);
+ feedbackMapper.updateById(new MesProFeedbackDO().setId(feedback.getId())
+ .setQualifiedQuantity(feedback.getFeedbackQuantity())
+ .setUnqualifiedQuantity(BigDecimal.ZERO));
+ }
+ // 2.3 闈炶川妫�宸ュ簭锛氫粛鏈夊緟妫�鏁伴噺鏃朵笉鑳藉鎵癸紙璐ㄦ宸ュ簭鐨� uncheckQuantity > 0 鏄甯哥姸鎬侊紝涓嶅仛鎷︽埅锛�
if (!checkFlag
&& feedback.getUncheckQuantity() != null
&& feedback.getUncheckQuantity().compareTo(BigDecimal.ZERO) > 0) {
throw exception(PRO_FEEDBACK_UNCHECK_QUANTITY_EXISTS, feedback.getUncheckQuantity());
}
- // 3. 鐗╂枡娑堣�楋細鍊掑啿宸ュ簭鎸� BOM 鑷姩鎵f枡锛涢潪鍊掑啿宸ュ簭璺宠繃锛堢墿鏂欒蛋鎵嬪伐棰嗘枡/鎶曟枡锛�
+ // 3. 鐗╂枡娑堣�楋細鍊掑啿宸ュ簭鎸夋湰宸ュ簭鎶曟枡 BOM 鑷姩鎵f枡锛涢潪鍊掑啿宸ュ簭璺宠繃锛堢墿鏂欒蛋鎵嬪伐棰嗘枡/鎶曟枡锛�
boolean backflushFlag = routeProcess != null && Boolean.TRUE.equals(routeProcess.getBackflushFlag());
if (backflushFlag) {
- // 3.1 鏍¢獙鍊掑啿宸ュ簭蹇呴』閰嶇疆 BOM 娑堣�楋紝閬垮厤闈欓粯涓嶆墸鏂�
- List<MesProWorkOrderBomDO> boms = workOrderBomService.getWorkOrderBomListByWorkOrderId(
- feedback.getWorkOrderId());
+ // 3.1 鏍¢獙鍊掑啿宸ュ簭蹇呴』閰嶇疆鏈伐搴忕殑鎶曟枡 BOM锛岄伩鍏嶉潤榛樹笉鎵f枡
+ // 锛堝彧鏍¢獙褰撳墠鎶ュ伐宸ュ簭鐨勬姇鏂欙紝鍏朵粬宸ュ簭鎶曟枡鐢卞悇鑷伐搴忔姤宸ユ椂鎵i櫎锛�
+ List<MesProWorkOrderBomDO> boms = workOrderBomService.getWorkOrderBomListByWorkOrderIdAndProcessId(
+ feedback.getWorkOrderId(), feedback.getProcessId());
if (CollUtil.isEmpty(boms)) {
throw exception(PRO_FEEDBACK_BACKFLUSH_BOM_REQUIRED);
}
- // 3.2 鐢熸垚娑堣�楄褰曞苟鎵ц鎵e噺锛圔OM 脳 鎶ュ伐鏁伴噺锛孎IFO 鎵g嚎杈瑰簱锛�
+ // 3.2 鐢熸垚娑堣�楄褰曞苟鎵ц鎵e噺锛堟湰宸ュ簭鎶曟枡鐢ㄩ噺姣斾緥 脳 鎶ュ伐鏁伴噺锛孎IFO 鎵g嚎杈瑰簱锛�
MesWmItemConsumeDO itemConsume = itemConsumeService.generateItemConsume(feedback);
if (itemConsume != null) {
itemConsumeService.finishItemConsume(itemConsume.getId());
@@ -273,6 +384,12 @@
if (ObjUtil.equal(line.getQualityStatus(), MesWmQualityStatusEnum.PASS.getStatus())) {
qualifiedQty = qualifiedQty.add(line.getQuantity());
}
+ }
+ // 1.1 鍏滃簳锛氬叧閿潪璐ㄦ宸ュ簭瀹℃壒鏃朵骇鍑哄崟琛屽皻鏈敓鎴愶紝鐩存帴閲囩敤鎶ュ伐鍗曚笂鐨勫悎鏍�/涓嶈壇鏁伴噺
+ // 锛堥潪璐ㄦ宸ュ簭榛樿鍏ㄩ儴涓哄悎鏍煎搧锛涜川妫�宸ュ簭鐨勫悎鏍�/涓嶈壇鍦ㄨ川妫�鍥炶皟鍚庢寜浜у嚭琛岃仛鍚堬級
+ if (CollUtil.isEmpty(lines)) {
+ qualifiedQty = ObjectUtil.defaultIfNull(feedback.getQualifiedQuantity(), BigDecimal.ZERO);
+ unqualifiedQty = ObjectUtil.defaultIfNull(feedback.getUnqualifiedQuantity(), BigDecimal.ZERO);
}
// 2. 鏇存柊浠诲姟鐨勫凡鐢熶骇/鍚堟牸/涓嶅悎鏍兼暟閲�
@@ -373,24 +490,79 @@
if (routeProcess == null) {
throw exception(PRO_FEEDBACK_ROUTE_PROCESS_INVALID);
}
- // 4.1 鏍¢獙鏁伴噺
- boolean checkFlag = Boolean.TRUE.equals(routeProcess.getCheckFlag());
- if (checkFlag) {
- // 闇�瑕佹楠岋細鍙渶濉姤宸ユ暟閲忥紝涓斿繀椤� > 0
- if (reqVO.getFeedbackQuantity() == null
- || reqVO.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) {
- throw exception(PRO_FEEDBACK_QUANTITY_MUST_POSITIVE);
- }
- } else {
- // 涓嶉渶妫�楠岋細闇�濉悎鏍煎搧 + 涓嶈壇鍝佹暟閲忥紝鍚堣 > 0
- BigDecimal qualified = ObjectUtil.defaultIfNull(reqVO.getQualifiedQuantity(), BigDecimal.ZERO);
- BigDecimal unqualified = ObjectUtil.defaultIfNull(reqVO.getUnqualifiedQuantity(), BigDecimal.ZERO);
- if (qualified.add(unqualified).compareTo(BigDecimal.ZERO) <= 0) {
- throw exception(PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_REQUIRED);
- }
+ // 4.1 鏍¢獙鏁伴噺锛氭棤璁烘槸鍚﹂渶瑕佹楠岋紝鎶ュ伐鍙渶濉姤宸ユ暟閲忥紝涓斿繀椤� > 0
+ // 鍚堟牸鍝�/涓嶈壇鍝佹暟閲忕敱璐ㄦ纭畾锛堥潪璐ㄦ宸ュ簭鍦ㄥ鎵规椂榛樿鍏ㄩ儴涓哄悎鏍煎搧锛�
+ if (reqVO.getFeedbackQuantity() == null
+ || reqVO.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) {
+ throw exception(PRO_FEEDBACK_QUANTITY_MUST_POSITIVE);
}
return task;
+ }
+
+ /**
+ * 椤哄簭鎶ュ伐鏍¢獙锛氬悓涓�鐢熶骇宸ュ崟鍐咃紝涓婁竴閬撳伐搴忓繀椤诲凡鎶ュ伐瀹屾垚锛屽惁鍒欎笉鍏佽鎶ユ湰閬撳伐搴�
+ *
+ * <p>鍒ゅ畾鍙e緞锛氫笂涓�閬撳伐搴忕殑鏈夋晥浠诲姟锛堟湭鍙栨秷锛夌疮璁″鎵归�氳繃鐨勪骇閲忓凡杈惧埌鍏舵帓浜ф暟閲忥紝
+ * 鍗充换涓�鏈夋晥浠诲姟 produced_quantity < quantity 閮借涓烘湭瀹屾垚骞舵嫤鎴��
+ * 涔嬫墍浠ヤ笉渚濊禆浠诲姟 status锛氫换鍔$姸鎬佸彧鏈夋暣鍗曞畬宸�/鍙栨秷鏃舵墠缃粓鎬�
+ * 锛坒inishTaskByOrderId / cancelTaskByOrderId锛夛紝鏃犳硶浣滀负"鍗曢亾宸ュ簭宸插畬鎴�"鐨勪緷鎹紝
+ * produced_quantity 鏄敮涓�瀹炴椂鍙潬鐨勮繘搴︿俊鍙枫��
+ *
+ * @param task 褰撳墠寰呮姤宸ヤ换鍔�
+ */
+ private void validatePreviousProcessFinished(MesProTaskDO task) {
+ if (task == null || task.getWorkOrderId() == null || task.getProcessId() == null) {
+ return; // 鏁版嵁涓嶅畬鏁达紝鏃犳硶鎺ㄥ椤哄簭锛屾斁琛�
+ }
+ // 1. 褰撳墠浠诲姟鎵�灞炲伐搴忓湪宸ュ崟宸ュ簭閾撅紙鎸� sort 鍗囧簭锛変腑鐨勪綅缃�
+ List<MesProWorkOrderProcessDO> processes = workOrderProcessService
+ .getWorkOrderProcessListByWorkOrderId(task.getWorkOrderId());
+ if (CollUtil.isEmpty(processes)) {
+ return; // 宸ュ崟鏈厤缃伐搴忥紝鏀捐
+ }
+ // 鎷疯礉鍚庡啀鎺掑簭锛岄伩鍏嶄慨鏀硅皟鐢ㄦ柟杩斿洖鐨勶紙鍙兘鏄笉鍙彉锛夐泦鍚�
+ processes = new ArrayList<>(processes);
+ processes.sort(Comparator.comparing(MesProWorkOrderProcessDO::getSort,
+ Comparator.nullsLast(Comparator.naturalOrder())));
+ int index = -1;
+ for (int i = 0; i < processes.size(); i++) {
+ if (ObjUtil.equal(processes.get(i).getProcessId(), task.getProcessId())) {
+ index = i;
+ break;
+ }
+ }
+ if (index <= 0) {
+ return; // 褰撳墠宸ュ簭涓嶅湪閾句腑锛堟暟鎹紓甯革紝鏀捐锛夋垨鏈韩灏辨槸绗竴閬撳伐搴忥紝鏃犻渶鍓嶇疆
+ }
+ Long prevProcessId = processes.get(index - 1).getProcessId();
+ if (prevProcessId == null) {
+ return;
+ }
+ // 2. 涓婁竴閬撳伐搴忕殑鏈夋晥浠诲姟锛堟帓闄ゅ凡鍙栨秷锛夌疮璁″緟瀹屾垚閲�
+ List<MesProTaskDO> prevTasks = taskService.getTaskListByWorkOrderIds(
+ Collections.singletonList(task.getWorkOrderId())).stream()
+ .filter(t -> ObjUtil.equal(t.getProcessId(), prevProcessId))
+ .filter(t -> !ObjUtil.equal(t.getStatus(), MesProTaskStatusEnum.CANCELED.getStatus()))
+ .toList();
+ if (CollUtil.isEmpty(prevTasks)) {
+ return; // 涓婁竴閬撳伐搴忔棤鏈夋晥鐢熶骇浠诲姟锛堝惈鍏ㄩ儴鍙栨秷锛夛紝瑙嗕负鏃犲墠缃姹傦紝鏀捐
+ }
+ BigDecimal remaining = BigDecimal.ZERO;
+ for (MesProTaskDO prevTask : prevTasks) {
+ BigDecimal qty = prevTask.getQuantity() == null ? BigDecimal.ZERO : prevTask.getQuantity();
+ BigDecimal produced = prevTask.getProducedQuantity() == null ? BigDecimal.ZERO : prevTask.getProducedQuantity();
+ if (produced.compareTo(qty) < 0) {
+ remaining = remaining.add(qty.subtract(produced));
+ }
+ }
+ if (remaining.compareTo(BigDecimal.ZERO) <= 0) {
+ return; // 涓婁竴閬撳伐搴忓凡鍏ㄩ儴鎶ユ弧锛屾斁琛�
+ }
+ // 3. 鎷︽埅骞舵彁绀轰笂涓�閬撳伐搴忓悕绉颁笌鍓╀綑寰呮姤鏁伴噺
+ MesProProcessDO prevProcess = processService.getProcess(prevProcessId);
+ String prevProcessName = prevProcess != null ? prevProcess.getName() : String.valueOf(prevProcessId);
+ throw exception(PRO_FEEDBACK_PREV_PROCESS_NOT_FINISHED, prevProcessName, remaining);
}
@Override
@@ -403,6 +575,8 @@
if (!MesProTaskStatusEnum.canFeedback(task.getStatus())) {
throw exception(PRO_FEEDBACK_CANNOT_CREATE_WHEN_PAUSED);
}
+ // 1.1 椤哄簭鎶ュ伐鏍¢獙锛氬悓涓�鐢熶骇宸ュ崟鍐咃紝涓婁竴閬撳伐搴忓繀椤诲凡鎶ュ伐瀹屾垚锛屽惁鍒欎笉鍏佽鎶ュ伐
+ validatePreviousProcessFinished(task);
// 2. 鏍¢獙宸ヨ壓璺嚎宸ュ簭閰嶇疆
MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId(
@@ -410,19 +584,10 @@
if (routeProcess == null) {
throw exception(PRO_FEEDBACK_ROUTE_PROCESS_INVALID);
}
- // 3. 鏍¢獙鏁伴噺
- boolean checkFlag = Boolean.TRUE.equals(routeProcess.getCheckFlag());
- if (checkFlag) {
- if (reqVO.getFeedbackQuantity() == null
- || reqVO.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) {
- throw exception(PRO_FEEDBACK_QUANTITY_MUST_POSITIVE);
- }
- } else {
- BigDecimal qualified = ObjectUtil.defaultIfNull(reqVO.getQualifiedQuantity(), BigDecimal.ZERO);
- BigDecimal unqualified = ObjectUtil.defaultIfNull(reqVO.getUnqualifiedQuantity(), BigDecimal.ZERO);
- if (qualified.add(unqualified).compareTo(BigDecimal.ZERO) <= 0) {
- throw exception(PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_REQUIRED);
- }
+ // 3. 鏍¢獙鏁伴噺锛氬彧濉姤宸ユ暟閲忥紝涓斿繀椤� > 0锛堝悎鏍煎搧/涓嶈壇鍝佹暟閲忕敱璐ㄦ纭畾锛�
+ if (reqVO.getFeedbackQuantity() == null
+ || reqVO.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) {
+ throw exception(PRO_FEEDBACK_QUANTITY_MUST_POSITIVE);
}
// 4. 鏋勫缓鎶ュ伐DO
MesProFeedbackDO feedback = new MesProFeedbackDO()
@@ -435,19 +600,29 @@
.setTaskId(reqVO.getTaskId())
.setItemId(task.getItemId())
.setFeedbackQuantity(reqVO.getFeedbackQuantity())
- .setQualifiedQuantity(reqVO.getQualifiedQuantity())
- .setUnqualifiedQuantity(reqVO.getUnqualifiedQuantity())
.setScheduledQuantity(task.getQuantity())
.setFeedbackTime(LocalDateTime.now())
.setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus())
.setRemark(reqVO.getRemark());
feedbackMapper.insert(feedback);
+ saveParamValues(task.getId(), reqVO.getParamValues());
// 5. 杩斿洖缁撴灉
MesProWorkOrderDO workOrder = workOrderService.getWorkOrder(task.getWorkOrderId());
+ // 5.1 鎶ュ伐鍚庡墿浣欏彲鎶ュ伐鏁伴噺 = 鎺掍骇 - 宸茬敓浜� - 鍦ㄩ�旓紙鍚湰娆℃姤宸ワ級
+ BigDecimal reportable = task.getQuantity() == null ? BigDecimal.ZERO : task.getQuantity();
+ BigDecimal produced = task.getProducedQuantity() == null ? BigDecimal.ZERO : task.getProducedQuantity();
+ BigDecimal inTransit = BigDecimal.ZERO;
+ for (MesProFeedbackDO fb : getFeedbackListByTaskId(task.getId())) {
+ if (!ObjUtil.equal(fb.getStatus(), MesProFeedbackStatusEnum.FINISHED.getStatus())) {
+ inTransit = inTransit.add(fb.getFeedbackQuantity() == null ? BigDecimal.ZERO : fb.getFeedbackQuantity());
+ }
+ }
+ BigDecimal reportableQuantity = reportable.subtract(produced).subtract(inTransit).max(BigDecimal.ZERO);
return new MesProFeedbackQuickCreateRespVO()
.setFeedbackId(feedback.getId())
.setTaskStatus(task.getStatus())
- .setWorkOrderStatus(workOrder != null ? workOrder.getStatus() : null);
+ .setWorkOrderStatus(workOrder != null ? workOrder.getStatus() : null)
+ .setReportableQuantity(reportableQuantity);
}
@Override
@@ -461,8 +636,6 @@
MesProFeedbackQuickCreateReqVO singleReq = new MesProFeedbackQuickCreateReqVO();
singleReq.setTaskId(taskId);
singleReq.setFeedbackQuantity(reqVO.getFeedbackQuantity());
- singleReq.setQualifiedQuantity(reqVO.getQualifiedQuantity());
- singleReq.setUnqualifiedQuantity(reqVO.getUnqualifiedQuantity());
singleReq.setRemark(reqVO.getRemark());
MesProFeedbackQuickCreateRespVO resp = quickCreateFeedback(singleReq);
results.add(new MesProFeedbackBatchCreateRespVO.BatchResult()
--
Gitblit v1.9.3