2026-03-27 16:15:17 +08:00
|
|
|
|
package com.klp.service.impl;
|
|
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
|
|
|
import com.klp.common.core.page.TableDataInfo;
|
|
|
|
|
|
import com.klp.common.core.domain.PageQuery;
|
|
|
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
2026-04-10 15:07:29 +08:00
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
2026-03-27 16:15:17 +08:00
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
|
|
import com.klp.common.utils.StringUtils;
|
|
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
|
|
import org.springframework.stereotype.Service;
|
2026-04-06 10:28:52 +08:00
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
2026-04-10 09:24:42 +08:00
|
|
|
|
import com.klp.common.helper.LoginHelper;
|
2026-03-27 16:15:17 +08:00
|
|
|
|
import com.klp.domain.bo.WmsTransferOrderBo;
|
|
|
|
|
|
import com.klp.domain.vo.WmsTransferOrderVo;
|
|
|
|
|
|
import com.klp.domain.WmsTransferOrder;
|
2026-04-06 10:28:52 +08:00
|
|
|
|
import com.klp.domain.WmsTransferOrderItem;
|
2026-04-10 13:13:58 +08:00
|
|
|
|
import com.klp.domain.WmsMaterialCoil;
|
|
|
|
|
|
import com.klp.domain.WmsRawMaterial;
|
|
|
|
|
|
import com.klp.domain.WmsProduct;
|
2026-03-27 16:15:17 +08:00
|
|
|
|
import com.klp.mapper.WmsTransferOrderMapper;
|
2026-04-06 10:28:52 +08:00
|
|
|
|
import com.klp.mapper.WmsTransferOrderItemMapper;
|
2026-04-10 13:13:58 +08:00
|
|
|
|
import com.klp.mapper.WmsMaterialCoilMapper;
|
|
|
|
|
|
import com.klp.mapper.WmsRawMaterialMapper;
|
|
|
|
|
|
import com.klp.mapper.WmsProductMapper;
|
2026-03-27 16:15:17 +08:00
|
|
|
|
import com.klp.service.IWmsTransferOrderService;
|
2026-04-06 10:28:52 +08:00
|
|
|
|
import com.klp.service.IWmsTransferOrderItemService;
|
2026-03-27 16:15:17 +08:00
|
|
|
|
|
2026-04-10 15:07:29 +08:00
|
|
|
|
import java.util.*;
|
2026-04-10 13:13:58 +08:00
|
|
|
|
import java.util.stream.Collectors;
|
2026-03-27 16:15:17 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 调拨单主Service业务层处理
|
|
|
|
|
|
*
|
|
|
|
|
|
* @author klp
|
|
|
|
|
|
* @date 2026-03-27
|
|
|
|
|
|
*/
|
|
|
|
|
|
@RequiredArgsConstructor
|
|
|
|
|
|
@Service
|
|
|
|
|
|
public class WmsTransferOrderServiceImpl implements IWmsTransferOrderService {
|
|
|
|
|
|
|
|
|
|
|
|
private final WmsTransferOrderMapper baseMapper;
|
2026-04-06 10:28:52 +08:00
|
|
|
|
private final WmsTransferOrderItemMapper wmsTransferOrderItemMapper;
|
|
|
|
|
|
private final IWmsTransferOrderItemService wmsTransferOrderItemService;
|
2026-04-10 13:13:58 +08:00
|
|
|
|
private final WmsMaterialCoilMapper coilMapper;
|
|
|
|
|
|
private final WmsRawMaterialMapper rawMaterialMapper;
|
|
|
|
|
|
private final WmsProductMapper productMapper;
|
2026-03-27 16:15:17 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 查询调拨单主
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public WmsTransferOrderVo queryById(Long orderId){
|
|
|
|
|
|
return baseMapper.selectVoById(orderId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 查询调拨单主列表
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public TableDataInfo<WmsTransferOrderVo> queryPageList(WmsTransferOrderBo bo, PageQuery pageQuery) {
|
|
|
|
|
|
LambdaQueryWrapper<WmsTransferOrder> lqw = buildQueryWrapper(bo);
|
|
|
|
|
|
Page<WmsTransferOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
|
|
|
|
|
return TableDataInfo.build(result);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 查询调拨单主列表
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public List<WmsTransferOrderVo> queryList(WmsTransferOrderBo bo) {
|
|
|
|
|
|
LambdaQueryWrapper<WmsTransferOrder> lqw = buildQueryWrapper(bo);
|
|
|
|
|
|
return baseMapper.selectVoList(lqw);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private LambdaQueryWrapper<WmsTransferOrder> buildQueryWrapper(WmsTransferOrderBo bo) {
|
|
|
|
|
|
Map<String, Object> params = bo.getParams();
|
|
|
|
|
|
LambdaQueryWrapper<WmsTransferOrder> lqw = Wrappers.lambdaQuery();
|
|
|
|
|
|
lqw.eq(StringUtils.isNotBlank(bo.getTransferNo()), WmsTransferOrder::getTransferNo, bo.getTransferNo());
|
|
|
|
|
|
lqw.like(StringUtils.isNotBlank(bo.getTransferName()), WmsTransferOrder::getTransferName, bo.getTransferName());
|
|
|
|
|
|
lqw.eq(bo.getTransferStatus() != null, WmsTransferOrder::getTransferStatus, bo.getTransferStatus());
|
|
|
|
|
|
lqw.eq(bo.getTransferTime() != null, WmsTransferOrder::getTransferTime, bo.getTransferTime());
|
2026-04-10 09:24:42 +08:00
|
|
|
|
lqw.like(StringUtils.isNotBlank(bo.getTransferType()), WmsTransferOrder::getTransferType, bo.getTransferType());
|
|
|
|
|
|
lqw.like(StringUtils.isNotBlank(bo.getApproveBy()), WmsTransferOrder::getApproveBy, bo.getApproveBy());
|
|
|
|
|
|
lqw.eq(bo.getApproveStatus() != null, WmsTransferOrder::getApproveStatus, bo.getApproveStatus());
|
|
|
|
|
|
lqw.eq(bo.getApproveTime() != null, WmsTransferOrder::getApproveTime, bo.getApproveTime());
|
2026-03-27 16:15:17 +08:00
|
|
|
|
return lqw;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 新增调拨单主
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public Boolean insertByBo(WmsTransferOrderBo bo) {
|
|
|
|
|
|
WmsTransferOrder add = BeanUtil.toBean(bo, WmsTransferOrder.class);
|
|
|
|
|
|
validEntityBeforeSave(add);
|
|
|
|
|
|
boolean flag = baseMapper.insert(add) > 0;
|
|
|
|
|
|
if (flag) {
|
|
|
|
|
|
bo.setOrderId(add.getOrderId());
|
|
|
|
|
|
}
|
|
|
|
|
|
return flag;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 修改调拨单主
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public Boolean updateByBo(WmsTransferOrderBo bo) {
|
|
|
|
|
|
WmsTransferOrder update = BeanUtil.toBean(bo, WmsTransferOrder.class);
|
|
|
|
|
|
validEntityBeforeSave(update);
|
|
|
|
|
|
return baseMapper.updateById(update) > 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 保存前的数据校验
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void validEntityBeforeSave(WmsTransferOrder entity){
|
|
|
|
|
|
//TODO 做一些数据校验,如唯一约束
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 批量删除调拨单主
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Override
|
2026-04-06 10:28:52 +08:00
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
2026-03-27 16:15:17 +08:00
|
|
|
|
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
|
|
|
|
|
if(isValid){
|
|
|
|
|
|
//TODO 做一些业务上的校验,判断是否需要校验
|
|
|
|
|
|
}
|
2026-04-10 11:10:30 +08:00
|
|
|
|
|
2026-04-06 10:28:52 +08:00
|
|
|
|
// 先删除关联的调拨单明细记录
|
|
|
|
|
|
if (ids != null && !ids.isEmpty()) {
|
|
|
|
|
|
LambdaQueryWrapper<WmsTransferOrderItem> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
|
queryWrapper.in(WmsTransferOrderItem::getTransferId, ids);
|
|
|
|
|
|
wmsTransferOrderItemMapper.delete(queryWrapper);
|
|
|
|
|
|
}
|
2026-04-10 11:10:30 +08:00
|
|
|
|
|
2026-04-06 10:28:52 +08:00
|
|
|
|
// 再删除调拨单主记录
|
2026-03-27 16:15:17 +08:00
|
|
|
|
return baseMapper.deleteBatchIds(ids) > 0;
|
|
|
|
|
|
}
|
2026-04-10 09:24:42 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 审批调拨单
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Override
|
2026-04-10 13:13:58 +08:00
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
2026-04-10 09:24:42 +08:00
|
|
|
|
public Boolean approve(Long orderId, Integer approveStatus) {
|
2026-04-10 13:13:58 +08:00
|
|
|
|
// 1. 查询并校验调拨单
|
2026-04-10 09:24:42 +08:00
|
|
|
|
WmsTransferOrder order = baseMapper.selectById(orderId);
|
|
|
|
|
|
if (order == null) {
|
|
|
|
|
|
throw new RuntimeException("调拨单不存在");
|
|
|
|
|
|
}
|
2026-04-10 11:10:30 +08:00
|
|
|
|
if (order.getApproveStatus() != null && order.getApproveStatus() != 1) {
|
2026-04-10 09:24:42 +08:00
|
|
|
|
throw new RuntimeException("该调拨单已审批,不能重复审批");
|
|
|
|
|
|
}
|
2026-04-10 13:13:58 +08:00
|
|
|
|
|
|
|
|
|
|
// 2. 更新审批状态
|
2026-04-10 09:24:42 +08:00
|
|
|
|
order.setApproveStatus(approveStatus);
|
|
|
|
|
|
order.setApproveBy(LoginHelper.getUsername());
|
|
|
|
|
|
order.setApproveTime(new Date());
|
2026-04-10 15:07:29 +08:00
|
|
|
|
order.setTransferStatus(1L);
|
2026-04-10 13:13:58 +08:00
|
|
|
|
boolean updateResult = baseMapper.updateById(order) > 0;
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 如果审批通过,批量更新钢卷信息
|
2026-04-10 13:19:35 +08:00
|
|
|
|
if (updateResult && approveStatus != null && approveStatus == 2) {
|
2026-04-10 13:13:58 +08:00
|
|
|
|
batchUpdateCoilsOnApprove(orderId, order.getTransferType());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return updateResult;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-04-10 15:07:29 +08:00
|
|
|
|
* 审批通过时批量更新钢卷信息 需要测试是否报错以及明细isTransfer字段是否改成1 钢卷是否被修改如果不改类型和逻辑库区钢卷的更新人时间就不会变
|
2026-04-10 13:13:58 +08:00
|
|
|
|
*/
|
|
|
|
|
|
private void batchUpdateCoilsOnApprove(Long orderId, String transferType) {
|
|
|
|
|
|
// 1. 批量查询调拨明细
|
|
|
|
|
|
LambdaQueryWrapper<WmsTransferOrderItem> itemWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
|
itemWrapper.eq(WmsTransferOrderItem::getTransferId, orderId);
|
|
|
|
|
|
List<WmsTransferOrderItem> items = wmsTransferOrderItemMapper.selectList(itemWrapper);
|
|
|
|
|
|
|
|
|
|
|
|
if (items == null || items.isEmpty()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 构建coilId到明细项的映射
|
|
|
|
|
|
Map<Long, WmsTransferOrderItem> coilToItemMap = items.stream()
|
|
|
|
|
|
.filter(item -> item.getCoilId() != null)
|
|
|
|
|
|
.collect(Collectors.toMap(
|
|
|
|
|
|
WmsTransferOrderItem::getCoilId,
|
|
|
|
|
|
v -> v,
|
|
|
|
|
|
(a, b) -> a
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 收集所有coilId
|
|
|
|
|
|
List<Long> coilIds = new ArrayList<>(coilToItemMap.keySet());
|
|
|
|
|
|
|
|
|
|
|
|
if (coilIds.isEmpty()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 批量查询钢卷并校验存在性
|
|
|
|
|
|
List<WmsMaterialCoil> coils = coilMapper.selectBatchIds(coilIds);
|
|
|
|
|
|
if (coils.size() != coilIds.size()) {
|
|
|
|
|
|
throw new RuntimeException("部分钢卷不存在");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-10 15:07:29 +08:00
|
|
|
|
// 5. 收集所有需要校验的itemId(使用调拨后的值)
|
2026-04-10 13:13:58 +08:00
|
|
|
|
List<Long> itemIdsToValidate = items.stream()
|
2026-04-10 15:07:29 +08:00
|
|
|
|
.map(WmsTransferOrderItem::getItemIdAfter)
|
2026-04-10 13:13:58 +08:00
|
|
|
|
.filter(itemId -> itemId != null)
|
|
|
|
|
|
.distinct()
|
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
|
|
|
|
|
|
// 6. 按物料类型分组校验itemId是否存在
|
|
|
|
|
|
validateItemIds(items, itemIdsToValidate);
|
|
|
|
|
|
|
|
|
|
|
|
// 7. 批量更新钢卷信息
|
|
|
|
|
|
List<WmsMaterialCoil> coilsToUpdate = coils.stream()
|
|
|
|
|
|
.map(coil -> {
|
|
|
|
|
|
// 从映射中快速找到对应的明细项
|
|
|
|
|
|
WmsTransferOrderItem item = coilToItemMap.get(coil.getCoilId());
|
|
|
|
|
|
if (item == null) {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 使用调拨后的值更新钢卷
|
|
|
|
|
|
Long finalItemId = item.getItemIdAfter();
|
|
|
|
|
|
Long finalMaterialType = item.getMaterialTypeAfter();
|
|
|
|
|
|
Long finalWarehouseId = item.getWarehouseIdAfter();
|
2026-04-10 15:07:29 +08:00
|
|
|
|
|
|
|
|
|
|
// 如果调拨后的值为空,则不修改该钢卷
|
|
|
|
|
|
if (finalItemId == null && finalMaterialType == null && finalWarehouseId == null) {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果不为空,必须itemId和itemType都不为空才能修改
|
|
|
|
|
|
if ((finalItemId != null || finalMaterialType != null)
|
|
|
|
|
|
&& (finalItemId == null || finalMaterialType == null)) {
|
|
|
|
|
|
// itemId和materialType只有一个有值,不符合要求,跳过
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 计算itemType
|
2026-04-10 13:13:58 +08:00
|
|
|
|
String finalItemType = finalMaterialType != null && finalMaterialType == 1 ? "raw_material" : "product";
|
|
|
|
|
|
|
|
|
|
|
|
// 更新钢卷信息
|
|
|
|
|
|
coil.setItemId(finalItemId);
|
|
|
|
|
|
coil.setItemType(finalItemType);
|
|
|
|
|
|
coil.setMaterialType(finalMaterialType != null && finalMaterialType == 1 ? "原料" : "成品");
|
|
|
|
|
|
coil.setWarehouseId(finalWarehouseId);
|
|
|
|
|
|
coil.setTransferType(transferType);
|
|
|
|
|
|
|
|
|
|
|
|
return coil;
|
|
|
|
|
|
})
|
2026-04-10 15:07:29 +08:00
|
|
|
|
.filter(Objects::nonNull)
|
2026-04-10 13:13:58 +08:00
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
|
2026-04-10 15:07:29 +08:00
|
|
|
|
// 8. 批量更新钢卷数据库
|
2026-04-10 13:13:58 +08:00
|
|
|
|
if (!coilsToUpdate.isEmpty()) {
|
2026-04-10 15:07:29 +08:00
|
|
|
|
coilMapper.updateBatchById(coilsToUpdate);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 9. 批量更新明细的isTransferred字段为1(已调拨)
|
|
|
|
|
|
List<Long> itemIds = items.stream()
|
|
|
|
|
|
.map(WmsTransferOrderItem::getOrderItemId)
|
|
|
|
|
|
.filter(Objects::nonNull)
|
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
|
|
|
|
|
|
if (!itemIds.isEmpty()) {
|
|
|
|
|
|
LambdaUpdateWrapper<WmsTransferOrderItem> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
|
|
|
updateWrapper.in(WmsTransferOrderItem::getOrderItemId, itemIds);
|
|
|
|
|
|
updateWrapper.set(WmsTransferOrderItem::getIsTransferred, 1);
|
|
|
|
|
|
wmsTransferOrderItemMapper.update(null, updateWrapper);
|
2026-04-10 13:13:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 校验itemId是否存在
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void validateItemIds(List<WmsTransferOrderItem> items, List<Long> itemIdsToValidate) {
|
|
|
|
|
|
if (itemIdsToValidate.isEmpty()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 按物料类型分组
|
|
|
|
|
|
Map<Long, List<Long>> materialTypeGroupMap = items.stream()
|
2026-04-10 15:07:29 +08:00
|
|
|
|
.filter(item -> item.getItemIdAfter() != null && item.getMaterialTypeAfter() != null)
|
2026-04-10 13:13:58 +08:00
|
|
|
|
.collect(Collectors.groupingBy(
|
2026-04-10 15:07:29 +08:00
|
|
|
|
WmsTransferOrderItem::getMaterialTypeAfter,
|
|
|
|
|
|
Collectors.mapping(WmsTransferOrderItem::getItemIdAfter, Collectors.toList())
|
2026-04-10 13:13:58 +08:00
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
|
|
// 校验原料
|
|
|
|
|
|
if (materialTypeGroupMap.containsKey(1L)) {
|
|
|
|
|
|
List<Long> rawMaterialIds = materialTypeGroupMap.get(1L).stream().distinct().collect(Collectors.toList());
|
|
|
|
|
|
List<WmsRawMaterial> rawMaterials = rawMaterialMapper.selectBatchIds(rawMaterialIds);
|
|
|
|
|
|
if (rawMaterials.size() != rawMaterialIds.size()) {
|
|
|
|
|
|
throw new RuntimeException("部分原材料不存在");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 校验成品
|
|
|
|
|
|
if (materialTypeGroupMap.containsKey(2L)) {
|
|
|
|
|
|
List<Long> productIds = materialTypeGroupMap.get(2L).stream().distinct().collect(Collectors.toList());
|
|
|
|
|
|
List<WmsProduct> products = productMapper.selectBatchIds(productIds);
|
|
|
|
|
|
if (products.size() != productIds.size()) {
|
|
|
|
|
|
throw new RuntimeException("部分产品不存在");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-04-10 09:24:42 +08:00
|
|
|
|
}
|
2026-03-27 16:15:17 +08:00
|
|
|
|
}
|