|
|
@@ -1,12 +1,12 @@
|
|
|
package com.jeesite.modules.mes.service;
|
|
|
|
|
|
-import java.text.SimpleDateFormat;
|
|
|
-import java.util.Date;
|
|
|
import java.util.List;
|
|
|
|
|
|
-import com.jeesite.common.lang.ObjectUtils;
|
|
|
+import com.jeesite.common.lang.StringUtils;
|
|
|
import com.jeesite.common.mybatis.mapper.query.QueryType;
|
|
|
+import com.jeesite.common.service.ServiceException;
|
|
|
import com.jeesite.modules.mes.entity.MesProduct;
|
|
|
+import com.jeesite.modules.mes.entity.MesProductOrder;
|
|
|
import com.jeesite.modules.mes.entity.MesShift;
|
|
|
import com.jeesite.modules.mes.resp.MesShiftDataResp;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
@@ -16,6 +16,8 @@ import com.jeesite.common.entity.Page;
|
|
|
import com.jeesite.common.service.CrudService;
|
|
|
import com.jeesite.modules.mes.entity.MesProductPlan;
|
|
|
import com.jeesite.modules.mes.dao.MesProductPlanDao;
|
|
|
+import com.jeesite.modules.wms.entity.WmsBom;
|
|
|
+import com.jeesite.modules.wms.service.WmsBomService;
|
|
|
|
|
|
/**
|
|
|
* 生产计划Service
|
|
|
@@ -27,10 +29,15 @@ public class MesProductPlanService extends CrudService<MesProductPlanDao, MesPro
|
|
|
|
|
|
private final MesShiftService mesShiftService;
|
|
|
private final MesProductService mesProductService;
|
|
|
+ private final MesProductOrderService mesProductOrderService;
|
|
|
+ private final WmsBomService wmsBomService;
|
|
|
|
|
|
- public MesProductPlanService(MesShiftService mesShiftService, MesProductService mesProductService) {
|
|
|
+ public MesProductPlanService(MesShiftService mesShiftService, MesProductService mesProductService,
|
|
|
+ MesProductOrderService mesProductOrderService, WmsBomService wmsBomService) {
|
|
|
this.mesShiftService = mesShiftService;
|
|
|
this.mesProductService = mesProductService;
|
|
|
+ this.mesProductOrderService = mesProductOrderService;
|
|
|
+ this.wmsBomService = wmsBomService;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -76,6 +83,68 @@ public class MesProductPlanService extends CrudService<MesProductPlanDao, MesPro
|
|
|
@Transactional
|
|
|
public void save(MesProductPlan mesProductPlan) {
|
|
|
if(mesProductPlan.getIsNewRecord()){
|
|
|
+ if(StringUtils.isBlank(mesProductPlan.getOrderId())
|
|
|
+ || mesProductPlan.getDay() == null
|
|
|
+ || StringUtils.isBlank(mesProductPlan.getShiftId())
|
|
|
+ || mesProductPlan.getNums() == null
|
|
|
+ || mesProductPlan.getNums() <= 0){
|
|
|
+ throw new ServiceException(text("生产订单、日期、班次、生产数量不能为空,且生产数量必须大于0"));
|
|
|
+ }
|
|
|
+
|
|
|
+ MesShift mesShift = mesShiftService.get(new MesShift(mesProductPlan.getShiftId()));
|
|
|
+ if(mesShift == null || !"0".equals(mesShift.getStatus())){
|
|
|
+ throw new ServiceException(text("所选班次不存在或已停用,请重新选择"));
|
|
|
+ }
|
|
|
+
|
|
|
+ MesProductOrder mesProductOrder = mesProductOrderService.get(new MesProductOrder(mesProductPlan.getOrderId()));
|
|
|
+ if(mesProductOrder == null || !"1".equals(mesProductOrder.getState())){
|
|
|
+ throw new ServiceException(text("只有已下发的生产订单才能排产"));
|
|
|
+ }
|
|
|
+
|
|
|
+ String bomCateSn = null;
|
|
|
+ if(StringUtils.isNotBlank(mesProductOrder.getBomId())){
|
|
|
+ WmsBom wmsBom = wmsBomService.get(new WmsBom(mesProductOrder.getBomId()));
|
|
|
+ if(wmsBom != null){
|
|
|
+ bomCateSn = wmsBom.getProductCateId();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(StringUtils.isBlank(bomCateSn)){
|
|
|
+ throw new ServiceException(text("生产订单的BOM未维护工件类型,无法排产"));
|
|
|
+ }
|
|
|
+
|
|
|
+ MesProductPlan query = new MesProductPlan();
|
|
|
+ query.setOrderId(mesProductPlan.getOrderId());
|
|
|
+ query.setDay(mesProductPlan.getDay());
|
|
|
+ query.setShiftId(mesProductPlan.getShiftId());
|
|
|
+ query.getSqlMap().getWhere().and("a.status", QueryType.EQ, "0");
|
|
|
+ if(!findList(query).isEmpty()){
|
|
|
+ throw new ServiceException(text("同一订单、日期、班次已存在有效的生产计划,不能重复排产"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 同一日期、班次、产品只能有一个计划,否则产品创建时无法唯一确定计划。
|
|
|
+ MesProductPlan slotQuery = new MesProductPlan();
|
|
|
+ slotQuery.setDay(mesProductPlan.getDay());
|
|
|
+ slotQuery.setShiftId(mesProductPlan.getShiftId());
|
|
|
+ slotQuery.setBomProductCateId(bomCateSn);
|
|
|
+ slotQuery.getSqlMap().getWhere().and("a.status", QueryType.EQ, "0");
|
|
|
+ if(!findList(slotQuery).isEmpty()){
|
|
|
+ throw new ServiceException(text("同一日期、班次、产品已存在生产计划,不能重复排产"));
|
|
|
+ }
|
|
|
+
|
|
|
+ MesProductPlan sumQuery = new MesProductPlan();
|
|
|
+ sumQuery.setOrderId(mesProductPlan.getOrderId());
|
|
|
+ sumQuery.getSqlMap().getWhere().and("a.status", QueryType.EQ, "0");
|
|
|
+ long plannedNums = 0L;
|
|
|
+ for(MesProductPlan plan : findList(sumQuery)){
|
|
|
+ if(plan.getNums() != null){
|
|
|
+ plannedNums += plan.getNums();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(mesProductOrder.getNums() != null
|
|
|
+ && plannedNums + mesProductPlan.getNums() > mesProductOrder.getNums()){
|
|
|
+ throw new ServiceException(text("累计计划数量不能超过生产订单数量"));
|
|
|
+ }
|
|
|
+
|
|
|
mesProductPlan.setIsPick("0");
|
|
|
}
|
|
|
super.save(mesProductPlan);
|
|
|
@@ -98,24 +167,71 @@ public class MesProductPlanService extends CrudService<MesProductPlanDao, MesPro
|
|
|
@Override
|
|
|
@Transactional
|
|
|
public void delete(MesProductPlan mesProductPlan) {
|
|
|
+ if(mesProductPlan != null && StringUtils.isNotBlank(mesProductPlan.getId())){
|
|
|
+ MesProduct query = new MesProduct();
|
|
|
+ query.setPlanId(mesProductPlan.getId());
|
|
|
+ if(mesProductService.findCount(query) > 0){
|
|
|
+ throw new ServiceException(text("该计划已绑定产品,不能直接删除"));
|
|
|
+ }
|
|
|
+ }
|
|
|
super.delete(mesProductPlan);
|
|
|
}
|
|
|
|
|
|
- public MesProductPlan getCurPlan(){
|
|
|
- MesProductPlan mesProductPlan1 = null;
|
|
|
+ /**
|
|
|
+ * 获取当前班次、指定工件类型对应的唯一有效生产计划。
|
|
|
+ *
|
|
|
+ * 计划日期以“班次开始日期”为准,因此跨零点的夜班在次日凌晨仍然匹配前一天的计划。
|
|
|
+ *
|
|
|
+ * @param cateSn 产品工件类型(对应 wms_bom.product_cate_id)
|
|
|
+ * @return 唯一计划;没有计划时返回 null
|
|
|
+ */
|
|
|
+ public MesProductPlan getCurrentPlan(String cateSn){
|
|
|
+ if(StringUtils.isBlank(cateSn)){
|
|
|
+ throw new ServiceException(text("产品未维护工件类型,无法匹配生产计划"));
|
|
|
+ }
|
|
|
+
|
|
|
MesShiftDataResp mesShiftDataResp = mesShiftService.getCurShift();
|
|
|
- if(!ObjectUtils.isEmpty(mesShiftDataResp)){
|
|
|
- MesProductPlan mesProductPlan = new MesProductPlan();
|
|
|
- Date date = new Date();
|
|
|
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
- String timeStr = sdf.format(date);
|
|
|
-
|
|
|
- mesProductPlan.getSqlMap().getWhere().and("a.day", QueryType.EQ, timeStr);
|
|
|
- mesProductPlan.setShiftId(mesShiftDataResp.getMesShift().getId());
|
|
|
- mesProductPlan1 = findInfo(mesProductPlan);
|
|
|
+ if(mesShiftDataResp == null
|
|
|
+ || mesShiftDataResp.getMesShift() == null
|
|
|
+ || StringUtils.isBlank(mesShiftDataResp.getStart())
|
|
|
+ || mesShiftDataResp.getStart().length() < 10){
|
|
|
+ throw new ServiceException(text("当前时间未匹配到有效班次,无法匹配生产计划"));
|
|
|
+ }
|
|
|
+
|
|
|
+ String planDay = mesShiftDataResp.getStart().substring(0, 10);
|
|
|
+ MesProductPlan query = new MesProductPlan();
|
|
|
+ query.setShiftId(mesShiftDataResp.getMesShift().getId());
|
|
|
+ query.setDay(java.sql.Date.valueOf(planDay));
|
|
|
+ query.setBomProductCateId(cateSn);
|
|
|
+ query.getSqlMap().getWhere().and("a.status", QueryType.EQ, "0");
|
|
|
+ query.getSqlMap().getWhere().and("c.state", QueryType.EQ, "1");
|
|
|
+
|
|
|
+ List<MesProductPlan> plans = findList(query);
|
|
|
+ if(plans.isEmpty()){
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if(plans.size() > 1){
|
|
|
+ throw new ServiceException(text("当前班次、该产品存在多条有效生产计划,请先处理重复计划"));
|
|
|
+ }
|
|
|
+ return plans.get(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验计划剩余可生产数量,防止超产。
|
|
|
+ * 一件产品在创建时即占用一个计划数量,因此这里统计已绑定该计划的产品数。
|
|
|
+ *
|
|
|
+ * @param plan 已匹配到的生产计划
|
|
|
+ */
|
|
|
+ public void validatePlanCapacity(MesProductPlan plan){
|
|
|
+ if(plan == null || StringUtils.isBlank(plan.getId()) || plan.getNums() == null){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ MesProduct query = new MesProduct();
|
|
|
+ query.setPlanId(plan.getId());
|
|
|
+ long produced = mesProductService.findCount(query);
|
|
|
+ if(produced >= plan.getNums()){
|
|
|
+ throw new ServiceException(text("生产计划已完成,不能继续生产"));
|
|
|
}
|
|
|
- return mesProductPlan1;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
-
|