- 在WmsDeliveryPlanServiceImpl中添加LambdaUpdateWrapper导入 - 为发货计划删除操作添加级联删除逻辑,遍历计划ID并删除相关发货单及明细 - 新增cascadeDeleteDeliveryWaybillsByPlanId方法处理发货单及其明细的级联删除 - 在WmsDeliveryWaybillServiceImpl中添加WmsDeliveryWaybillDetail和WmsDeliveryWaybillDetailMapper依赖 - 为发货单删除操作添加级联删除发货单明细的功能 - 使用LambdaQueryWrapper构建查询条件删除关联的发货单明细记录
336 lines
13 KiB
Java
336 lines
13 KiB
Java
package com.klp.service.impl;
|
||
|
||
import cn.hutool.core.bean.BeanUtil;
|
||
import com.klp.common.core.domain.entity.SysUser;
|
||
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.QueryWrapper;
|
||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||
import com.klp.common.exception.ServiceException;
|
||
import com.klp.common.utils.StringUtils;
|
||
import com.klp.domain.*;
|
||
import com.klp.domain.vo.*;
|
||
import com.klp.mapper.*;
|
||
import com.klp.system.service.ISysUserService;
|
||
import lombok.RequiredArgsConstructor;
|
||
import org.springframework.stereotype.Service;
|
||
import com.klp.domain.bo.WmsDeliveryPlanBo;
|
||
import com.klp.service.IWmsDeliveryPlanService;
|
||
|
||
import java.util.*;
|
||
import java.util.stream.Collectors;
|
||
|
||
/**
|
||
* 发货计划Service业务层处理
|
||
*
|
||
* @author klp
|
||
* @date 2025-11-25
|
||
*/
|
||
@RequiredArgsConstructor
|
||
@Service
|
||
public class WmsDeliveryPlanServiceImpl implements IWmsDeliveryPlanService {
|
||
|
||
private final WmsDeliveryPlanMapper baseMapper;
|
||
|
||
private final ISysUserService userService;
|
||
|
||
private final WmsMaterialCoilMapper coilMapper;
|
||
|
||
private final WmsDeliveryWaybillMapper waybillMapper;
|
||
|
||
private final WmsDeliveryWaybillDetailMapper waybillDetailMapper;
|
||
|
||
private final WmsCoilPendingActionMapper coilPendingActionMapper;
|
||
|
||
/**
|
||
* 查询发货计划
|
||
*/
|
||
@Override
|
||
public WmsDeliveryPlanVo queryById(Long planId){
|
||
return baseMapper.selectVoById(planId);
|
||
}
|
||
|
||
/**
|
||
* 查询发货计划列表
|
||
*/
|
||
@Override
|
||
public TableDataInfo<WmsDeliveryPlanVo> queryPageList(WmsDeliveryPlanBo bo, PageQuery pageQuery) {
|
||
LambdaQueryWrapper<WmsDeliveryPlan> lqw = buildQueryWrapper(bo);
|
||
Page<WmsDeliveryPlanVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||
List<WmsDeliveryPlanVo> records = result.getRecords();
|
||
Set<String> userNames = records.stream()
|
||
.flatMap(v -> java.util.stream.Stream.of(v.getCreateBy(), v.getUpdateBy()))
|
||
.filter(StringUtils::isNotBlank)
|
||
.collect(Collectors.toSet());
|
||
if (!userNames.isEmpty()) {
|
||
Map<String, String> nickMap = userService.selectNickNameMapByUserNames(records.stream()
|
||
.flatMap(v -> java.util.stream.Stream.of(v.getCreateBy(), v.getUpdateBy()))
|
||
.filter(StringUtils::isNotBlank)
|
||
.distinct()
|
||
.collect(Collectors.toList()));
|
||
records.forEach(item -> {
|
||
if (StringUtils.isNotBlank(item.getCreateBy())) {
|
||
item.setCreateByName(nickMap.getOrDefault(item.getCreateBy(), item.getCreateBy()));
|
||
}
|
||
if (StringUtils.isNotBlank(item.getUpdateBy())) {
|
||
item.setUpdateByName(nickMap.getOrDefault(item.getUpdateBy(), item.getUpdateBy()));
|
||
}
|
||
});
|
||
}
|
||
return TableDataInfo.build(result);
|
||
}
|
||
|
||
/**
|
||
* 查询发货计划列表
|
||
*/
|
||
@Override
|
||
public List<WmsDeliveryPlanVo> queryList(WmsDeliveryPlanBo bo) {
|
||
LambdaQueryWrapper<WmsDeliveryPlan> lqw = buildQueryWrapper(bo);
|
||
return baseMapper.selectVoList(lqw);
|
||
}
|
||
|
||
private LambdaQueryWrapper<WmsDeliveryPlan> buildQueryWrapper(WmsDeliveryPlanBo bo) {
|
||
Map<String, Object> params = bo.getParams();
|
||
LambdaQueryWrapper<WmsDeliveryPlan> lqw = Wrappers.lambdaQuery();
|
||
lqw.like(StringUtils.isNotBlank(bo.getPlanName()), WmsDeliveryPlan::getPlanName, bo.getPlanName());
|
||
lqw.eq(bo.getPlanDate() != null, WmsDeliveryPlan::getPlanDate, bo.getPlanDate());
|
||
lqw.eq(bo.getPlanType() != null, WmsDeliveryPlan::getPlanType, bo.getPlanType());
|
||
lqw.eq(bo.getAuditStatus() != null, WmsDeliveryPlan::getAuditStatus, bo.getAuditStatus());
|
||
// 计划根据plan_date降序排序最新的放在最前面
|
||
lqw.orderByDesc(WmsDeliveryPlan::getPlanDate);
|
||
return lqw;
|
||
}
|
||
|
||
/**
|
||
* 新增发货计划
|
||
*/
|
||
@Override
|
||
public Boolean insertByBo(WmsDeliveryPlanBo bo) {
|
||
WmsDeliveryPlan add = BeanUtil.toBean(bo, WmsDeliveryPlan.class);
|
||
validEntityBeforeSave(add);
|
||
boolean flag = baseMapper.insert(add) > 0;
|
||
if (flag) {
|
||
bo.setPlanId(add.getPlanId());
|
||
}
|
||
return flag;
|
||
}
|
||
|
||
/**
|
||
* 修改发货计划
|
||
*/
|
||
@Override
|
||
public Boolean updateByBo(WmsDeliveryPlanBo bo) {
|
||
WmsDeliveryPlan update = BeanUtil.toBean(bo, WmsDeliveryPlan.class);
|
||
validEntityBeforeSave(update);
|
||
return baseMapper.updateById(update) > 0;
|
||
}
|
||
|
||
/**
|
||
* 保存前的数据校验
|
||
*/
|
||
private void validEntityBeforeSave(WmsDeliveryPlan entity){
|
||
//TODO 做一些数据校验,如唯一约束
|
||
}
|
||
|
||
/**
|
||
* 批量删除发货计划
|
||
*/
|
||
@Override
|
||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||
if (isValid) {
|
||
// 检查是否有关联的收货计划明细(actionType为401的操作记录)
|
||
for (Long planId : ids) {
|
||
// 查询与该计划关联的待操作记录
|
||
List<WmsCoilPendingAction> pendingActions = coilPendingActionMapper.selectList(
|
||
Wrappers.<WmsCoilPendingAction>lambdaQuery()
|
||
.eq(WmsCoilPendingAction::getActionType, 401)
|
||
.eq(WmsCoilPendingAction::getWarehouseId, planId)
|
||
.eq(WmsCoilPendingAction::getDelFlag, 0)
|
||
);
|
||
|
||
// 如果有待操作记录,检查这些记录关联的钢卷是否至少有一个还存在
|
||
if (!pendingActions.isEmpty()) {
|
||
boolean hasValidCoil = false;
|
||
|
||
for (WmsCoilPendingAction pendingAction : pendingActions) {
|
||
// 检查关联的钢卷是否还存在(未被删除)
|
||
WmsMaterialCoil coil = coilMapper.selectOne(
|
||
Wrappers.<WmsMaterialCoil>lambdaQuery()
|
||
.eq(WmsMaterialCoil::getCoilId, pendingAction.getCoilId())
|
||
.eq(WmsMaterialCoil::getDelFlag, 0)
|
||
);
|
||
|
||
// 如果存在任意一个未被删除的钢卷,标记为不允许删除
|
||
if (coil != null) {
|
||
hasValidCoil = true;
|
||
break; // 只要有一个存在就无需继续检查
|
||
}
|
||
}
|
||
|
||
// 只要有一个关联的钢卷还存在,就不允许删除计划
|
||
if (hasValidCoil) {
|
||
throw new ServiceException("计划下存在有效明细,无法删除");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 对于发货计划(planType = 0),需要先级联删除相关的发货单及明细
|
||
// 遍历所有要删除的计划,对发货计划进行级联删除
|
||
for (Long planId : ids) {
|
||
WmsDeliveryPlan plan = baseMapper.selectById(planId);
|
||
if (plan != null && plan.getPlanType() != null && plan.getPlanType() == 0) { // 发货计划
|
||
// 删除关联的发货单及明细
|
||
cascadeDeleteDeliveryWaybillsByPlanId(planId);
|
||
}
|
||
}
|
||
|
||
return baseMapper.deleteBatchIds(ids) > 0;
|
||
}
|
||
|
||
|
||
/**
|
||
* 获取发货计划统计信息
|
||
*
|
||
* @param planId 计划ID,可选
|
||
* @return 统计信息列表
|
||
*/
|
||
public List<WmsDeliveryPlanStatisticsVo> getDeliveryPlanStatistics(Long planId) {
|
||
return baseMapper.selectDeliveryPlanStatistics(planId);
|
||
}
|
||
|
||
/**
|
||
* 获取发货报表统计信息
|
||
*
|
||
* @param startTime 开始时间
|
||
* @param endTime 结束时间
|
||
* @return 报表统计信息(包含汇总和按类型统计)
|
||
*/
|
||
public WmsDeliveryReportResultVo getDeliveryReport(Date startTime, Date endTime) {
|
||
WmsDeliveryReportResultVo result = new WmsDeliveryReportResultVo();
|
||
|
||
// 获取汇总数据
|
||
WmsDeliveryReportSummaryVo summary = baseMapper.selectDeliveryReportSummary(startTime, endTime);
|
||
result.setSummary(summary);
|
||
|
||
// 获取按钢卷类型分类的数据
|
||
List<WmsDeliveryReportByTypeVo> details = baseMapper.selectDeliveryReportByType(startTime, endTime);
|
||
result.setDetails(details);
|
||
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 获取收货报表统计信息
|
||
*/
|
||
@Override
|
||
public WmsReceivingReportResultVo getReceivingReport(Date startTime, Date endTime) {
|
||
WmsReceivingReportResultVo result = new WmsReceivingReportResultVo();
|
||
WmsReceivingReportSummaryVo summary = baseMapper.selectReceivingReportSummary(startTime, endTime);
|
||
result.setSummary(summary);
|
||
List<WmsReceivingReportByTypeVo> details = baseMapper.selectReceivingReportByType(startTime, endTime);
|
||
result.setDetails(details);
|
||
return result;
|
||
}
|
||
|
||
@Override
|
||
public List<WmsMaterialCoilVo> getSelectableCoilsByPlanId(Long planId) {
|
||
if (planId == null) {
|
||
return Collections.emptyList();
|
||
}
|
||
WmsDeliveryPlanVo planVo = baseMapper.selectVoById(planId);
|
||
if (planVo == null || StringUtils.isBlank(planVo.getCoil())) {
|
||
return Collections.emptyList();
|
||
}
|
||
Set<Long> planCoilIds = Arrays.stream(planVo.getCoil().split(","))
|
||
.map(String::trim)
|
||
.filter(StringUtils::isNotBlank)
|
||
.map(Long::valueOf)
|
||
.collect(Collectors.toSet());
|
||
|
||
if (planCoilIds.isEmpty()) {
|
||
return Collections.emptyList();
|
||
}
|
||
|
||
List<WmsDeliveryWaybill> waybills = waybillMapper.selectList(
|
||
Wrappers.<WmsDeliveryWaybill>lambdaQuery().eq(WmsDeliveryWaybill::getPlanId, planId)
|
||
);
|
||
if (waybills == null || waybills.isEmpty()) {
|
||
return queryCoilsByIds(planCoilIds);
|
||
}
|
||
Set<Long> waybillIds = waybills.stream().map(WmsDeliveryWaybill::getWaybillId).collect(Collectors.toSet());
|
||
if (waybillIds.isEmpty()) {
|
||
return queryCoilsByIds(planCoilIds);
|
||
}
|
||
List<WmsDeliveryWaybillDetail> details = waybillDetailMapper.selectList(
|
||
Wrappers.<WmsDeliveryWaybillDetail>lambdaQuery().in(WmsDeliveryWaybillDetail::getWaybillId, waybillIds)
|
||
);
|
||
Set<Long> usedCoilIds = details == null ? Collections.emptySet() : details.stream()
|
||
.map(WmsDeliveryWaybillDetail::getCoilId)
|
||
.filter(Objects::nonNull)
|
||
.collect(Collectors.toSet());
|
||
|
||
planCoilIds.removeAll(usedCoilIds);
|
||
if (planCoilIds.isEmpty()) {
|
||
return Collections.emptyList();
|
||
}
|
||
return queryCoilsByIds(planCoilIds);
|
||
}
|
||
|
||
private List<WmsMaterialCoilVo> queryCoilsByIds(Set<Long> coilIds) {
|
||
if (coilIds == null || coilIds.isEmpty()) {
|
||
return Collections.emptyList();
|
||
}
|
||
QueryWrapper<WmsMaterialCoil> qw = new QueryWrapper<>();
|
||
qw.in("mc.coil_id", coilIds);
|
||
qw.eq("mc.del_flag", 0);
|
||
//根据创建时间倒叙
|
||
qw.orderByDesc("mc.create_time");
|
||
// 使用动态联查以返回更完整的钢卷信息
|
||
return coilMapper.selectVoListWithDynamicJoin(qw);
|
||
}
|
||
|
||
/**
|
||
* 级联删除发货单及其明细数据
|
||
*
|
||
* @param planId 计划ID
|
||
*/
|
||
private void cascadeDeleteDeliveryWaybillsByPlanId(Long planId) {
|
||
// 先查询该计划下的所有发货单
|
||
List<WmsDeliveryWaybill> waybills = waybillMapper.selectList(
|
||
Wrappers.<WmsDeliveryWaybill>lambdaQuery()
|
||
.eq(WmsDeliveryWaybill::getPlanId, planId)
|
||
.eq(WmsDeliveryWaybill::getDelFlag, 0)
|
||
);
|
||
|
||
if (!waybills.isEmpty()) {
|
||
// 获取所有发货单ID
|
||
List<Long> waybillIds = waybills.stream()
|
||
.map(WmsDeliveryWaybill::getWaybillId)
|
||
.collect(Collectors.toList());
|
||
|
||
// 先删除发货单明细
|
||
if (!waybillIds.isEmpty()) {
|
||
LambdaQueryWrapper<WmsDeliveryWaybillDetail> detailWrapper =
|
||
Wrappers.<WmsDeliveryWaybillDetail>lambdaQuery()
|
||
.in(WmsDeliveryWaybillDetail::getWaybillId, waybillIds)
|
||
.eq(WmsDeliveryWaybillDetail::getDelFlag, 0);
|
||
|
||
// 直接删除
|
||
waybillDetailMapper.delete(detailWrapper);
|
||
}
|
||
|
||
// 再删除发货单主表
|
||
LambdaQueryWrapper<WmsDeliveryWaybill> waybillWrapper =
|
||
Wrappers.<WmsDeliveryWaybill>lambdaQuery()
|
||
.in(WmsDeliveryWaybill::getWaybillId, waybillIds)
|
||
.eq(WmsDeliveryWaybill::getDelFlag, 0);
|
||
waybillMapper.delete(waybillWrapper);
|
||
}
|
||
}
|
||
|
||
}
|