diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanRespVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanRespVO.java index f89f6985b9..e56ecdbfca 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanRespVO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/plan/vo/PlanRespVO.java @@ -87,6 +87,6 @@ public class PlanRespVO { private LocalDateTime createTime; @Schema(description = "制浆线") - @ExcelProperty("创建时间") + @ExcelProperty("制浆线") private String feedingPipeline; } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/plan/PlanMapper.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/plan/PlanMapper.java index 4e3af42cf4..80d66c8105 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/plan/PlanMapper.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/plan/PlanMapper.java @@ -10,6 +10,8 @@ import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanStatusEnum; import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; import java.util.ArrayList; import java.util.List; @@ -90,4 +92,8 @@ public interface PlanMapper extends BaseMapperX { .inIfPresent(PlanDO::getStatus, statusList) .orderByAsc(PlanDO::getStartTime)); } + @Update("UPDATE mes_plan SET status = #{status} WHERE id = #{id}") + void updateStatus(@Param("id") Long id, @Param("status") Integer status); + + } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/stockindetail/StockInDetailMapper.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/stockindetail/StockInDetailMapper.java index d06257ec14..c14a1a4319 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/stockindetail/StockInDetailMapper.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/stockindetail/StockInDetailMapper.java @@ -1,13 +1,18 @@ package cn.iocoder.yudao.module.mes.dal.mysql.stockindetail; -import java.util.*; - +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.mes.controller.admin.stockindetail.vo.StockInDetailPageReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.stockindetail.StockInDetailDO; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.apache.ibatis.annotations.Mapper; -import cn.iocoder.yudao.module.mes.controller.admin.stockindetail.vo.*; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; /** * 生产入库分配明细 Mapper @@ -29,4 +34,18 @@ public interface StockInDetailMapper extends BaseMapperX { .orderByDesc(StockInDetailDO::getId)); } + //查询计划已经入库的总数 + default BigDecimal selectSumBy(Long planId) { + + // SQL sum 查询 + List> result = selectMaps(new QueryWrapper() + .select("SUM(number) AS sumCount") + .eq("plan_id", planId)); + // 获得数量 + if (CollUtil.isEmpty(result)) { + return BigDecimal.ZERO; + } + return BigDecimal.valueOf(MapUtil.getDouble(result.get(0), "sumCount", 0D)); + } + } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanService.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanService.java index 8e5d011046..69ce6c4aec 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanService.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanService.java @@ -67,6 +67,7 @@ public interface PlanService { PlanDO selectLastOne(); List buildVOList(List list); + List buildProgress(List list); Boolean saveBatchPlan(List planDOList); @@ -82,4 +83,6 @@ public interface PlanService { List getPlanByStatus(List statusList); List getPlanByStatusAndPipeline(List statusList, String pipeline); + + void updateStatus( Long id,Integer status); } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanServiceImpl.java index 5cb66325c3..34a05ca759 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/plan/PlanServiceImpl.java @@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.itemrequisition.ItemRequisitio import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO; import cn.iocoder.yudao.module.mes.dal.dataobject.task.TaskDO; import cn.iocoder.yudao.module.mes.dal.mysql.plan.PlanMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.stockindetail.StockInDetailMapper; import cn.iocoder.yudao.module.mes.dal.redis.no.MesNoRedisDAO; import cn.iocoder.yudao.module.mes.service.itemrequisition.ItemRequisitionService; import cn.iocoder.yudao.module.mes.service.itemrequisition.entity.ItemRequisitionAndStock; @@ -28,6 +29,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.*; @@ -108,12 +110,16 @@ public class PlanServiceImpl implements PlanService { private AdminUserService userService; @Resource private TaskService taskService; + @Resource + private StockInDetailMapper stockInDetailMapper; @Override public List buildVOList(List list) { if (CollUtil.isEmpty(list)) { return Collections.emptyList(); } + //入库数量统计 + list = buildProgress(list); Map map = productService.getProductMap( convertSet(list, PlanDO::getProductId)); Map userMap = userService.getUserMap( @@ -132,7 +138,14 @@ public class PlanServiceImpl implements PlanService { task -> item.setTaskCode(task.getCode())); }); } - + @Override + public List buildProgress(List list){ + for (PlanDO plan : list) { + BigDecimal count = stockInDetailMapper.selectSumBy(plan.getId()); + plan.setFinishNumber(count.longValue()); + } + return list; + } /** * 查询按日期排序最后一个未完成(已经下达)的计划 **/ @@ -190,4 +203,8 @@ public class PlanServiceImpl implements PlanService { public List getPlanByStatusAndPipeline(List statusList, String pipeline) { return planMapper.selectBy(statusList, pipeline); } + @Override + public void updateStatus( Long id,Integer status){ + planMapper.updateStatus(id, status); + } } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/stockindetail/StockInDetailServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/stockindetail/StockInDetailServiceImpl.java index 183ef850a0..750ad3202d 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/stockindetail/StockInDetailServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/stockindetail/StockInDetailServiceImpl.java @@ -1,21 +1,18 @@ package cn.iocoder.yudao.module.mes.service.stockindetail; -import org.springframework.stereotype.Service; -import javax.annotation.Resource; -import org.springframework.validation.annotation.Validated; -import org.springframework.transaction.annotation.Transactional; - -import java.util.*; -import cn.iocoder.yudao.module.mes.controller.admin.stockindetail.vo.*; -import cn.iocoder.yudao.module.mes.dal.dataobject.stockindetail.StockInDetailDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; - +import cn.iocoder.yudao.module.mes.controller.admin.stockindetail.vo.StockInDetailPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.stockindetail.vo.StockInDetailSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.stockindetail.StockInDetailDO; import cn.iocoder.yudao.module.mes.dal.mysql.stockindetail.StockInDetailMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.STOCK_IN_DETAIL_NOT_EXISTS; /** * 生产入库分配明细 Service 实现类 diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/stockworkshop/MesStockInService.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/stockworkshop/MesStockInService.java index 7d205132d4..b37519869b 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/stockworkshop/MesStockInService.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/stockworkshop/MesStockInService.java @@ -1,5 +1,13 @@ package cn.iocoder.yudao.module.mes.service.stockworkshop; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.stockindetail.StockInDetailDO; + +import java.util.List; +import java.util.Map; + /** * ERP 其它入库单 Service 接口 * @@ -16,6 +24,8 @@ public interface MesStockInService { */ void updateStockInStatus(Long id, Integer status); - + void updateStatus(Long id, Integer status, boolean approve, ErpStockInDO stockIn, List stockInItems + ,List finishedPlans, List startPlans,Map stockInItemDOMap + ,Map stockInDetailDOMap); } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/stockworkshop/MesStockInServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/stockworkshop/MesStockInServiceImpl.java index 7b3440f741..0c09f80bd9 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/stockworkshop/MesStockInServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/stockworkshop/MesStockInServiceImpl.java @@ -5,21 +5,27 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInItemMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInMapper; -import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum; import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockRecordService; -import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService; import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO; +import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanStatusEnum; +import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.stockindetail.StockInDetailDO; +import cn.iocoder.yudao.module.mes.dal.mysql.stockindetail.StockInDetailMapper; +import cn.iocoder.yudao.module.mes.service.plan.PlanService; +import cn.iocoder.yudao.module.mes.service.stockindetail.StockInDetailService; 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.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*; @@ -40,21 +46,20 @@ public class MesStockInServiceImpl implements MesStockInService { @Resource private ErpStockInItemMapper stockInItemMapper; - @Resource - private ErpNoRedisDAO noRedisDAO; - @Resource private ErpProductService productService; @Resource - private ErpWarehouseService warehouseService; - @Resource - private ErpSupplierService supplierService; + private StockInDetailMapper stockInDetailMapper; @Resource private ErpStockRecordService stockRecordService; + @Resource + private StockInDetailService stockInDetailService; + @Resource + private PlanService planService; + @Override - @Transactional(rollbackFor = Exception.class) public void updateStockInStatus(Long id, Integer status) { boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status); // 1.1 校验存在 @@ -64,6 +69,42 @@ public class MesStockInServiceImpl implements MesStockInService { throw exception(approve ? STOCK_IN_APPROVE_FAIL : STOCK_IN_PROCESS_FAIL); } + // 3. 变更库存 + List stockInItems = stockInItemMapper.selectListByInId(id); + + //生产入库分配给计划 + //完工的计划列表 + List statusList = new ArrayList<>(); + statusList.add(PlanStatusEnum.完工.getValue()); + List finishedPlans = planService.getPlanByStatus(statusList); + planService.buildProgress(finishedPlans); + + //开工的计划列表 + statusList = new ArrayList<>(); + statusList.add(PlanStatusEnum.开工.getValue()); + List startPlans = planService.getPlanByStatus(statusList); + planService.buildProgress(startPlans); + //合并同产品 + Map stockInItemDOMap = new HashMap<>(); + stockInItems.forEach(itemDO -> { + if(stockInItemDOMap.containsKey(itemDO.getProductId())){ + BigDecimal old = stockInItemDOMap.get(itemDO.getProductId()).getCount(); + stockInItemDOMap.get(itemDO.getProductId()).setCount(old.add(itemDO.getCount())); + } + else stockInItemDOMap.put(itemDO.getProductId(), itemDO); + }); + + //分配 + Map stockInDetailDOMap = get(stockIn,finishedPlans,startPlans,stockInItemDOMap); + updateStatus( id, status, approve, stockIn,stockInItems + ,finishedPlans, startPlans, stockInItemDOMap, stockInDetailDOMap); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateStatus(Long id, Integer status, boolean approve, ErpStockInDO stockIn,List stockInItems + ,List finishedPlans, List startPlans, Map stockInItemDOMap, + Map stockInDetailDOMap){ // 2. 更新状态 int updateCount = stockInMapper.updateByIdAndStatus(id, stockIn.getStatus(), new ErpStockInDO().setStatus(status)); @@ -71,8 +112,6 @@ public class MesStockInServiceImpl implements MesStockInService { throw exception(approve ? STOCK_IN_APPROVE_FAIL : STOCK_IN_PROCESS_FAIL); } - // 3. 变更库存 - List stockInItems = stockInItemMapper.selectListByInId(id); Integer bizType = approve ? ErpStockRecordBizTypeEnum.OTHER_IN.getType() : ErpStockRecordBizTypeEnum.OTHER_IN_CANCEL.getType(); stockInItems.forEach(stockInItem -> { @@ -83,11 +122,16 @@ public class MesStockInServiceImpl implements MesStockInService { bizType, stockInItem.getInId(), stockInItem.getId(), stockIn.getNo())); }); - //生产入库分配给计划 - + //保存分配明细 + if(stockInDetailDOMap.size()>0) + stockInDetailMapper.insertBatch( stockInDetailDOMap.values()); + //将完成数大于计划数的完工计划状态改为 入库状态 + for (PlanDO plan : finishedPlans) { + if(plan.getFinishNumber()>= plan.getPlanNumber()){ + planService.updateStatus(plan.getId(), PlanStatusEnum.入库.getValue()); + } + } } - - private ErpStockInDO validateStockInExists(Long id) { ErpStockInDO stockIn = stockInMapper.selectById(id); if (stockIn == null) { @@ -96,5 +140,78 @@ public class MesStockInServiceImpl implements MesStockInService { return stockIn; } + private Map get( ErpStockInDO stockIn, List finishedPlans, List startPlans, + Map stockInItemDOMap){ + //分配入库数量 + Map stockInDetailDOMap = new HashMap<>(); + //先分配给完工的计划 + for (PlanDO plan : finishedPlans) { + //计划待分配 + long needNumber = plan.getPlanNumber() - plan.getFinishNumber() ; + if(needNumber > 0 && stockInItemDOMap.containsKey(plan.getProductId())){ + ErpStockInItemDO itemDO = stockInItemDOMap.get(plan.getProductId()); + //入库待分配 + if(itemDO.getCount().compareTo(BigDecimal.ZERO) > 0){ + StockInDetailDO detailDO = new StockInDetailDO() + .setStockInItemId(itemDO.getId()) + .setStockInId(stockIn.getId()).setStockInNo(stockIn.getNo()) + .setPlanId(plan.getId()).setProductId(plan.getProductId()); + + if(itemDO.getCount().compareTo(BigDecimal.valueOf(needNumber)) > 0){ + detailDO.setNumber(BigDecimal.valueOf(needNumber)); + } + else detailDO.setNumber(itemDO.getCount()); + //入库数量减去分配给计划的数量 + itemDO.setCount(itemDO.getCount().add(detailDO.getNumber().negate())); + plan.setFinishNumber(plan.getFinishNumber()+detailDO.getNumber().longValue()); + stockInDetailDOMap.put(itemDO.getId(), detailDO); + } + } + } + //分配给开工的计划 + for (PlanDO plan : startPlans) { + //计划待分配 + long needNumber = plan.getPlanNumber() - plan.getFinishNumber() ; + if(needNumber > 0 && stockInItemDOMap.containsKey(plan.getProductId())){ + ErpStockInItemDO itemDO = stockInItemDOMap.get(plan.getProductId()); + //入库待分配 + if(itemDO.getCount().compareTo(BigDecimal.ZERO) > 0){ + StockInDetailDO detailDO = new StockInDetailDO() + .setStockInItemId(itemDO.getId()) + .setStockInId(stockIn.getId()).setStockInNo(stockIn.getNo()) + .setPlanId(plan.getId()).setProductId(plan.getProductId()); + + if(itemDO.getCount().compareTo(BigDecimal.valueOf(needNumber)) > 0){ + detailDO.setNumber(BigDecimal.valueOf(needNumber)); + } + else detailDO.setNumber(itemDO.getCount()); + //入库数量减去分配给计划的数量 + itemDO.setCount(itemDO.getCount().add(detailDO.getNumber().negate())); + plan.setFinishNumber(plan.getFinishNumber()+detailDO.getNumber().longValue()); + stockInDetailDOMap.put(itemDO.getId(), detailDO); + } + } + } + //处理剩下的 + for (Long productId : stockInItemDOMap.keySet()) { + ErpStockInItemDO itemDO = stockInItemDOMap.get(productId); + //有剩余未分配 + if(itemDO.getCount().compareTo(BigDecimal.ZERO)>0){ + if(stockInDetailDOMap.containsKey(itemDO.getId())){ + BigDecimal old = stockInDetailDOMap.get(itemDO.getId()).getNumber(); + stockInDetailDOMap.get(itemDO.getId()).setNumber(old.add(itemDO.getCount())); + }else{ + StockInDetailDO detailDO = new StockInDetailDO() + .setStockInItemId(itemDO.getId()) + .setStockInId(stockIn.getId()).setStockInNo(stockIn.getNo()) + .setPlanId(null).setProductId(itemDO.getProductId()); + detailDO.setNumber(itemDO.getCount()); + stockInDetailDOMap.put(itemDO.getId(), detailDO); + } + } + } + + return stockInDetailDOMap; + } } \ No newline at end of file