Browse Source

其他出库

master
han\hanst 5 months ago
parent
commit
5f064444e7
  1. 1
      .gitignore
  2. 27
      src/main/java/com/gaotao/modules/inboundNotification/config/AsyncConfig.java
  3. 210
      src/main/java/com/gaotao/modules/otherOutbound/controller/OtherOutboundController.java
  4. 101
      src/main/java/com/gaotao/modules/otherOutbound/dao/OtherOutboundMapper.java
  5. 71
      src/main/java/com/gaotao/modules/otherOutbound/service/OtherOutboundService.java
  6. 265
      src/main/java/com/gaotao/modules/otherOutbound/service/impl/OtherOutboundServiceImpl.java
  7. 140
      src/main/resources/mapper/otherOutbound/OtherOutboundMapper.xml

1
.gitignore

@ -23,3 +23,4 @@ target
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid* hs_err_pid*
/src/test/

27
src/main/java/com/gaotao/modules/inboundNotification/config/AsyncConfig.java

@ -1,27 +0,0 @@
package com.gaotao.modules.inboundNotification.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
/**
* 异步任务配置
*/
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("InboundAsync-");
executor.initialize();
return executor;
}
}

210
src/main/java/com/gaotao/modules/otherOutbound/controller/OtherOutboundController.java

