Files
xgy-oa/klp-wms/src/main/java/com/klp/service/impl/WmsStockIoDetailServiceImpl.java
Joshi 8cf81f29f9 feat(wms): 补全出入库明细中的单位信息
- 在新增出入库明细时,如果单位信息为空,自动从商品或原材料表中获取
- 支持产品和原材料两种物料类型的单位信息补全
- 优化了数据录入流程,提高了系统易用性
2025-08-23 16:52:22 +08:00

224 lines
9.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.klp.common.utils.StringUtils;
import com.klp.domain.WmsProduct;
import com.klp.domain.WmsRawMaterial;
import com.klp.mapper.WmsProductMapper;
import com.klp.mapper.WmsRawMaterialMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.klp.domain.bo.WmsStockIoDetailBo;
import com.klp.domain.vo.WmsStockIoDetailVo;
import com.klp.domain.WmsStockIoDetail;
import com.klp.domain.WmsStockIo;
import com.klp.mapper.WmsStockIoDetailMapper;
import com.klp.mapper.WmsStockIoMapper;
import com.klp.service.IWmsStockIoDetailService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.Date;
import com.klp.common.exception.ServiceException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
/**
* 出入库单明细Service业务层处理
*
* @author Joshi
* @date 2025-07-18
*/
@RequiredArgsConstructor
@Service
public class WmsStockIoDetailServiceImpl implements IWmsStockIoDetailService {
private final WmsStockIoDetailMapper baseMapper;
private final WmsStockIoMapper stockIoMapper;
private final WmsProductMapper productMapper;
private final WmsRawMaterialMapper rawMaterialMapper;
/**
* 查询出入库单明细
*/
@Override
public WmsStockIoDetailVo queryById(Long detailId){
return baseMapper.selectVoById(detailId);
}
/**
* 查询出入库单明细列表
*/
@Override
public TableDataInfo<WmsStockIoDetailVo> queryPageList(WmsStockIoDetailBo bo, PageQuery pageQuery) {
QueryWrapper<WmsStockIoDetail> qw = buildQueryWrapperPlus(bo);
Page<WmsStockIoDetailVo> result = baseMapper.selectVoPagePlus(pageQuery.build(), qw);
return TableDataInfo.build(result);
}
/**
* 查询出入库单明细列表
*/
@Override
public List<WmsStockIoDetailVo> queryList(WmsStockIoDetailBo bo) {
LambdaQueryWrapper<WmsStockIoDetail> qw = buildQueryWrapper(bo);
return baseMapper.selectVoList(qw);
}
private LambdaQueryWrapper<WmsStockIoDetail> buildQueryWrapper(WmsStockIoDetailBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<WmsStockIoDetail> lqw = new LambdaQueryWrapper<>();
lqw.eq(bo.getStockIoId() != null, WmsStockIoDetail::getStockIoId, bo.getStockIoId());
lqw.eq(bo.getWarehouseId() != null, WmsStockIoDetail::getWarehouseId, bo.getWarehouseId());
lqw.eq(StringUtils.isNotBlank(bo.getItemType()), WmsStockIoDetail::getItemType, bo.getItemType());
lqw.eq(bo.getItemId() != null, WmsStockIoDetail::getItemId, bo.getItemId());
lqw.eq(bo.getQuantity() != null, WmsStockIoDetail::getQuantity, bo.getQuantity());
lqw.eq(StringUtils.isNotBlank(bo.getUnit()), WmsStockIoDetail::getUnit, bo.getUnit());
lqw.eq(StringUtils.isNotBlank(bo.getBatchNo()), WmsStockIoDetail::getBatchNo, bo.getBatchNo());
return lqw;
}
private QueryWrapper<WmsStockIoDetail> buildQueryWrapperPlus(WmsStockIoDetailBo bo) {
Map<String, Object> params = bo.getParams();
QueryWrapper<WmsStockIoDetail> qw = new QueryWrapper<>();
qw.eq("d.del_flag", 0); // 手动添加逻辑删除条件
qw.eq(bo.getStockIoId() != null, "d.stock_io_id", bo.getStockIoId());
qw.eq(bo.getWarehouseId() != null, "d.warehouse_id", bo.getWarehouseId());
qw.eq(StringUtils.isNotBlank(bo.getItemType()), "d.item_type", bo.getItemType());
qw.eq(bo.getItemId() != null, "d.item_id", bo.getItemId());
qw.eq(bo.getQuantity() != null, "d.quantity", bo.getQuantity());
qw.eq(StringUtils.isNotBlank(bo.getUnit()), "d.unit", bo.getUnit());
qw.eq(StringUtils.isNotBlank(bo.getBatchNo()), "d.batch_no", bo.getBatchNo());
return qw;
}
/**
* 新增出入库单明细
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean insertByBo(WmsStockIoDetailBo bo) {
// 检查主表状态,已审核的单据不能添加明细
WmsStockIo stockIo = stockIoMapper.selectById(bo.getStockIoId());
if (stockIo != null && stockIo.getStatus() >= 2) {
throw new ServiceException("已审核的单据不能修改明细");
}
// 如果unit为空自动查item表补全新增逻辑
String unit = bo.getUnit();
if (unit == null || unit.trim().isEmpty()) {
if ("product".equals(bo.getItemType())) {
WmsProduct p = productMapper.selectById(bo.getItemId());
unit = p != null ? p.getUnit() : null;
} else if ("raw_material".equals(bo.getItemType())) {
WmsRawMaterial r = rawMaterialMapper.selectById(bo.getItemId());
unit = r != null ? r.getUnit() : null;
}
}
// 将获取到的unit设置回bo对象
bo.setUnit(unit);
WmsStockIoDetail add = BeanUtil.toBean(bo, WmsStockIoDetail.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setDetailId(add.getDetailId());
// 检查主表状态,如果有明细且状态为草稿,则自动变为待审核
if (stockIo != null && stockIo.getStatus() == 0) {
// 检查是否有明细
Long detailCount = baseMapper.selectCount(
new LambdaQueryWrapper<WmsStockIoDetail>()
.eq(WmsStockIoDetail::getStockIoId, bo.getStockIoId())
);
if (detailCount > 0) {
// 自动更新状态为待审核
stockIo.setStatus(1);
stockIo.setUpdateTime(new Date());
stockIoMapper.updateById(stockIo);
}
}
}
return flag;
}
/**
* 修改出入库单明细
*/
@Override
public Boolean updateByBo(WmsStockIoDetailBo bo) {
// 检查主表状态,已审核的单据不能修改明细
WmsStockIo stockIo = stockIoMapper.selectById(bo.getStockIoId());
if (stockIo != null && stockIo.getStatus() >= 2) {
throw new ServiceException("已审核的单据不能修改明细");
}
WmsStockIoDetail update = BeanUtil.toBean(bo, WmsStockIoDetail.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(WmsStockIoDetail entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除出入库单明细
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
// 获取要删除的明细对应的主表ID检查状态
List<WmsStockIoDetail> details = baseMapper.selectBatchIds(ids);
if (details != null && !details.isEmpty()) {
// 检查主表状态,已审核的单据不能删除明细
for (WmsStockIoDetail detail : details) {
WmsStockIo stockIo = stockIoMapper.selectById(detail.getStockIoId());
if (stockIo != null && stockIo.getStatus() >= 2) {
throw new ServiceException("已审核的单据不能修改明细");
}
}
// 按主表ID分组
Map<Long, List<WmsStockIoDetail>> stockIoIdMap = details.stream()
.collect(java.util.stream.Collectors.groupingBy(WmsStockIoDetail::getStockIoId));
boolean flag = baseMapper.deleteBatchIds(ids) > 0;
if (flag) {
// 检查每个主表是否还有其他明细
for (Long stockIoId : stockIoIdMap.keySet()) {
Long remainingCount = baseMapper.selectCount(
new LambdaQueryWrapper<WmsStockIoDetail>()
.eq(WmsStockIoDetail::getStockIoId, stockIoId)
);
// 如果没有明细了,状态回退为草稿
if (remainingCount == 0) {
WmsStockIo stockIo = stockIoMapper.selectById(stockIoId);
if (stockIo != null && stockIo.getStatus() == 1) {
stockIo.setStatus(0);
stockIo.setUpdateTime(new Date());
stockIoMapper.updateById(stockIo);
}
}
}
}
return flag;
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}