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.*;
|
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.*;
|
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.math.BigDecimal;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* @Description: 刀具准备单
|
* @Author: jeecg-boot
|
* @Date: 2025-06-09
|
* @Version: V1.0
|
*/
|
@Service
|
public class PreparationOrderServiceImpl extends ServiceImpl<PreparationOrderMapper, PreparationOrder> implements IPreparationOrderService {
|
|
@Autowired
|
private PreparationOrderMapper preparationOrderMapper;
|
@Autowired
|
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;
|
@Autowired
|
private PreparationOrderConvert preparationOrderConvert;
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void delMain(String id) {
|
preparationOrderDetailMapper.deleteByMainId(id);
|
preparationOrderMapper.deleteById(id);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void delBatchMain(Collection<? extends Serializable> idList) {
|
for(Serializable id:idList) {
|
preparationOrderDetailMapper.deleteByMainId(id.toString());
|
preparationOrderMapper.deleteById(id);
|
}
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void editTotal(PreparationOrderAndDetailDto preparationOrderAndDetailDto) {
|
//先删除所有明细
|
preparationOrderDetailMapper.delete(new LambdaQueryWrapper<PreparationOrderDetail>()
|
.eq(PreparationOrderDetail::getPreparationOrderId, preparationOrderAndDetailDto.getId()));
|
PreparationOrder preparationOrder = preparationOrderConvert.convert(preparationOrderAndDetailDto);
|
updateById(preparationOrder);
|
List<PreparationOrderDetail> detailUpdateList = CollectionUtil.newArrayList();
|
preparationOrderAndDetailDto.getPreparationOrderDetailList().forEach(item->{
|
item.setPreparationOrderId(preparationOrder.getId());
|
detailUpdateList.add(item);
|
});
|
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);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void addPreparationOrderFromDnc(PreparationOrderAndDetailDto preparationOrderAndDetailDto) {
|
PreparationOrder preparationOrder = preparationOrderConvert.convert(preparationOrderAndDetailDto);
|
preparationOrder
|
.setId(null)
|
.setPreparationOrderNum(businessCodeRuleService.generateBusinessCodeSeq("ToolPreparationOrder"))
|
.setOrderStatus(PreparationOrderStatus.PENDING_AUDIT.getValue());
|
save(preparationOrder);
|
List<PreparationOrderDetail> preparationOrderDetailList = preparationOrderAndDetailDto.getPreparationOrderDetailList();
|
preparationOrderDetailList.forEach(item -> {
|
item.setId(null).setPreparationOrderId(preparationOrder.getId());
|
});
|
preparationOrderDetailService.saveBatch(preparationOrderDetailList);
|
}
|
|
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;
|
}
|
|
}
|