@ -0,0 +1,210 @@
package com.gaotao.modules.otherOutbound.controller;
import com.gaotao.common.utils.R;
import com.gaotao.modules.otherOutbound.service.OtherOutboundService;
import com.gaotao.modules.sys.controller.AbstractController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* 其他出库控制器
* 数据来源return_notification_head/detail表类型为其他出库
*/
@RestController
@RequestMapping("/otherOutbound")
@Api(tags = "其他出库管理")
public class OtherOutboundController extends AbstractController {
@Autowired
private OtherOutboundService otherOutboundService;
/**
* 获取其他出库单列表
* 数据来源return_notification_head表类型为其他出库
*/
@PostMapping("/getOutboundList")
@ApiOperation("获取其他出库单列表")
public R getOutboundList(@RequestBody Map<String, Object> params) {
try {
String site = (String) params.get("site");
String warehouseId = (String) params.get("warehouseId");
String searchCode = (String) params.get("searchCode");
String status = (String) params.get("status");
if (warehouseId == null || warehouseId.trim().isEmpty()) {
return R.error("仓库ID不能为空");
}
// 默认状态为待出库
if (status == null || status.trim().isEmpty()) {
status = "待出库";
}
logger.info("获取其他出库单列表,站点: {}, 仓库: {}, 搜索码: {}, 状态: {}",
site, warehouseId, searchCode, status);
List<Map<String, Object>> list = otherOutboundService.getOutboundList(
site, warehouseId, searchCode, status);
return R.ok().put("data", list);
} catch (Exception e) {
logger.error("获取其他出库单列表失败", e);
return R.error("获取数据失败: " + e.getMessage());
}
}
/**
* 获取其他出库单详情
*/
@PostMapping("/getOutboundDetails")
@ApiOperation("获取其他出库单详情")
public R getOutboundDetails(@RequestBody Map<String, Object> params) {
try {
String outboundNo = (String) params.get("outboundNo");
String buNo = (String) params.get("buNo");
String warehouseId = (String) params.get("warehouseId");
String site = (String) params.get("site");
if (outboundNo == null || outboundNo.trim().isEmpty()) {
return R.error("出库单号不能为空");
}
if (warehouseId == null || warehouseId.trim().isEmpty()) {
return R.error("仓库ID不能为空");
}
Map<String, Object> result = otherOutboundService.getOutboundDetails(
outboundNo, buNo, warehouseId, site);
if (result == null || result.isEmpty()) {
return R.error("未找到出库单详情");
}
return R.ok().put("data", result);
} catch (Exception e) {
logger.error("获取其他出库单详情失败", e);
return R.error("获取详情失败: " + e.getMessage());
}
}
/**
* 验证标签与其他出库单是否匹配并检查库存
*/
@PostMapping("/validateLabelWithOutbound")
@ApiOperation("验证标签与出库单匹配")
public R validateLabelWithOutbound(@RequestBody Map<String, Object> params) {
try {
String labelCode = (String) params.get("labelCode");
String outboundNo = (String) params.get("outboundNo");
String warehouseId = (String) params.get("warehouseId");
String site = (String) params.get("site");
String buNo = (String) params.get("buNo");
if (labelCode == null || labelCode.trim().isEmpty()) {
return R.error("标签条码不能为空");
}
if (outboundNo == null || outboundNo.trim().isEmpty()) {
return R.error("出库单号不能为空");
}
Map<String, Object> result = otherOutboundService.validateLabelWithOutbound(
labelCode, outboundNo, warehouseId, site, buNo);
return R.ok().put("data", result);
} catch (Exception e) {
logger.error("其他出库标签验证失败", e);
return R.error(e.getMessage());
}
}
/**
* 确认其他出库
* 系统逻辑
* 1. 更新库存表中的标签状态
* 2. 更改return_notification_head表中的单据状态为"已出库"
* 3. 生成WMS出库记录Transheader...
* 4. 异步调用ERP接口回传数据
*/
@PostMapping("/confirmOtherOutbound")
@ApiOperation("确认其他出库")
public R confirmOtherOutbound(@RequestBody Map<String, Object> params) {
try {
String site = (String) params.get("site");
String buNo = (String) params.get("buNo");
String outboundNo = (String) params.get("outboundNo");
String warehouseId = (String) params.get("warehouseId");
List<Map<String, Object>> labels = (List<Map<String, Object>>) params.get("labels");
if (outboundNo == null || outboundNo.trim().isEmpty()) {
return R.error("出库单号不能为空");
}
if (warehouseId == null || warehouseId.trim().isEmpty()) {
return R.error("仓库ID不能为空");
}
if (labels == null || labels.isEmpty()) {
return R.error("标签列表不能为空");
}
// 验证标签数据完整性
for (Map<String, Object> label : labels) {
String labelCode = (String) label.get("labelCode");
if (labelCode == null || labelCode.trim().isEmpty()) {
return R.error("标签条码不能为空");
}
}
boolean success = otherOutboundService.confirmOtherOutbound(
site, buNo, outboundNo, warehouseId, labels);
if (success) {
return R.ok("出库成功");
} else {
return R.error("出库失败");
}
} catch (Exception e) {
logger.error("其他出库失败", e);
return R.error("出库失败: " + e.getMessage());
}
}
/**
* 获取其他出库单物料清单
* 根据sitebuNooutboundNo从return_notification_detail表获取物料信息
*/
@PostMapping("/getMaterialList")
@ApiOperation("获取物料清单")
public R getMaterialList(@RequestBody Map<String, Object> params) {
try {
String site = (String) params.get("site");
String buNo = (String) params.get("buNo");
String outboundNo = (String) params.get("outboundNo");
if (site == null || site.trim().isEmpty()) {
return R.error("站点不能为空");
}
if (buNo == null || buNo.trim().isEmpty()) {
return R.error("业务单元不能为空");
}
if (outboundNo == null || outboundNo.trim().isEmpty()) {
return R.error("出库单号不能为空");
}
List<Map<String, Object>> materialList = otherOutboundService.getMaterialList(site, buNo, outboundNo);
return R.ok().put("data", materialList);
} catch (Exception e) {
logger.error("获取其他出库物料清单失败", e);
return R.error("获取物料清单失败: " + e.getMessage());
}
}
}

101
src/main/java/com/gaotao/modules/otherOutbound/dao/OtherOutboundMapper.java

