cuilei
2025-06-11 2be9b7f9c675e6ffe64adfac0a3e37f30404af99
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/PreparationOrderServiceImpl.java
@@ -1,22 +1,31 @@
package org.jeecg.modules.tms.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.system.service.ISysBusinessCodeRuleService;
import org.jeecg.modules.tms.convert.PreparationOrderConvert;
import org.jeecg.modules.tms.entity.PreparationOrder;
import org.jeecg.modules.tms.entity.PreparationOrderDetail;
import org.jeecg.modules.tms.entity.*;
import org.jeecg.modules.tms.entity.dto.PreparationOrderAndDetailDto;
import org.jeecg.modules.tms.enums.*;
import org.jeecg.modules.tms.mapper.PreparationOrderDetailMapper;
import org.jeecg.modules.tms.mapper.PreparationOrderMapper;
import org.jeecg.modules.tms.service.IPreparationOrderDetailService;
import org.jeecg.modules.tms.service.IPreparationOrderService;
import org.jeecg.modules.tms.service.*;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.List;
import java.util.Collection;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @Description: 刀具准备单
@@ -33,6 +42,18 @@
   private PreparationOrderDetailMapper preparationOrderDetailMapper;
   @Autowired
   private IPreparationOrderDetailService preparationOrderDetailService;
   @Autowired
   private IToolLedgerService toolLedgerService;
   @Autowired
   private IToolLedgerDetailService toolLedgerDetailService;
   @Autowired
   private IOutboundOrderService outboundOrderService;
   @Autowired
   private IOutboundDetailService outboundDetailService;
   @Autowired
   private ISysBusinessCodeRuleService businessCodeRuleService;
   @Autowired
   private IBaseToolsService baseToolsService;
   
   @Override
   @Transactional(rollbackFor = Exception.class)