@ -0,0 +1,101 @@
package com.gaotao.modules.otherOutbound.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
public interface OtherOutboundMapper extends BaseMapper {
/**
* 获取其他出库单列表
* @param site 站点
* @param warehouseId 仓库ID
* @param searchCode 搜索条件
* @param status 状态
* @return 出库单列表
*/
List<Map<String, Object>> getOutboundList(@Param("site") String site,
@Param("warehouseId") String warehouseId,
@Param("searchCode") String searchCode,
@Param("status") String status);
/**
* 获取其他出库单详情
* @param outboundNo 出库单号
* @param buNo 业务单元
* @param warehouseId 仓库ID
* @param site 站点
* @return 出库单详情
*/
Map<String, Object> getOutboundDetails(@Param("outboundNo") String outboundNo,
@Param("buNo") String buNo,
@Param("warehouseId") String warehouseId,
@Param("site") String site);
/**
* 验证标签与其他出库单是否匹配
* @param labelCode 标签条码
* @param outboundNo 出库单号
* @param warehouseId 仓库ID
* @param site 站点
* @param buNo 业务单元
* @return 标签信息
*/
Map<String, Object> validateLabelWithOutbound(@Param("labelCode") String labelCode,
@Param("outboundNo") String outboundNo,
@Param("warehouseId") String warehouseId,
@Param("site") String site,
@Param("buNo") String buNo);
/**
* 更新库存表中的标签状态
* @param labelCodes 标签条码列表
* @param status 状态
* @param site 站点
* @param buNo 业务单元
* @return 更新行数
*/
int updateInventoryStatus(@Param("labelCodes") List<String> labelCodes,
@Param("status") String status,
@Param("site") String site,
@Param("buNo") String buNo);
/**
* 更新出库单状态
* @param outboundNo 出库单号
* @param status 状态
* @param site 站点
* @param buNo 业务单元
* @return 更新行数
*/
int updateOutboundStatus(@Param("outboundNo") String outboundNo,
@Param("status") String status,
@Param("site") String site,
@Param("buNo") String buNo);
/**
* 检查出库单的所有标签是否都已出库
* @param outboundNo 出库单号
* @param site 站点
* @param buNo 业务单元
* @return 统计信息totalLabels总标签数outboundLabels已出库标签数
*/
Map<String, Object> checkAllLabelsOutbound(@Param("outboundNo") String outboundNo,
@Param("site") String site,
@Param("buNo") String buNo);
/**
* 获取其他出库单物料清单
* @param site 站点
* @param buNo 业务单元
* @param outboundNo 出库单号
* @return 物料清单
*/
List<Map<String, Object>> getMaterialList(@Param("site") String site,
@Param("buNo") String buNo,
@Param("outboundNo") String outboundNo);
}

71
src/main/java/com/gaotao/modules/otherOutbound/service/OtherOutboundService.java

@ -0,0 +1,71 @@
package com.gaotao.modules.otherOutbound.service;
import java.util.List;
import java.util.Map;
/**
* 其他出库服务接口
* 数据来源return_notification_head/detail表类型为其他出库
*/
public interface OtherOutboundService {
/**
* 获取其他出库单列表
* 数据来源return_notification_head表类型为其他出库
* @param site 站点
* @param warehouseId 仓库ID
* @param searchCode 搜索条件
* @param status 状态
* @return 出库单列表
*/
List<Map<String, Object>> getOutboundList(String site, String warehouseId, String searchCode, String status);
/**
* 获取其他出库单详情
* 数据来源return_notification_head表关联库存表统计
* @param outboundNo 出库单号
* @param buNo 业务单元
* @param warehouseId 仓库ID
* @param site 站点
* @return 出库单详情
*/
Map<String, Object> getOutboundDetails(String outboundNo, String buNo, String warehouseId, String site);
/**
* 验证标签与其他出库单是否匹配并检查库存
* 从库存表验证标签信息
* @param labelCode 标签条码
* @param outboundNo 出库单号
* @param warehouseId 仓库ID
* @param site 站点
* @param buNo 业务单元
* @return 标签信息
*/
Map<String, Object> validateLabelWithOutbound(String labelCode, String outboundNo,
String warehouseId, String site, String buNo);
/**
* 确认其他出库
* 1. 更新库存表中的标签状态
* 2. 更新return_notification_head表状态
* 3. 生成出库事务记录
* @param site 站点
* @param buNo 业务单元
* @param outboundNo 出库单号
* @param warehouseId 仓库ID
* @param labels 标签列表
* @return 处理结果
*/
boolean confirmOtherOutbound(String site, String buNo, String outboundNo,
String warehouseId, List<Map<String, Object>> labels);
/**
* 获取其他出库单物料清单
* 数据来源return_notification_detail表关联库存表
* @param site 站点
* @param buNo 业务单元
* @param outboundNo 出库单号
* @return 物料清单
*/
List<Map<String, Object>> getMaterialList(String site, String buNo, String outboundNo);
}