@@ -66,4 +87,147 @@
      preparationOrderDetailService.saveBatch(detailUpdateList);
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   public List<String> convertToOutboundOrder(List<String> preparationOrderIds) {
      List<String> resultMessage = CollectionUtil.newArrayList();
      List<PreparationOrder> preparationOrderList = listByIds(preparationOrderIds);
      //校验准备单明细中的数量
      for (PreparationOrder preparationOrder : preparationOrderList) {
         if (PreparationOrderStatus.PENDING_AUDIT.getValue().equals(preparationOrder.getOrderStatus())) {
            resultMessage.add("准备单【" + preparationOrder.getPreparationOrderNum() + "】未审核,无法转出库申请!");
            continue;
         }
         if (PreparationOrderStatus.CONVERT.getValue().equals(preparationOrder.getOrderStatus())) {
            resultMessage.add("准备单【" + preparationOrder.getPreparationOrderNum() + "】已经转出,请勿重复提交!");
            continue;
         }
         List<PreparationOrderDetail> preparationOrderDetailList = preparationOrderDetailService.list(new LambdaQueryWrapper<PreparationOrderDetail>()
               .eq(PreparationOrderDetail::getPreparationOrderId, preparationOrder.getId()));
         Map<String, BigDecimal> preparationOrderToolCodeMap = preparationOrderDetailList.stream().collect(Collectors.toMap(PreparationOrderDetail::getToolCode,
               PreparationOrderDetail::getOutboundQuantity, (k1, k2) -> k1));
         List<ToolLedgerDetail> toolLedgerDetailList = toolLedgerDetailService.list(new LambdaQueryWrapper<ToolLedgerDetail>()
               .in(ToolLedgerDetail::getToolCode, preparationOrderToolCodeMap.keySet())
               .eq(ToolLedgerDetail::getQuantity, BigDecimal.ONE)
               .eq(ToolLedgerDetail::getStatus, ToolCirculationStatus.IN_STOCK.getValue()));
         Map<String, List<ToolLedgerDetail>> ledgerDetailToolCodeMap = toolLedgerDetailList.stream().collect(Collectors.groupingBy(ToolLedgerDetail::getToolCode));
         List<OutboundDetail> outboundDetailList = CollectionUtil.newArrayList();
         for (PreparationOrderDetail preparationOrderDetail : preparationOrderDetailList) {
            String toolCode = preparationOrderDetail.getToolCode();
            BigDecimal needQuantity = preparationOrderDetail.getOutboundQuantity();
            List<ToolLedgerDetail> toolLedgerDetails = ledgerDetailToolCodeMap.get(toolCode);
            BigDecimal stockQuantity = Optional.ofNullable(toolLedgerDetails).orElse(Collections.emptyList()).stream()
                  .map(ToolLedgerDetail::getQuantity)
                  .reduce(BigDecimal.ZERO, BigDecimal::add);
            if (CollectionUtil.isEmpty(toolLedgerDetails) || stockQuantity.compareTo(needQuantity) < 0) {
               BaseTools tools = baseToolsService.getById(toolCode);
               resultMessage.add("准备单【" + preparationOrder.getPreparationOrderNum() +"】中,编码为【" + tools.getToolCode() + "】的工具,库存不足,转出库申请单失败!");
               break;
            } else {
               //从库存明细中取出需要的数量,指定到把
               List<ToolLedgerDetail> selectedTools = toolLedgerDetails.subList(0, needQuantity.intValue());
               //生成申请单明细
               selectedTools.forEach(item->{
                  OutboundDetail detail = new OutboundDetail()
                        .setToolCode(item.getToolCode())
                        .setToolId(item.getToolId())
                        .setOutboundQuantity(item.getQuantity())
                        .setStorageLocation(item.getWarehouseId())
                        .setOutboundLocation(item.getPositionCode())
                        .setStatus(OutBoundStatusEnum.NOT_OUTBOUND.getValue())
                        .setCreateBy(Objects.requireNonNull(getCurrentUser()).getUsername())
                        .setCreateTime(new Date());
                  outboundDetailList.add(detail);
               });
            }
         }
         BigDecimal totalOutboundQuantity = preparationOrderDetailList.stream()
               .map(detail -> Optional.ofNullable(detail.getOutboundQuantity()).orElse(BigDecimal.ZERO))
               .reduce(BigDecimal.ZERO, BigDecimal::add);
         if (outboundDetailList.size() == totalOutboundQuantity.intValue()) {
            //指定到把的数量与需求数量一致,满足转出库申请单的条件,生成出库申请单
            OutboundOrder order = new OutboundOrder()
                  .setOutNum(businessCodeRuleService.generateBusinessCodeSeq("outBoundOrder"))
                  .setOutStorehouseType(OutStorehouseType.PREPARATION_OUTBOUND.getValue())
                  .setHandler(Objects.requireNonNull(getCurrentUser()).getId())
                  .setReviewer(Objects.requireNonNull(getCurrentUser()).getUsername())
                  .setOrderStatus(OutBillStatus.DRAFT.getValue())
                  .setSubjectMatter("刀具准备单转入")
                  .setPreparationOrderId(preparationOrder.getId())
                  .setPartDrawingNo(preparationOrder.getPartDrawingNo())
                  .setPartName(preparationOrder.getPartName())
                  .setPartMaterial(preparationOrder.getPartMaterial())
                  .setProductionProcessesNo(preparationOrder.getProductionProcessesNo())
                  .setBatchCode(preparationOrder.getBatchCode())
                  .setMachiningCount(preparationOrder.getMachiningCount())
                  .setEquipmentCode(preparationOrder.getEquipmentCode())
                  .setNcName(preparationOrder.getNcName())
                  .setCreateBy(Objects.requireNonNull(getCurrentUser()).getUsername())
                  .setCreateTime(new Date());
            outboundOrderService.save(order);
            outboundDetailList.forEach(item -> item.setOutStorehouseId(order.getId()));
            outboundDetailService.saveBatch(outboundDetailList);
            //锁定库存台账明细库存
            LambdaQueryWrapper<ToolLedgerDetail> queryWrapper = new LambdaQueryWrapper<>();
            String codeIdString = outboundDetailList.stream()
                  .map(detail -> "'" + detail.getToolCode() + ":" + detail.getToolId() + "'")
                  .collect(Collectors.joining(","));
            String sql = "(tool_code + ':' + tool_id) IN (" + codeIdString + ")";
            queryWrapper.apply(sql);
            toolLedgerDetailService.update(new ToolLedgerDetail().setQuantity(BigDecimal.ZERO), queryWrapper);
            //锁定库存台账主表
            List<ToolLedger> toolLedgerList = toolLedgerService.list(new LambdaQueryWrapper<ToolLedger>()
                  .in(ToolLedger::getToolId, preparationOrderToolCodeMap.keySet()));
            toolLedgerList.forEach(item -> {
               BigDecimal outboundQuantity = preparationOrderToolCodeMap.getOrDefault(item.getToolId(), BigDecimal.ZERO);
               item.setAvailableCount(Optional.ofNullable(item.getAvailableCount()).orElse(BigDecimal.ZERO).subtract(outboundQuantity));
            });
            toolLedgerService.updateBatchById(toolLedgerList);
            //更新准备单状态
            updateById(new PreparationOrder()
                  .setId(preparationOrder.getId())
                  .setOutboundTime(new Date())
                  .setOrderStatus(PreparationOrderStatus.CONVERT.getValue()));//3.已转出库申请
            resultMessage.add("准备单【" + preparationOrder.getPreparationOrderNum() + "】转出库申请单成功!");
         }
      }
      return resultMessage;
   }
   @Override
   public IPage<PreparationOrder> queryPageList(Page<PreparationOrder> page, Map<String, String[]> parameterMap) {
      QueryWrapper<PreparationOrder> queryWrapper = Wrappers.query();
      String[] preparationOrderNums = parameterMap.get("preparationOrderNum");
      if (preparationOrderNums != null && preparationOrderNums.length > 0) {
         queryWrapper.like("t.preparation_order_num", preparationOrderNums[0]);
      }
      String[] orderStatuses = parameterMap.get("orderStatus");
      if (orderStatuses != null && orderStatuses.length > 0) {
         queryWrapper.eq("t.order_status", orderStatuses[0]);
      }
      String[] beginTimes = parameterMap.get("beginTime");
      if (beginTimes != null && beginTimes.length > 0) {
         queryWrapper.ge("t.create_time", beginTimes[0]);
      }
      String[] endTimes = parameterMap.get("endTime");
      if (endTimes != null && endTimes.length > 0) {
         queryWrapper.le("t.create_time", endTimes[0]);
      }
      queryWrapper.orderByAsc("t.create_time");
      return this.baseMapper.queryPageList(page, queryWrapper);
   }
   private LoginUser getCurrentUser() {
      // 获取当前认证的登录用户信息
      Subject currentUser = SecurityUtils.getSubject();
      if (currentUser != null && currentUser.isAuthenticated()) {
         Object principal = currentUser.getPrincipal();
         if (principal instanceof LoginUser) {
            return (LoginUser) principal;
         }
      }
      return null;
   }
}