265
src/main/java/com/gaotao/modules/otherOutbound/service/impl/OtherOutboundServiceImpl.java

@ -0,0 +1,265 @@
package com.gaotao.modules.otherOutbound.service.impl;
import com.gaotao.modules.otherOutbound.dao.OtherOutboundMapper;
import com.gaotao.modules.otherOutbound.service.OtherOutboundService;
import com.gaotao.modules.inventoryStock.service.InventoryStockService;
import com.gaotao.modules.trans.entity.TransDetail;
import com.gaotao.modules.trans.entity.TransDetailDto;
import com.gaotao.modules.trans.entity.TransHeader;
import com.gaotao.modules.trans.service.TransDetailService;
import com.gaotao.modules.trans.service.TransHeaderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 其他出库服务实现类
*/
@Service
public class OtherOutboundServiceImpl implements OtherOutboundService {
private static final Logger logger = LoggerFactory.getLogger(OtherOutboundServiceImpl.class);
@Autowired
private OtherOutboundMapper otherOutboundMapper;
@Autowired
private InventoryStockService inventoryStockService;
@Autowired
private TransHeaderService transHeaderService;
@Autowired
private TransDetailService transDetailService;
@Override
public List<Map<String, Object>> getOutboundList(String site, String warehouseId, String searchCode, String status) {
try {
logger.info("获取其他出库单列表,站点: {}, 仓库: {}, 搜索码: {}, 状态: {}",
site, warehouseId, searchCode, status);
List<Map<String, Object>> list = otherOutboundMapper.getOutboundList(site, warehouseId, searchCode, status);
logger.info("获取其他出库单列表成功,共{}条记录", list != null ? list.size() : 0);
return list != null ? list : new ArrayList<>();
} catch (Exception e) {
logger.error("获取其他出库单列表失败", e);
throw new RuntimeException("获取出库单列表失败: " + e.getMessage());
}
}
@Override
public Map<String, Object> getOutboundDetails(String outboundNo, String buNo, String warehouseId, String site) {
try {
logger.info("获取其他出库单详情,出库单号: {}, 业务单元: {}, 仓库: {}, 站点: {}",
outboundNo, buNo, warehouseId, site);
Map<String, Object> details = otherOutboundMapper.getOutboundDetails(outboundNo, buNo, warehouseId, site);
if (details != null) {
logger.info("获取其他出库单详情成功");
} else {
logger.warn("未找到出库单详情");
}
return details;
} catch (Exception e) {
logger.error("获取其他出库单详情失败", e);
throw new RuntimeException("获取出库单详情失败: " + e.getMessage());
}
}
@Override
public Map<String, Object> validateLabelWithOutbound(String labelCode, String outboundNo,
String warehouseId, String site, String buNo) {
try {
logger.info("验证标签与其他出库单匹配,标签: {}, 出库单: {}, 仓库: {}, 站点: {}, 业务单元: {}",
labelCode, outboundNo, warehouseId, site, buNo);
Map<String, Object> result = otherOutboundMapper.validateLabelWithOutbound(
labelCode, outboundNo, warehouseId, site, buNo);
if (result == null || result.isEmpty()) {
throw new RuntimeException("该标签与出库单不匹配或标签状态不正确");
}
// 检查标签状态只有"在库"状态的标签才能出库
String labelStatus = (String) result.get("status");
if (!"在库".equals(labelStatus)) {
throw new RuntimeException("标签状态为:" + labelStatus + ",无法出库");
}
logger.info("标签验证成功,物料编码: {}, 数量: {}",
result.get("partNo"), result.get("quantity"));
return result;
} catch (Exception e) {
logger.error("验证标签与其他出库单匹配失败", e);
throw new RuntimeException(e.getMessage());
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean confirmOtherOutbound(String site, String buNo, String outboundNo,
String warehouseId, List<Map<String, Object>> labels) {
logger.info("开始确认其他出库,出库单号: {}, 仓库ID: {}, 标签数量: {}",
outboundNo, warehouseId, labels.size());
try {
// 1. 更新库存表中的标签状态为"已出库"
List<String> labelCodes = new ArrayList<>();
for (Map<String, Object> label : labels) {
labelCodes.add((String) label.get("labelCode"));
}
int updatedLabels = otherOutboundMapper.updateInventoryStatus(labelCodes, "已出库", site, buNo);
if (updatedLabels != labelCodes.size()) {
throw new RuntimeException("部分标签状态更新失败");
}
// 2. 检查是否所有标签都已出库决定是否更新出库单状态
Map<String, Object> labelStats = otherOutboundMapper.checkAllLabelsOutbound(outboundNo, site, buNo);
if (labelStats != null) {
Integer totalLabels = (Integer) labelStats.get("totalLabels");
Integer outboundLabels = (Integer) labelStats.get("outboundLabels");
logger.info("出库单 {} 标签统计: 总标签数={}, 已出库标签数={}", outboundNo, totalLabels, outboundLabels);
// 只有当所有标签都已出库时才更新出库单状态为"已完成"
if (totalLabels != null && outboundLabels != null && totalLabels.equals(outboundLabels) && totalLabels > 0) {
int updatedHead = otherOutboundMapper.updateOutboundStatus(outboundNo, "已完成", site, buNo);
if (updatedHead > 0) {
logger.info("出库单 {} 所有标签已出库,状态更新为已完成", outboundNo);
}
} else {
logger.info("出库单 {} 还有标签未出库,保持待出库状态", outboundNo);
}
}
// 3. 生成出库事务记录
generateOutboundTransaction(outboundNo, warehouseId, labels, site);
// 4. 异步调用ERP接口这里可以发送消息到队列
//asyncCallErpInterface(outboundNo, labels);
logger.info("其他出库确认完成,出库单号: {}", outboundNo);
return true;
} catch (Exception e) {
logger.error("其他出库确认失败,出库单号: {}, 错误信息: {}", outboundNo, e.getMessage(), e);
throw new RuntimeException("出库确认失败: " + e.getMessage(), e);
}
}
@Override
public List<Map<String, Object>> getMaterialList(String site, String buNo, String outboundNo) {
logger.info("获取其他出库物料清单,站点: {}, 业务单元: {}, 出库单号: {}", site, buNo, outboundNo);
try {
List<Map<String, Object>> materialList = otherOutboundMapper.getMaterialList(site, buNo, outboundNo);
if (materialList == null) {
materialList = new ArrayList<>();
}
logger.info("获取其他出库物料清单成功,站点: {}, 业务单元: {}, 出库单号: {}, 记录数: {}",
site, buNo, outboundNo, materialList.size());
return materialList;
} catch (Exception e) {
logger.error("获取其他出库物料清单失败,站点: {}, 业务单元: {}, 出库单号: {}, 错误信息: {}",
site, buNo, outboundNo, e.getMessage(), e);
throw new RuntimeException("获取物料清单失败: " + e.getMessage(), e);
}
}
/**
* 生成出库事务记录
*/
private void generateOutboundTransaction(String outboundNo, String warehouseId, List<Map<String, Object>> labels, String site) {
logger.info("开始生成出库事务记录,出库单号: {}", outboundNo);
// 构建TransDetailDto对象
TransDetailDto transDetailDto = new TransDetailDto();
transDetailDto.setSite(site); // 站点
transDetailDto.setRemark("其他出库 - " + outboundNo);
transDetailDto.setOrderref1(outboundNo); // 出库单号
transDetailDto.setOrderref3(warehouseId); // 仓库ID
// 使用TransHeaderService的genTrans方法生成事务头
TransHeader transHeader = transHeaderService.genTrans(transDetailDto, "OUT", warehouseId);
if (transHeader == null) {
throw new RuntimeException("生成事务头记录失败");
}
logger.info("事务头记录生成成功,事务单号: {}", transHeader.getTransno());
// 生成事务明细记录
generateTransactionDetails(transHeader.getTransno(), labels, site);
logger.info("出库事务记录生成完成,事务单号: {}, 出库单号: {}, 明细记录数: {}",
transHeader.getTransno(), outboundNo, labels.size());
}
/**
* 生成事务明细记录
*/
private void generateTransactionDetails(String transNo, List<Map<String, Object>> labels, String site) {
logger.info("开始生成事务明细记录,事务单号: {}, 明细数量: {}", transNo, labels.size());
List<TransDetail> transDetailList = new ArrayList<>();
double itemNo = 1.0; // 行号从1开始
for (Map<String, Object> label : labels) {
String labelCode = (String) label.get("labelCode");
Object quantityObj = label.get("quantity");
String batchNo = (String) label.get("batchNo");
String partNo = (String) label.get("partNo");
// 转换数量
BigDecimal quantity = BigDecimal.ZERO;
if (quantityObj != null) {
if (quantityObj instanceof BigDecimal) {
quantity = (BigDecimal) quantityObj;
} else if (quantityObj instanceof Number) {
quantity = new BigDecimal(quantityObj.toString());
} else {
quantity = new BigDecimal(quantityObj.toString());
}
}
// 构建事务明细记录
TransDetail transDetail = new TransDetail();
transDetail.setSite(site); // 站点
transDetail.setTransno(transNo);
transDetail.setItemno(itemNo);
transDetail.setPartno(partNo);
transDetail.setTransqty(quantity);
transDetail.setBatchno(batchNo);
transDetail.setDirection("-"); // 出库方向
transDetail.setOrderref1(labelCode); // 标签条码
transDetail.setOrderref2(partNo); // 物料编码
transDetail.setOrderref3(batchNo); // 批次号
transDetail.setRemark("其他出库 - 标签: " + labelCode);
transDetailList.add(transDetail);
itemNo += 1.0; // 行号递增
}
// 批量保存事务明细记录
if (!transDetailList.isEmpty()) {
boolean success = transDetailService.saveBatch(transDetailList);
if (!success) {
throw new RuntimeException("事务明细记录保存失败");
}
logger.info("事务明细记录生成成功,共生成 {} 条明细记录", transDetailList.size());
}
}
}

140
src/main/resources/mapper/otherOutbound/OtherOutboundMapper.xml

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gaotao.modules.otherOutbound.dao.OtherOutboundMapper">
<!-- 获取其他出库单列表 -->
<select id="getOutboundList" resultType="java.util.Map">
SELECT
h.order_no AS outboundNo,
h.bu_no AS buNo,
h.related_order_no AS relatedNo,
h.related_order_line_no AS relatedLineNo,
0 as totalLabels,
0 as availableLabels,
SUM(CAST(d.required_qty AS float)) as totalQty,
0 as availableQty
FROM outbound_notification_head h
INNER JOIN outbound_notification_detail d ON h.order_no = d.order_no AND h.site = d.site
WHERE h.site = #{site}
AND h.order_type = '其他出库'
AND h.close_flag = 'N'
AND h.order_status = #{status}
AND h.out_warehouse = #{warehouseId}
<if test="searchCode != null and searchCode != ''">
AND (
h.order_no LIKE CONCAT('%', #{searchCode}, '%')
OR h.related_order_no LIKE CONCAT('%', #{searchCode}, '%')
)
</if>
<if test="searchCode == null or searchCode == ''">
AND CONVERT(DATE, h.required_outbound_date) = CONVERT(DATE, GETDATE())
</if>
GROUP BY h.order_no, h.bu_no, h.related_order_no, h.related_order_line_no, h.required_outbound_date
ORDER BY h.required_outbound_date DESC
</select>
<!-- 获取其他出库单详情 -->
<select id="getOutboundDetails" resultType="java.util.Map">
SELECT
h.order_no AS outboundNo,
h.site AS site,
h.bu_no AS buNo,
h.related_order_no AS relatedNo,
h.related_order_line_no AS relatedLineNo,
0 as totalLabels,
0 as availableLabels,
SUM(CAST(d.required_qty AS float)) as totalQty,
0 as availableQty
FROM outbound_notification_head h
INNER JOIN outbound_notification_detail d ON h.order_no = d.order_no AND h.site = d.site
WHERE h.order_no = #{outboundNo}
AND h.site = #{site}
AND h.bu_no = #{buNo}
AND h.out_warehouse = #{warehouseId}
AND h.order_type = '其他出库'
GROUP BY h.order_no, h.site, h.bu_no, h.related_order_no, h.related_order_line_no, h.required_outbound_date
</select>
<!-- 验证标签与其他出库单是否匹配 -->
<select id="validateLabelWithOutbound" resultType="java.util.Map">
SELECT
inv.roll_no AS labelCode,
inv.part_no AS partNo,
inv.qty_on_hand AS quantity,
inv.batch_no AS batchNo,
inv.status AS status,
inv.warehouse_id AS warehouseId,
inv.location_id AS locationId
FROM inventory_stock inv
INNER JOIN outbound_notification_detail d ON inv.part_no = d.part_no
INNER JOIN outbound_notification_head h ON d.order_no = h.order_no AND d.site = h.site
WHERE inv.roll_no = #{labelCode}
AND h.order_no = #{outboundNo}
AND inv.warehouse_id = #{warehouseId}
AND inv.site = #{site}
AND inv.bu_no = #{buNo}
AND h.order_type = '其他出库'
AND inv.status = '在库'
AND inv.qty_on_hand > 0
</select>
<!-- 更新库存表中的标签状态 -->
<update id="updateInventoryStatus">
UPDATE inventory_stock
SET status = #{status},
updated_date = GETDATE(),
updated_by = 'SYSTEM'
WHERE roll_no IN
<foreach collection="labelCodes" item="labelCode" open="(" separator="," close=")">
#{labelCode}
</foreach>
AND site = #{site}
AND bu_no = #{buNo}
</update>
<!-- 更新出库单状态 -->
<update id="updateOutboundStatus">
UPDATE outbound_notification_head
SET order_status = #{status},
updated_date = GETDATE(),
updated_by = 'SYSTEM'
WHERE order_no = #{outboundNo}
AND site = #{site}
AND bu_no = #{buNo}
AND order_type = '其他出库'
</update>
<!-- 检查出库单的所有标签是否都已出库 -->
<select id="checkAllLabelsOutbound" resultType="java.util.Map">
SELECT
COUNT(DISTINCT inv.roll_no) AS totalLabels,
SUM(CASE WHEN inv.status = '已出库' THEN 1 ELSE 0 END) AS outboundLabels
FROM outbound_notification_head h
INNER JOIN outbound_notification_detail d ON h.order_no = d.order_no AND h.site = d.site
LEFT JOIN inventory_stock inv ON d.part_no = inv.part_no
AND h.out_warehouse = inv.warehouse_id
AND h.site = inv.site
WHERE h.order_no = #{outboundNo}
AND h.site = #{site}
AND h.bu_no = #{buNo}
AND h.order_type = '其他出库'
</select>
<!-- 获取其他出库单物料清单 -->
<select id="getMaterialList" resultType="java.util.Map">
SELECT
d.part_no AS materialCode,
d.part_desc AS partDesc,
d.required_qty AS requiredQty,
SUM(CASE WHEN inv.status = '在库' THEN inv.qty_on_hand ELSE 0 END) AS availableQty
FROM outbound_notification_detail d
LEFT JOIN inventory_stock inv ON d.part_no = inv.part_no
AND d.site = inv.site
WHERE d.site = #{site}
AND d.bu_no = #{buNo}
AND d.order_no = #{outboundNo}
GROUP BY d.part_no, d.part_desc, d.required_qty
</select>
</mapper>
Loading…
Cancel
Save