oms出入库预约单导入接口开发;

This commit is contained in:
王奎兴
2026-05-14 17:55:14 +08:00
parent 89a1eb13cc
commit 3a6cefa0f6
26 changed files with 1504 additions and 45 deletions
@@ -22,7 +22,7 @@ public class MinIoUploadService {
private MinioClient minioClient;
private static String bucket="ngwl";
private static String host="http://10.102.192.5:6000";
private static String host="http://127.0.0.1:6000";
private static String accessKey="minioadmin";
private static String secretKey="gmminioadmin";
/**
@@ -125,12 +125,19 @@ public class ReservationMaterialInventoryImpl extends ServiceImpl<ReservationMat
String batchNumber = materialInventoryOmsParamDO.getBatchNumber();
Long materialBaseInfoId = materialInventoryOmsParamDO.getMaterialBaseInfoId();
Long warehouseId = materialInventoryOmsParamDO.getWarehouseId();
List<ReservationMaterialInventory> reservationMaterialInventories = materialInventoryMapper.selectList(new LambdaQueryWrapper<ReservationMaterialInventory>()
LambdaQueryWrapper<ReservationMaterialInventory> param = new LambdaQueryWrapper<ReservationMaterialInventory>()
.eq(ReservationMaterialInventory::getInOrderNumber, inOrderNumber)
.eq(ReservationMaterialInventory::getLotNumber, lotNumber)
.eq(ReservationMaterialInventory::getBatchNumber, batchNumber)
//.eq(ReservationMaterialInventory::getLotNumber, lotNumber)
//.eq(ReservationMaterialInventory::getBatchNumber, batchNumber)
.eq(ReservationMaterialInventory::getMaterialBaseInfoId, materialBaseInfoId)
.eq(ReservationMaterialInventory::getWarehouseId, warehouseId));
.eq(ReservationMaterialInventory::getWarehouseId, warehouseId);
if(lotNumber != null && !lotNumber.isEmpty()) {
param.eq(ReservationMaterialInventory::getLotNumber, lotNumber);
}
if (batchNumber != null && !batchNumber.isEmpty()) {
param.eq(ReservationMaterialInventory::getBatchNumber, batchNumber);
}
List<ReservationMaterialInventory> reservationMaterialInventories = materialInventoryMapper.selectList(param);
if (reservationMaterialInventories != null && reservationMaterialInventories.size() > 0) {
ReservationMaterialInventory reservationMaterialInventory = reservationMaterialInventories.get(0);
Long materialInventoryId = reservationMaterialInventory.getMaterialInventoryId();
@@ -0,0 +1,89 @@
package com.mhd.oms.domain.reserveStockInOrder.repository.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.mhd.oms.domain.reserveStockInOrder.repository.util.ExcelParseUtil;
import com.mhd.oms.domain.reserveStockInOrder.repository.vo.ReservedInventory;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
public class ReservedInventoryListener implements ReadListener<ReservedInventory> {
private static final Logger log = LoggerFactory.getLogger(ReservedInventoryListener.class);
@Getter
private final List<ReservedInventory> dataList = new ArrayList<>();
private static final int BATCH_SIZE = 100;
@Override
public void invoke(ReservedInventory data, AnalysisContext context) {
// 1. 获取当前行号(关键:EasyExcel 3.2.1 中 rowIndex 从0开始,需+1转为实际行号)
long currentRowNum = context.readRowHolder().getRowIndex() + 1;
log.info("读取第{}行数据:{}", currentRowNum, data);
// 2. 核心过滤:仅保留 >= 数据起始行(第4行)的数据
if (currentRowNum < ExcelParseUtil.TemplateConfig.DATA_START_ROW) {
log.info("第{}行(说明行/表头行),跳过解析", currentRowNum);
return;
}
// 3. 过滤说明文本行(双重保障,避免极端情况)
if (isRemarkRow(data)) {
log.info("第{}行包含说明文本(如'保質到哪一天的日期'),跳过解析", currentRowNum);
return;
}
// 4. 过滤空行,保留有效数据
if (isValidDataRow(data)) {
dataList.add(data);
// 批量处理逻辑不变
if (dataList.size() >= BATCH_SIZE) {
log.info("已读取{}条数据,执行批量处理", BATCH_SIZE);
dataList.clear();
}
}
}
/**
* 判断是否为说明文本行(精准匹配“保質到哪一天的日期”等关键词)
*/
private boolean isRemarkRow(ReservedInventory data) {
if (data == null) {
return false;
}
// 匹配说明行特征:货物名称为提示文本,或保质期/件数均为空
boolean isGoodsNameRemark = data.getGoodsName() != null &&
(data.getGoodsName().contains("请输入") || data.getGoodsName().contains("保質到哪一天的日期"));
boolean isEmptyRow = data.getQuantity() == null && data.getShelfLife() == null;
return isGoodsNameRemark || isEmptyRow;
}
/**
* 判断是否为有效数据行(至少一个必填字段有值)
*/
private boolean isValidDataRow(ReservedInventory data) {
if (data == null) {
return false;
}
return (data.getGoodsName() != null && !data.getGoodsName().trim().isEmpty())
|| data.getQuantity() != null
|| data.getShelfLife() != null;
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
log.info("Excel数据读取完成,共读取{}条有效数据", dataList.size());
}
/**
* 可选:提前判断是否需要继续读取(优化性能)
*/
@Override
public boolean hasNext(AnalysisContext context) {
// 无需特殊处理,返回true即可
return ReadListener.super.hasNext(context);
}
}
@@ -0,0 +1,20 @@
package com.mhd.oms.domain.reserveStockInOrder.repository.listener;
/**
* 数据验证异常
* 用于Excel导入数据验证失败场景
*/
public class ValidationException extends RuntimeException {
public ValidationException() {
super();
}
public ValidationException(String message) {
super(message);
}
public ValidationException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -31,6 +31,8 @@ public interface ReserveStockInOrderMapper extends BaseMapper<ReserveStockInOrde
public MaterialBaseInfoPO getinfo(@Param("id") Long id);
public List<MaterialBaseInfoPO> getByName(@Param("name") String name);
public List<MaterialBaseInfoPO> getMaterialBaseInfoList(@Param("id") String id);
public MaterialWarehouseControlPO getInfoByMaterialBaseInfoIds(@Param("id") Long id);
@@ -0,0 +1,49 @@
package com.mhd.oms.domain.reserveStockInOrder.repository.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* 日期工具类:统一日期格式处理
*/
public class DateUtils {
// 支持的日期格式(与自定义转换器一致)
public static final SimpleDateFormat[] DATE_FORMATS = {
new SimpleDateFormat("yyyy/M/d HH:mm:ss", Locale.CHINA),
new SimpleDateFormat("yyyy/M/d", Locale.CHINA),
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA),
new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
};
/**
* 字符串转Date(复用转换器逻辑)
*/
public static Date strToDate(String dateStr) throws ParseException {
if (dateStr == null || dateStr.trim().isEmpty()) {
return null;
}
dateStr = dateStr.replaceAll("\\s+", ""); // 清洗空格
for (SimpleDateFormat format : DATE_FORMATS) {
try {
format.setLenient(false);
return format.parse(dateStr);
} catch (ParseException e) {
continue;
}
}
throw new ParseException("日期格式不支持:" + dateStr, 0);
}
/**
* Date转字符串
*/
public static String dateToStr(Date date) {
if (date == null) {
return "";
}
return DATE_FORMATS[0].format(date); // 统一输出为 2023/12/9 12:20:30 格式
}
}
@@ -0,0 +1,79 @@
package com.mhd.oms.domain.reserveStockInOrder.repository.util;
import com.alibaba.excel.EasyExcel;
import com.mhd.oms.domain.reserveStockInOrder.repository.listener.ReservedInventoryListener;
import com.mhd.oms.domain.reserveStockInOrder.repository.vo.ReservedInventory;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* Excel解析工具类
* 提供Excel文件验证和数据解析功能
*/
public class ExcelParseUtil {
/**
* Excel模板常量配置
*/
public static final class TemplateConfig {
// 表头行号(从1开始)
public static final int HEADER_ROW_NUM = 2;
// 数据起始行号(从1开始)
public static final int DATA_START_ROW = 4;
public static final int RELATIVE_HEAD_ROW = 2; // 相对表头的偏移量(表头行+2行=数据行)
// 工作表名称
public static final String SHEET_NAME = "Sheet1";
// 最大文件大小(10MB
public static final long MAX_FILE_SIZE = 100 * 1024 * 1024;
}
/**
* 解析Excel文件为实体类列表
* @param file 上传的Excel文件
* @return 解析并验证后的实体类列表
* @throws IOException 文件处理异常
*/
public static List<ReservedInventory> parseExcel(MultipartFile file) throws IOException {
// 1. 验证文件格式和大小
validateFile(file);
// 2. 读取Excel数据
ReservedInventoryListener listener = new ReservedInventoryListener();
try (InputStream inputStream = file.getInputStream()) {
EasyExcel.read(inputStream, ReservedInventory.class, listener)
.sheet(TemplateConfig.SHEET_NAME) // 指定工作表
.headRowNumber(TemplateConfig.HEADER_ROW_NUM) // 指定表头行
.doRead(); // 执行读取
}
// 3. 数据验证
List<ReservedInventory> dataList = listener.getDataList();
ReservedInventoryValidator.validateAll(dataList, TemplateConfig.DATA_START_ROW);
return dataList;
}
/**
* 验证Excel文件合法性
*/
private static void validateFile(MultipartFile file) throws IOException {
// 验证文件不为空
if (file.isEmpty()) {
throw new IOException("上传的Excel文件不能为空");
}
// 验证文件后缀
String fileName = file.getOriginalFilename();
if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) {
throw new IOException("请上传Excel格式文件(.xlsx或.xls");
}
// 验证文件大小
if (file.getSize() > TemplateConfig.MAX_FILE_SIZE) {
throw new IOException("文件大小不能超过10MB");
}
}
}
@@ -0,0 +1,125 @@
package com.mhd.oms.domain.reserveStockInOrder.repository.util;
import com.mhd.oms.domain.reserveStockInOrder.repository.listener.ValidationException;
import com.mhd.oms.domain.reserveStockInOrder.repository.vo.ReservedInventory;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
* 预约存货数据验证器
* 实现数据合法性校验
*/
public class ReservedInventoryValidator {
// 保持与转换器一致的格式,用于二次校验
private static final SimpleDateFormat[] VALIDATE_FORMATS = {
new SimpleDateFormat("yyyy/M/d HH:mm:ss", Locale.CHINA),
new SimpleDateFormat("yyyy/M/d", Locale.CHINA),
new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.CHINA),
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA),
new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
};
static {
// 所有格式均开启严格校验
for (SimpleDateFormat format : VALIDATE_FORMATS) {
format.setLenient(false);
}
}
/**
* 批量验证数据列表
* @param dataList 待验证数据
* @param startRow 数据起始行号(用于错误定位)
*/
public static void validateAll(List<ReservedInventory> dataList, int startRow) {
if (dataList == null || dataList.isEmpty()) {
throw new ValidationException("待验证的数据列表为空");
}
List<String> errorList = new ArrayList<>();
// 逐条验证
for (int i = 0; i < dataList.size(); i++) {
ReservedInventory data = dataList.get(i);
int rowNum = startRow + i; // 计算当前数据在Excel中的行号
try {
validateSingle(data, rowNum);
} catch (ValidationException e) {
errorList.add(e.getMessage());
// 设置验证结果到实体类
data.setValidationResult(e.getMessage());
}
}
// 汇总错误信息
if (!errorList.isEmpty()) {
throw new ValidationException("Excel数据验证失败:\n" + String.join("\n", errorList));
}
}
/**
* 单个数据验证
*/
private static void validateSingle(ReservedInventory data, int rowNum) {
List<String> errors = new ArrayList<>();
// 1. 必填项验证
if (data.getGoodsName() == null || data.getGoodsName().trim().isEmpty()) {
errors.add(String.format("第%d行:货物名称为必填项", rowNum));
}
if (data.getQuantity() == null) {
errors.add(String.format("第%d行:件数为必填项", rowNum));
} else if (data.getQuantity().compareTo(BigDecimal.ZERO) < 0) {
errors.add(String.format("第%d行:件数必须为正整数(当前值:%d)", rowNum, data.getQuantity()));
}
// 保质期验证:更新错误提示
Date shelfLife = data.getShelfLife();
if (shelfLife == null) {
errors.add(String.format("第%d行:保质期为必填项,请填写格式如 2023/12/9 12:20:30", rowNum));
} else {
// 二次校验日期合法性(避免转换器未覆盖的异常)
boolean isValid = false;
String dateStr = null;
for (SimpleDateFormat format : VALIDATE_FORMATS) {
try {
dateStr = format.format(shelfLife);
format.parse(dateStr);
isValid = true;
break;
} catch (ParseException e) {
continue;
}
}
if (!isValid) {
errors.add(String.format("第%d行:保质期格式非法,支持 2023/12/9 12:20:30 或 2023-12-09 18:30:30(当前值:%s",
rowNum, dateStr));
}
// 保质期不能早于当前日期
if (shelfLife.before(new Date())) {
SimpleDateFormat showFormat = new SimpleDateFormat("yyyy/M/d HH:mm:ss", Locale.CHINA);
errors.add(String.format("第%d行:保质期不能早于当前日期(当前值:%s)",
rowNum, showFormat.format(shelfLife)));
}
}
if (data.getOperationType() == null || !"新增".equals(data.getOperationType().trim())) {
errors.add(String.format("第%d行:操作类型必须为'新增'(当前值:%s", rowNum, data.getOperationType()));
}
// 2. 可选字段验证(重量非负)
if (data.getWeight() != null && data.getWeight().compareTo(BigDecimal.ZERO) < 0) {
errors.add(String.format("第%d行:重量不能为负数(当前值:%s)", rowNum, data.getWeight()));
}
// 抛出验证错误
if (!errors.isEmpty()) {
throw new ValidationException(String.join("", errors));
}
// 验证通过
data.setValidationResult("验证通过");
}
}
@@ -0,0 +1,103 @@
package com.mhd.oms.domain.reserveStockInOrder.repository.util;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.math.BigDecimal;
import java.util.regex.Pattern;
/**
* EasyExcel 3.2.1 适配版:字符串转BigDecimal转换器
* 解决WriteCellData实例化爆红问题
*/
public class StringToBigDecimalConverter implements Converter<BigDecimal> {
// 正则表达式:清洗非数字字符(保留小数点)
private static final Pattern NUMBER_PATTERN = Pattern.compile("[^0-9.]");
/**
* 支持的Java类型(BigDecimal
*/
@Override
public Class<BigDecimal> supportJavaTypeKey() {
return BigDecimal.class;
}
/**
* 支持的Excel单元格类型(文本+数值)
*/
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING; // 覆盖文本和数值类型转换
}
/**
* 导入:Excel → Java(逻辑不变,确保件数正确转换)
*/
@Override
public BigDecimal convertToJavaData(
ReadCellData<?> cellData,
ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
// 1. 获取并清洗单元格数据
String cellValue = getCleanedCellValue(cellData);
if (cellValue == null || cellValue.isEmpty()) {
return null;
}
// 2. 转换为BigDecimal(处理格式异常)
try {
return new BigDecimal(cellValue);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
String.format("单元格数据[%s]无法转换为数字,请检查格式", cellValue), e);
}
}
/**
* 导出:Java → Excel3.2.1版本适配核心)
* 关键:使用构造方法直接实例化,不依赖Builder
*/
@Override
public WriteCellData<?> convertToExcelData(
BigDecimal value,
ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
// 1. 处理空值:返回空字符串单元格
if (value == null) {
WriteCellData<String> emptyData = new WriteCellData<>("");
emptyData.setType(CellDataTypeEnum.STRING); // 明确指定文本类型
return emptyData;
}
// 2. 处理非空值:BigDecimal转字符串后写入
String valueStr = value.toString();
WriteCellData<String> cellData = new WriteCellData<>(valueStr);
cellData.setType(CellDataTypeEnum.STRING); // 明确数据类型,避免自动转换异常
return cellData;
}
/**
* 辅助方法:获取并清洗单元格数据(处理文本/数值型)
*/
private String getCleanedCellValue(ReadCellData<?> cellData) {
String rawValue = null;
// 根据单元格类型获取原始值
if (cellData.getType() == CellDataTypeEnum.STRING) {
rawValue = cellData.getStringValue().trim();
} else if (cellData.getType() == CellDataTypeEnum.NUMBER) {
rawValue = cellData.getNumberValue().toString().trim();
}
// 清洗非数字字符(如"5件"→"5"" 10.5 "→"10.5"
if (rawValue == null) {
return null;
}
return NUMBER_PATTERN.matcher(rawValue).replaceAll("");
}
}
@@ -0,0 +1,135 @@
package com.mhd.oms.domain.reserveStockInOrder.repository.util;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* 适配 2023/12/9 12:20:30 格式的日期转换器
* 支持斜杠分隔、无补零日期/月份
*/
public class StringToDateConverter implements Converter<Date> {
// 核心修改:新增斜杠无补零格式,放在优先匹配位置
private static final SimpleDateFormat[] DATE_FORMATS = {
// 1. 目标格式:2023/12/9 12:20:30(斜杠、无补零)
new SimpleDateFormat("yyyy/M/d HH:mm:ss", Locale.CHINA),
// 2. 简化格式:2023/12/9(斜杠、无补零)
new SimpleDateFormat("yyyy/M/d", Locale.CHINA),
// 3. 原支持格式:2023-12-09 18:30:30(横杠、有补零)
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA),
// 4. 原支持格式:2023-12-09(横杠、有补零)
new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA),
// 5. 兼容格式:2023/12/09 12:20:30(斜杠、有补零)
new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.CHINA),
// 6. 兼容格式:2023/12/09(斜杠、有补零)
new SimpleDateFormat("yyyy/MM/dd", Locale.CHINA)
};
@Override
public Class<Date> supportJavaTypeKey() {
return Date.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING; // 支持文本型单元格(实际使用格式)
}
/**
* 导入解析:重点处理 2023/12/9 12:20:30 格式
*/
@Override
public Date convertToJavaData(
ReadCellData<?> cellData,
ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
// 1. 获取并清洗单元格数据(去除空格、换行等干扰字符)
String cellValue = getCleanedDateValue(cellData);
if (cellValue == null || cellValue.trim().isEmpty()) {
return null;
}
// 2. 按优先级尝试匹配格式(优先匹配目标格式)
for (SimpleDateFormat format : DATE_FORMATS) {
try {
format.setLenient(false); // 严格校验(避免 2023/02/30 等非法日期)
return format.parse(cellValue.trim());
} catch (ParseException e) {
continue; // 格式不匹配,尝试下一种
}
}
// 3. 所有格式匹配失败,抛出明确异常
// throw new IllegalArgumentException(
// String.format("单元格数据[%s]无法转换为日期,请使用格式:2023/12/9 12:20:30 或 2023-12-09 18:30:30", cellValue));
return null;
}
/**
* 导出:保持与导入格式一致(2023/12/9 12:20:30
*/
@Override
public WriteCellData<?> convertToExcelData(
Date value,
ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
if (value == null) {
WriteCellData<String> emptyData = new WriteCellData<>("");
emptyData.setType(CellDataTypeEnum.STRING);
return emptyData;
}
// 导出格式与导入目标格式一致:2023/12/9 12:20:30
SimpleDateFormat targetFormat = new SimpleDateFormat("yyyy/M/d HH:mm:ss", Locale.CHINA);
String dateStr = targetFormat.format(value);
WriteCellData<String> cellData = new WriteCellData<>(dateStr);
cellData.setType(CellDataTypeEnum.STRING);
return cellData;
}
/**
* 辅助方法:清洗单元格数据(处理文本型)
*/
private String getCleanedDateValue(ReadCellData<?> cellData) {
if (cellData.getType() == CellDataTypeEnum.STRING) {
// 去除空格、制表符、换行符等干扰字符
return cellData.getStringValue().replaceAll("\\s+", "");
} else if (cellData.getType() == CellDataTypeEnum.NUMBER) {
// 兼容数值型日期(如 Excel 序列号 45235
BigDecimal numberValue = cellData.getNumberValue();
double v = numberValue.doubleValue();
Date date = convertExcelDateToDate(v);
return getStringDate(date);
}
return null;
}
public static Date convertExcelDateToDate(double excelDateValue) {
// Excel 的时间起始点是 1900年1月1日,但有一个需要修正的bug:Excel 误把1900年当作闰年
// 简单处理下,减去2天(1天是起始偏移,1天是闰年bug)
int startDay = 25569; // 1970-01-01 对应的Excel序列号
return new Date((long) ((excelDateValue - startDay) * 86400000));
}
public String getStringDate(Date date) {
// 创建日期格式化对象,指定格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
// 将 Date 转换为 String
String dateString = sdf.format(date);
return dateString;
}
}
@@ -0,0 +1,71 @@
package com.mhd.oms.domain.reserveStockInOrder.repository.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.mhd.oms.domain.reserveStockInOrder.repository.util.StringToBigDecimalConverter;
import com.mhd.oms.domain.reserveStockInOrder.repository.util.StringToDateConverter;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 预约存货实体类
* 与Excel模板字段一一映射
*/
@Data
public class ReservedInventory {
/**
* 货物名称(必填)
* index=2:对应Excel第3列(从0开始计数)
*/
@ExcelProperty(index = 2, value = "貨物名稱")
private String goodsName;
/**
* 件数(改为BigDecimal类型,添加自定义转换器)
* converter:指定自定义转换器处理类型转换
*/
@ExcelProperty(
index = 3,
value = "件數",
converter = StringToBigDecimalConverter.class // 关键:自定义转换器
)
private BigDecimal quantity;
/**
* 保质期(支持 2023/12/9 12:20:30 格式)
* 已引用修改后的 StringToDateConverter
*/
@ExcelProperty(
index = 4,
value = "保質期",
converter = StringToDateConverter.class // 关键:确保引用正确
)
private Date shelfLife;
/**
* 重量(可选)
*/
@ExcelProperty(index = 5, value = "重量",
converter = StringToBigDecimalConverter.class
)
private BigDecimal weight;
/**
* 备注(可选)
*/
@ExcelProperty(index = 6, value = "備註")
private String remarks;
/**
* 操作类型(必填)
*/
@ExcelProperty(index = 7, value = "操作")
private String operationType;
/**
* 验证结果(导入后自动填充,不映射Excel)
*/
private String validationResult;
}
@@ -7,16 +7,26 @@ import com.alibaba.fastjson2.JSONObject;
import com.mhd.common.core.domain.po.UserPo;
import com.mhd.common.core.enums.DictCode;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.utils.OrderSequence;
import com.mhd.common.core.utils.StringUtils;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.oms.domain.reservationMaterialInventory.repository.mapper.ReservationMaterialInventoryMapper;
import com.mhd.oms.domain.reservationMaterialInventory.repository.todo.MaterialBaseInfo;
import com.mhd.oms.domain.reservationStockInOrder.repository.po.MaterialBaseInfoPO;
import com.mhd.oms.domain.reserveInMaterialDetail.entity.ReserveInMaterialDetail;
import com.mhd.oms.domain.reserveInMaterialDetail.repository.po.ReserveInMaterialDetailPO;
import com.mhd.oms.domain.reserveInMaterialDetail.repository.todo.ReserveInMaterialDetailDO;
import com.mhd.oms.domain.reserveStockInOrder.entity.ReserveStockInOrder;
import com.mhd.oms.domain.reserveStockInOrder.repository.mapper.ReserveStockInOrderMapper;
import com.mhd.oms.domain.reserveStockInOrder.repository.po.ReserveStockInOrderPO;
import com.mhd.oms.domain.reserveStockInOrder.repository.todo.ReserveStockInOrderDO;
import com.mhd.oms.domain.reserveStockInOrder.repository.todo.ReserveStockInOrderDTO;
import com.mhd.oms.domain.reserveStockInOrder.repository.vo.InAndOutListVo;
import com.mhd.oms.domain.reserveStockInOrder.repository.vo.ReservedInventory;
import com.mhd.system.api.SystemServiceFeign;
import com.mhd.system.api.UserServiceFeign;
import com.mhd.system.api.WmsServiceFeign;
import com.mhd.system.api.domain.InMaterialDetailTZPD;
import com.mhd.system.api.domain.StockInOrderTZPD;
import com.mhd.system.api.domain.SysDictData;
@@ -31,12 +41,13 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
/**
* 入库单ApplicationService
@@ -50,9 +61,15 @@ public class ReserveStockInOrderApplicationService {
@Autowired
private ReserveStockInOrderDomainService stockInOrderDomainService;
@Autowired
private ReserveStockInOrderMapper reserveStockInOrderMapper;
@Autowired
private ReservationMaterialInventoryMapper reservationMaterialInventoryMapper;
@Autowired
private UserServiceFeign userServiceFeign;
@Autowired
private SystemServiceFeign systemServiceFeign;
@Autowired
private WmsServiceFeign wmsServiceFeign;
// @Autowired
// private IMaterialBaseInfoService materialBaseInfoService;
@@ -1978,4 +1995,112 @@ public class ReserveStockInOrderApplicationService {
BeanUtils.copyProperties(stockInOrderDTO, stockInOrderDO);
return stockInOrderDomainService.queryNoticePrintDetail(stockInOrderDO);
}
public void importInData(List<ReservedInventory> dataList) {
LoginUser loginUser = SecurityUtils.getLoginUser();
ReserveStockInOrderDO reserveStockInOrder = new ReserveStockInOrderDO();
reserveStockInOrder.setBusinessOrderNo(generateDateTimeWithRandom());
reserveStockInOrder.setIssueStatus(0);
reserveStockInOrder.setDocumentDate(new Date());
reserveStockInOrder.setExpectTime(new Date());
reserveStockInOrder.setOrderStatus("新增");
reserveStockInOrder.setNeedTransport(0);
reserveStockInOrder.setNeedCustomsDeclaration(0);
if (loginUser != null){
Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId();
if (topOrganizationId != null && topOrganizationId != 1){
reserveStockInOrder.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
reserveStockInOrder.setOrganizationId(loginUser.getUserPo().getOrganizationId());
reserveStockInOrder.setOrganizationName(loginUser.getUserPo().getOrganizationName());
reserveStockInOrder.setShipperId(loginUser.getUserPo().getUserId());
reserveStockInOrder.setShipperName(loginUser.getUserPo().getUserName());
reserveStockInOrder.setSalesmanId(loginUser.getUserPo().getUserId().toString());
reserveStockInOrder.setSalesmanName(loginUser.getUserPo().getUserName());
reserveStockInOrder.setCustomerId(loginUser.getUserPo().getUserId());
reserveStockInOrder.setCustomerName(loginUser.getUserPo().getUserName());
reserveStockInOrder.setDocumentCreator(loginUser.getUserPo().getUserName());
reserveStockInOrder.setCreateTime(new Date());
reserveStockInOrder.setCreateBy(loginUser.getUserPo().getUserId());
reserveStockInOrder.setCreateByName(loginUser.getUserPo().getUserName());
}
}
List<ReserveInMaterialDetailDO> reserveInMaterialDetailDOList = new ArrayList<>();
int index = 1;
for (ReservedInventory reservedInventory : dataList) {
ReserveInMaterialDetailDO reserveInMaterialDetail = new ReserveInMaterialDetailDO();
BigDecimal quantity = reservedInventory.getQuantity();
String goodsName = reservedInventory.getGoodsName();
String remarks = reservedInventory.getRemarks();
Date shelfLife = reservedInventory.getShelfLife();
BigDecimal weight = reservedInventory.getWeight();
List<MaterialBaseInfoPO> materialBaseInfoPOS = reserveStockInOrderMapper.getByName(goodsName);
if (materialBaseInfoPOS != null&&materialBaseInfoPOS.size()>0) {
MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoPOS.get(0);
Long materialBaseInfoId = materialBaseInfoPO.getMaterialBaseInfoId();
String materialCode = materialBaseInfoPO.getMaterialCode();
reserveInMaterialDetail.setMaterialBaseInfoId(materialBaseInfoId);
reserveInMaterialDetail.setMaterialCode(materialCode);
reserveInMaterialDetail.setUnitCode(materialBaseInfoPO.getUnitCode());
reserveInMaterialDetail.setUnitName(materialBaseInfoPO.getUnitName());
} else {
throw new ServiceException(goodsName + "未找到对应物料");
}
reserveInMaterialDetail.setMaterialName(goodsName);
reserveInMaterialDetail.setRemark(remarks);
reserveInMaterialDetail.setShelfLife(shelfLife);
reserveInMaterialDetail.setQuantity(quantity);
reserveInMaterialDetail.setReserveQuantity(quantity);
reserveInMaterialDetail.setTotalNetWeight(weight);
reserveInMaterialDetail.setTotalGrossWeight(weight);
reserveInMaterialDetail.setContractFee(BigDecimal.ZERO);
//reserveInMaterialDetail.setInOrderNumber(OrderSequence.getOrderCode("RK"));
String lot = generateDateSerialNumber();
lot = lot+"-"+index;
index++;
reserveInMaterialDetail.setLotNo(lot);
if (loginUser != null){
Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId();
if (topOrganizationId != null && topOrganizationId != 1){
reserveInMaterialDetail.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
reserveInMaterialDetail.setOrganizationId(loginUser.getUserPo().getOrganizationId());
reserveInMaterialDetail.setOrganizationName(loginUser.getUserPo().getOrganizationName());
reserveInMaterialDetail.setCreateTime(new Date());
reserveInMaterialDetail.setCreateBy(loginUser.getUserPo().getUserId());
reserveInMaterialDetail.setCreateByName(loginUser.getUserPo().getUserName());
}
}
reserveInMaterialDetailDOList.add(reserveInMaterialDetail);
}
reserveStockInOrder.setMaterialDetailList(reserveInMaterialDetailDOList);
insert(reserveStockInOrder);
}
public static String generateDateTimeWithRandom() {
// 1. 获取当前时间,格式化:yyMMddHHmmss
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHHmmss");
String dateTimePart = now.format(formatter);
// 2. 生成四位随机数 (1000-9999,保证四位,不足补零)
int randomNum = ThreadLocalRandom.current().nextInt(1000, 10000);
String randomPart = String.valueOf(randomNum);
// 3. 拼接返回
return dateTimePart + randomPart;
}
public String generateDateSerialNumber() {
// 1. 获取当前时间,格式化为:yyMMdd (2位年+2位月+2位日)
SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
String datePart = sdf.format(new Date());
// 2. 生成 000~999 的 3 位随机数(不足补零)
Random random = new Random();
int randomNum = random.nextInt(1000); // 0~999
String randomPart = String.format("%03d", randomNum); // 自动补前导零
// 3. 拼接结果
return datePart + randomPart;
}
}
@@ -46,10 +46,8 @@ import org.springframework.util.CollectionUtils;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 入库单
@@ -106,16 +104,16 @@ public class ReserveStockInOrderDomainService {
// //设置物料信息
// setMaterialDetailInfo(stockInOrderDO);
// //统计总物料种数
// stockInOrderDO.setMaterialQuantity(stockInOrderDO.getMaterialDetailList().size());
stockInOrderDO.setMaterialQuantity(stockInOrderDO.getMaterialDetailList().size());
// //统计总计划数
BigDecimal quantity = stockInOrderDO.getMaterialDetailList().stream().map(ReserveInMaterialDetailDO::getQuantity).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
stockInOrderDO.setQuantity(quantity);
// //统计总重量
// BigDecimal weightLimit = stockInOrderDO.getMaterialDetailList().stream().map(ReserveInMaterialDetailDO::getWeightLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
// stockInOrderDO.setWeightLimit(weightLimit);
// //统计总体积
// BigDecimal volumeLimit = stockInOrderDO.getMaterialDetailList().stream().map(ReserveInMaterialDetailDO::getVolumeLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
// stockInOrderDO.setVolumeLimit(volumeLimit);
//统计总重量
BigDecimal weightLimit = stockInOrderDO.getMaterialDetailList().stream().map(ReserveInMaterialDetailDO::getWeightLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
stockInOrderDO.setWeightLimit(weightLimit);
//统计总体积
BigDecimal volumeLimit = stockInOrderDO.getMaterialDetailList().stream().map(ReserveInMaterialDetailDO::getVolumeLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
stockInOrderDO.setVolumeLimit(volumeLimit);
stockInOrderService.insert(stockInOrderDO);
return materialDetailService.batchInsert(stockInOrderDO.getInOrderNumber(), stockInOrderDO.getMaterialDetailList());
}
@@ -174,21 +172,6 @@ public class ReserveStockInOrderDomainService {
ReserveInMaterialDetailBaseDO inMaterialDetailBaseDO = new ReserveInMaterialDetailBaseDO();
BeanUtils.copyProperties(stockInOrderPO, inMaterialDetailBaseDO);
inMaterialDetailBaseDO.setInOrderNumber(stockInOrderPO.getInOrderNumber());
// if (stockInOrderDO.getNeedTransport() ==0) {
// List<BusinessDocumentOrder> businessDocumentOrders = businessDocumentOrderMapper.selectList(new LambdaQueryWrapper<BusinessDocumentOrder>().eq(BusinessDocumentOrder::getInOrderNumber, stockInOrderDO.getInOrderNumber()).notIn(BusinessDocumentOrder::getOrderStatus, 4, 5));
// if (businessDocumentOrders != null && businessDocumentOrders.size() > 0) {
// for (BusinessDocumentOrder businessDocumentOrder : businessDocumentOrders) {
// businessDocumentOrder.setOrderStatus(4L);
// String executeOrderNumber = businessDocumentOrder.getExecuteOrderNumber();
//
// if (executeOrderNumber !=null){
// throw new ServiceException("该业务单已生成执行单,取消失败");
// }
// businessDocumentOrderMapper.updateById(businessDocumentOrder);
// }
// }
// }
//
return materialDetailService.batchUpdate(stockInOrderDO.getMaterialDetailList(), inMaterialDetailBaseDO);
}
@@ -459,14 +442,22 @@ public class ReserveStockInOrderDomainService {
ReservationStockInOrder reservationStockInOrder = new ReservationStockInOrder();
BeanUtils.copyProperties(byId, reservationStockInOrder,"inOrderId","issueStatus","issueTime","issueId","issueName","reservationAuditId","reservationAuditName","reservationAuditTime");
reservationStockInOrder.setIssueStatus(0);
reservationStockInOrder.setOrderTypeCode("pu_tong_ru_ku");
reservationStockInOrder.setOrderTypeName("普通入库");
reservationStockInOrder.setReservationOrderSource("客户预约");
reservationStockInOrderService.save(reservationStockInOrder);
String inOrderNumber = reservationStockInOrder.getInOrderNumber();
List<ReserveInMaterialDetail> materialDetailList = materialDetailService.list(new QueryWrapper<ReserveInMaterialDetail>().lambda().eq(ReserveInMaterialDetail::getInOrderNumber, inOrderNumber));
List<ReservationInMaterialDetail> inMaterialDetailList = new ArrayList<>();
int index = 1;
for (ReserveInMaterialDetail reserveInMaterialDetail : materialDetailList) {
ReservationInMaterialDetail reservationInMaterialDetail = new ReservationInMaterialDetail();
BeanUtils.copyProperties(reserveInMaterialDetail, reservationInMaterialDetail,"materialDetailId");
reservationInMaterialDetail.setQuantity(reserveInMaterialDetail.getReserveQuantity());
String lot = generateDateSerialNumber();
lot = lot+"-"+index;
index++;
reservationInMaterialDetail.setLotNo(lot);
//reservationInMaterialDetail.set
inMaterialDetailList.add(reservationInMaterialDetail);
}
@@ -474,6 +465,20 @@ public class ReserveStockInOrderDomainService {
return update;
}
public String generateDateSerialNumber() {
// 1. 获取当前时间,格式化为:yyMMdd (2位年+2位月+2位日)
SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
String datePart = sdf.format(new Date());
// 2. 生成 000~999 的 3 位随机数(不足补零)
Random random = new Random();
int randomNum = random.nextInt(1000); // 0~999
String randomPart = String.format("%03d", randomNum); // 自动补前导零
// 3. 拼接结果
return datePart + randomPart;
}
/**
* @description 入库单返回结果
* @author ZhouGY
@@ -0,0 +1,89 @@
package com.mhd.oms.domain.reserveStockOutOrder.repository.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.mhd.oms.domain.reserveStockInOrder.repository.util.ExcelParseUtil;
import com.mhd.oms.domain.reserveStockOutOrder.repository.vo.ReservedInventoryOut;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
public class ReservedInventoryOutListener implements ReadListener<ReservedInventoryOut> {
private static final Logger log = LoggerFactory.getLogger(ReservedInventoryOutListener.class);
@Getter
private final List<ReservedInventoryOut> dataList = new ArrayList<>();
private static final int BATCH_SIZE = 100;
@Override
public void invoke(ReservedInventoryOut data, AnalysisContext context) {
// 1. 获取当前行号关键EasyExcel 3.2.1 rowIndex 从0开始+1转为实际行号
long currentRowNum = context.readRowHolder().getRowIndex() + 1;
log.info("读取第{}行数据:{}", currentRowNum, data);
// 2. 核心过滤仅保留 >= 数据起始行第4行的数据
if (currentRowNum < ExcelParseUtil.TemplateConfig.DATA_START_ROW) {
log.info("第{}行(说明行/表头行),跳过解析", currentRowNum);
return;
}
// 3. 过滤说明文本行双重保障避免极端情况
if (isRemarkRow(data)) {
log.info("第{}行包含说明文本(如'保質到哪一天的日期'),跳过解析", currentRowNum);
return;
}
// 4. 过滤空行保留有效数据
if (isValidDataRow(data)) {
dataList.add(data);
// 批量处理逻辑不变
if (dataList.size() >= BATCH_SIZE) {
log.info("已读取{}条数据,执行批量处理", BATCH_SIZE);
dataList.clear();
}
}
}
/**
* 判断是否为说明文本行精准匹配保質到哪一天的日期等关键词
*/
private boolean isRemarkRow(ReservedInventoryOut data) {
if (data == null) {
return false;
}
// 匹配说明行特征货物名称为提示文本或保质期/件数均为空
boolean isGoodsNameRemark = data.getGoodsName() != null &&
(data.getGoodsName().contains("请输入") || data.getGoodsName().contains("保質到哪一天的日期"));
//boolean isEmptyRow = data.getQuantity() == null && data.getShelfLife() == null;
return isGoodsNameRemark;
}
/**
* 判断是否为有效数据行至少一个必填字段有值
*/
private boolean isValidDataRow(ReservedInventoryOut data) {
if (data == null) {
return false;
}
return (data.getGoodsName() != null && !data.getGoodsName().trim().isEmpty())
|| data.getQuantity() != null;
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
log.info("Excel数据读取完成,共读取{}条有效数据", dataList.size());
}
/**
* 可选提前判断是否需要继续读取优化性能
*/
@Override
public boolean hasNext(AnalysisContext context) {
// 无需特殊处理返回true即可
return ReadListener.super.hasNext(context);
}
}
@@ -0,0 +1,20 @@
package com.mhd.oms.domain.reserveStockOutOrder.repository.listener;
/**
* 数据验证异常
* 用于Excel导入数据验证失败场景
*/
public class ValidationException extends RuntimeException {
public ValidationException() {
super();
}
public ValidationException(String message) {
super(message);
}
public ValidationException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,78 @@
package com.mhd.oms.domain.reserveStockOutOrder.repository.util;
import com.alibaba.excel.EasyExcel;
import com.mhd.oms.domain.reserveStockOutOrder.repository.listener.ReservedInventoryOutListener;
import com.mhd.oms.domain.reserveStockOutOrder.repository.vo.ReservedInventoryOut;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* Excel解析工具类
* 提供Excel文件验证和数据解析功能
*/
public class ExcelParseUtil {
/**
* Excel模板常量配置
*/
public static final class TemplateConfig {
// 表头行号从1开始
public static final int HEADER_ROW_NUM = 2;
// 数据起始行号从1开始
public static final int DATA_START_ROW = 4;
// 工作表名称
public static final String SHEET_NAME = "Sheet1";
// 最大文件大小10MB
public static final long MAX_FILE_SIZE = 100 * 1024 * 1024;
}
/**
* 解析Excel文件为实体类列表
* @param file 上传的Excel文件
* @return 解析并验证后的实体类列表
* @throws IOException 文件处理异常
*/
public static List<ReservedInventoryOut> parseExcel(MultipartFile file) throws IOException {
// 1. 验证文件格式和大小
validateFile(file);
// 2. 读取Excel数据
ReservedInventoryOutListener listener = new ReservedInventoryOutListener();
try (InputStream inputStream = file.getInputStream()) {
EasyExcel.read(inputStream, ReservedInventoryOut.class, listener)
.sheet(TemplateConfig.SHEET_NAME) // 指定工作表
.headRowNumber(TemplateConfig.HEADER_ROW_NUM) // 指定表头行
.doRead(); // 执行读取
}
// 3. 数据验证
List<ReservedInventoryOut> dataList = listener.getDataList();
ReservedInventoryOutValidator.validateAll(dataList, TemplateConfig.DATA_START_ROW);
return dataList;
}
/**
* 验证Excel文件合法性
*/
private static void validateFile(MultipartFile file) throws IOException {
// 验证文件不为空
if (file.isEmpty()) {
throw new IOException("上传的Excel文件不能为空");
}
// 验证文件后缀
String fileName = file.getOriginalFilename();
if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) {
throw new IOException("请上传Excel格式文件(.xlsx或.xls");
}
// 验证文件大小
if (file.getSize() > TemplateConfig.MAX_FILE_SIZE) {
throw new IOException("文件大小不能超过10MB");
}
}
}
@@ -0,0 +1,73 @@
package com.mhd.oms.domain.reserveStockOutOrder.repository.util;
import com.mhd.oms.domain.reserveStockInOrder.repository.listener.ValidationException;
import com.mhd.oms.domain.reserveStockOutOrder.repository.vo.ReservedInventoryOut;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
* 预约存货数据验证器
* 实现数据合法性校验
*/
public class ReservedInventoryOutValidator {
/**
* 批量验证数据列表
* @param dataList 待验证数据
* @param startRow 数据起始行号用于错误定位
*/
public static void validateAll(List<ReservedInventoryOut> dataList, int startRow) {
if (dataList == null || dataList.isEmpty()) {
throw new ValidationException("待验证的数据列表为空");
}
List<String> errorList = new ArrayList<>();
// 逐条验证
for (int i = 0; i < dataList.size(); i++) {
ReservedInventoryOut data = dataList.get(i);
int rowNum = startRow + i; // 计算当前数据在Excel中的行号
try {
validateSingle(data, rowNum);
} catch (ValidationException e) {
errorList.add(e.getMessage());
// 设置验证结果到实体类
data.setValidationResult(e.getMessage());
}
}
// 汇总错误信息
if (!errorList.isEmpty()) {
throw new ValidationException("Excel数据验证失败:\n" + String.join("\n", errorList));
}
}
/**
* 单个数据验证
*/
private static void validateSingle(ReservedInventoryOut data, int rowNum) {
List<String> errors = new ArrayList<>();
// 1. 必填项验证
if (data.getGoodsName() == null || data.getGoodsName().trim().isEmpty()) {
errors.add(String.format("第%d行:货物名称为必填项", rowNum));
}
if (data.getQuantity() == null) {
errors.add(String.format("第%d行:件数为必填项", rowNum));
} else if (data.getQuantity().compareTo(BigDecimal.ZERO) < 0) {
errors.add(String.format("第%d行:件数必须为正整数(当前值:%d)", rowNum, data.getQuantity()));
}
// 抛出验证错误
if (!errors.isEmpty()) {
throw new ValidationException(String.join("", errors));
}
// 验证通过
data.setValidationResult("验证通过");
}
}
@@ -0,0 +1,104 @@
package com.mhd.oms.domain.reserveStockOutOrder.repository.util;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.math.BigDecimal;
import java.util.regex.Pattern;
/**
* EasyExcel 3.2.1 适配版字符串转BigDecimal转换器
* 解决WriteCellData实例化爆红问题
*/
public class StringToBigDecimalConverter implements Converter<BigDecimal> {
// 正则表达式清洗非数字字符保留小数点
private static final Pattern NUMBER_PATTERN = Pattern.compile("[^0-9.]");
/**
* 支持的Java类型BigDecimal
*/
@Override
public Class<BigDecimal> supportJavaTypeKey() {
return BigDecimal.class;
}
/**
* 支持的Excel单元格类型文本+数值
*/
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING; // 覆盖文本和数值类型转换
}
/**
* 导入Excel Java逻辑不变确保件数正确转换
*/
@Override
public BigDecimal convertToJavaData(
ReadCellData<?> cellData,
ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
// 1. 获取并清洗单元格数据
String cellValue = getCleanedCellValue(cellData);
if (cellValue == null || cellValue.isEmpty()) {
return null;
}
// 2. 转换为BigDecimal处理格式异常
try {
return new BigDecimal(cellValue);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
String.format("单元格数据[%s]无法转换为数字,请检查格式", cellValue), e);
}
}
/**
* 导出Java Excel3.2.1版本适配核心
* 关键使用构造方法直接实例化不依赖Builder
*/
@Override
public WriteCellData<?> convertToExcelData(
BigDecimal value,
ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
// 1. 处理空值返回空字符串单元格
if (value == null) {
WriteCellData<String> emptyData = new WriteCellData<>("");
emptyData.setType(CellDataTypeEnum.STRING); // 明确指定文本类型
return emptyData;
}
// 2. 处理非空值BigDecimal转字符串后写入
String valueStr = value.toString();
WriteCellData<String> cellData = new WriteCellData<>(valueStr);
cellData.setType(CellDataTypeEnum.STRING); // 明确数据类型避免自动转换异常
return cellData;
}
/**
* 辅助方法获取并清洗单元格数据处理文本/数值型
*/
private String getCleanedCellValue(ReadCellData<?> cellData) {
String rawValue = null;
// 根据单元格类型获取原始值
if (cellData.getType() == CellDataTypeEnum.STRING) {
rawValue = cellData.getStringValue().trim();
} else if (cellData.getType() == CellDataTypeEnum.NUMBER) {
rawValue = cellData.getNumberValue().toString().trim();
}
// 清洗非数字字符"5件""5"" 10.5 ""10.5"
if (rawValue == null) {
return null;
}
return NUMBER_PATTERN.matcher(rawValue).replaceAll("");
}
}
@@ -0,0 +1,40 @@
package com.mhd.oms.domain.reserveStockOutOrder.repository.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.mhd.oms.domain.reserveStockInOrder.repository.util.StringToBigDecimalConverter;
import com.mhd.oms.domain.reserveStockInOrder.repository.util.StringToDateConverter;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 预约存货实体类
* 与Excel模板字段一一映射
*/
@Data
public class ReservedInventoryOut {
/**
* 货物名称必填
* index=2对应Excel第3列从0开始计数
*/
@ExcelProperty(index = 2, value = "貨物名稱")
private String goodsName;
/**
* 件数改为BigDecimal类型添加自定义转换器
* converter指定自定义转换器处理类型转换
*/
@ExcelProperty(
index = 3,
value = "件數",
converter = StringToBigDecimalConverter.class // 关键自定义转换器
)
private BigDecimal quantity;
/**
* 验证结果导入后自动填充不映射Excel
*/
private String validationResult;
}
@@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mhd.common.core.domain.po.UserPo;
import com.mhd.common.core.enums.DictCode;
import com.mhd.common.core.exception.ServiceException;
@@ -13,15 +14,22 @@ import com.mhd.common.core.utils.uuid.IdGenerator;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.oms.domain.reservationInMaterialDetail.repository.todo.InventoryAdjustmentRecordPO;
import com.mhd.oms.domain.reservationMaterialInventory.entity.ReservationMaterialInventory;
import com.mhd.oms.domain.reservationMaterialInventory.repository.mapper.ReservationMaterialInventoryMapper;
import com.mhd.oms.domain.reservationStockInOrder.repository.po.MaterialBaseInfoPO;
import com.mhd.oms.domain.reserveInMaterialDetail.repository.facade.IReserveInMaterialDetailService;
import com.mhd.oms.domain.reserveInMaterialDetail.repository.todo.ReserveInMaterialDetailDO;
import com.mhd.oms.domain.reserveOutMaterialDetail.repository.facade.IReserveOutMaterialDetailService;
import com.mhd.oms.domain.reserveOutMaterialDetail.repository.po.ReserveOutMaterialDetailPO;
import com.mhd.oms.domain.reserveOutMaterialDetail.repository.todo.ReserveOutMaterialDetailDO;
import com.mhd.oms.domain.reserveStockInOrder.repository.mapper.ReserveStockInOrderMapper;
import com.mhd.oms.domain.reserveStockInOrder.repository.todo.ReserveStockInOrderDO;
import com.mhd.oms.domain.reserveStockInOrder.repository.vo.ReservedInventory;
import com.mhd.oms.domain.reserveStockOutOrder.repository.facade.IReserveStockOutOrderService;
import com.mhd.oms.domain.reserveStockOutOrder.repository.po.ReserveStockOutOrderPO;
import com.mhd.oms.domain.reserveStockOutOrder.repository.todo.ReserveStockOutOrderDO;
import com.mhd.oms.domain.reserveStockOutOrder.repository.todo.ReserveStockOutOrderDTO;
import com.mhd.oms.domain.reserveStockOutOrder.repository.vo.ReservedInventoryOut;
import com.mhd.system.api.SystemServiceFeign;
import com.mhd.system.api.UserServiceFeign;
import com.mhd.system.api.domain.*;
@@ -34,10 +42,10 @@ import org.springframework.util.CollectionUtils;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
/**
* 出库单ApplicationService
@@ -56,6 +64,10 @@ public class ReserveStockOutOrderApplicationService {
// private MaterialInventoryDomainService materialInventoryDomainService;
// @Autowired
// private MaterialInventoryMapper materialInventoryMapper;
@Autowired
private ReserveStockInOrderMapper reserveStockInOrderMapper;
@Autowired
private ReservationMaterialInventoryMapper reservationMaterialInventoryMapper;
@Autowired
private UserServiceFeign userServiceFeign;
@Autowired
@@ -1034,4 +1046,109 @@ public class ReserveStockOutOrderApplicationService {
BeanUtils.copyProperties(stockOutOrderDTO, stockOutOrderDO);
return stockOutOrderDomainService.queryOutStockNoticePrintDetail(stockOutOrderDO);
}
public void importInData(List<ReservedInventoryOut> dataList) {
LoginUser loginUser = SecurityUtils.getLoginUser();
ReserveStockOutOrderDO reserveStockOutOrder = new ReserveStockOutOrderDO();
reserveStockOutOrder.setBusinessOrderNo(generateDateTimeWithRandom());
reserveStockOutOrder.setIssueStatus(0);
reserveStockOutOrder.setDocumentDate(new Date());
reserveStockOutOrder.setExpectTime(new Date());
reserveStockOutOrder.setNeedDeclareFlag("0");
reserveStockOutOrder.setNeedTransportFlag("0");
reserveStockOutOrder.setOutboundDate(new Date());
//reserveStockOutOrder.setOrderStatus("新增");
if (loginUser != null){
Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId();
if (topOrganizationId != null && topOrganizationId != 1){
reserveStockOutOrder.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
reserveStockOutOrder.setOrganizationId(loginUser.getUserPo().getOrganizationId());
reserveStockOutOrder.setOrganizationName(loginUser.getUserPo().getOrganizationName());
reserveStockOutOrder.setShipperId(loginUser.getUserPo().getUserId());
reserveStockOutOrder.setShipperName(loginUser.getUserPo().getUserName());
reserveStockOutOrder.setSalesmanId(loginUser.getUserPo().getUserId().toString());
reserveStockOutOrder.setSalesmanName(loginUser.getUserPo().getUserName());
reserveStockOutOrder.setCustomerId(loginUser.getUserPo().getUserId());
reserveStockOutOrder.setCustomerName(loginUser.getUserPo().getUserName());
reserveStockOutOrder.setDocumentCreator(loginUser.getUserPo().getUserName());
reserveStockOutOrder.setCreateTime(new Date());
reserveStockOutOrder.setCreateBy(loginUser.getUserPo().getUserId());
reserveStockOutOrder.setCreateByName(loginUser.getUserPo().getUserName());
}
}
List<ReserveOutMaterialDetailDO> reserveInMaterialDetailDOList = new ArrayList<>();
int index = 1;
for (ReservedInventoryOut reservedInventory : dataList) {
ReserveOutMaterialDetailDO reserveOutMaterialDetail = new ReserveOutMaterialDetailDO();
BigDecimal quantity = reservedInventory.getQuantity();
String goodsName = reservedInventory.getGoodsName();
List<MaterialBaseInfoPO> materialBaseInfoPOS = reserveStockInOrderMapper.getByName(goodsName);
if (materialBaseInfoPOS != null&&materialBaseInfoPOS.size()>0) {
MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoPOS.get(0);
Long materialBaseInfoId = materialBaseInfoPO.getMaterialBaseInfoId();
String materialCode = materialBaseInfoPO.getMaterialCode();
reserveOutMaterialDetail.setMaterialBaseInfoId(materialBaseInfoId);
reserveOutMaterialDetail.setMaterialCode(materialCode);
List<ReservationMaterialInventory> reservationMaterialInventories = reservationMaterialInventoryMapper.selectList(new LambdaQueryWrapper<ReservationMaterialInventory>().eq(ReservationMaterialInventory::getMaterialBaseInfoId, materialBaseInfoId));
if (reservationMaterialInventories!= null && reservationMaterialInventories.size()>0) {
ReservationMaterialInventory reservationMaterialInventory = reservationMaterialInventories.get(0);
reserveOutMaterialDetail.setAllocationQuantity(reservationMaterialInventory.getAllocationQuantity());
} else {
throw new ServiceException(goodsName + "未找到对应库存");
}
} else {
throw new ServiceException(goodsName + "未找到对应物料");
}
reserveOutMaterialDetail.setMaterialName(goodsName);
reserveOutMaterialDetail.setQuantity(quantity);
reserveOutMaterialDetail.setContractFee(BigDecimal.ZERO);
String lot = generateDateSerialNumber();
lot = lot+"-"+index;
index++;
reserveOutMaterialDetail.setLotNo(lot);
if (loginUser != null){
Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId();
if (topOrganizationId != null && topOrganizationId != 1){
reserveOutMaterialDetail.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
reserveOutMaterialDetail.setOrganizationId(loginUser.getUserPo().getOrganizationId());
reserveOutMaterialDetail.setOrganizationName(loginUser.getUserPo().getOrganizationName());
reserveOutMaterialDetail.setCreateTime(new Date());
reserveOutMaterialDetail.setCreateBy(loginUser.getUserPo().getUserId());
reserveOutMaterialDetail.setCreateByName(loginUser.getUserPo().getUserName());
}
}
reserveInMaterialDetailDOList.add(reserveOutMaterialDetail);
}
reserveStockOutOrder.setMaterialDetailList(reserveInMaterialDetailDOList);
insert(reserveStockOutOrder);
}
public static String generateDateTimeWithRandom() {
// 1. 获取当前时间格式化yyMMddHHmmss
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHHmmss");
String dateTimePart = now.format(formatter);
// 2. 生成四位随机数 (1000-9999保证四位不足补零)
int randomNum = ThreadLocalRandom.current().nextInt(1000, 10000);
String randomPart = String.valueOf(randomNum);
// 3. 拼接返回
return dateTimePart + randomPart;
}
public String generateDateSerialNumber() {
// 1. 获取当前时间格式化为yyMMdd (2位年+2位月+2位日)
SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
String datePart = sdf.format(new Date());
// 2. 生成 000~999 3 位随机数不足补零
Random random = new Random();
int randomNum = random.nextInt(1000); // 0~999
String randomPart = String.format("%03d", randomNum); // 自动补前导零
// 3. 拼接结果
return datePart + randomPart;
}
}
@@ -45,10 +45,8 @@ import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 出库单
@@ -277,13 +275,21 @@ public class ReserveStockOutOrderDomainService {
ReservationStockOutOrder reservationStockOutOrder = new ReservationStockOutOrder();
BeanUtils.copyProperties(byId, reservationStockOutOrder,"outOrderId","issueStatus","issueTime","issueId","issueName","reservationAuditId","reservationAuditName","reservationAuditTime");
reservationStockOutOrder.setIssueStatus(0);
reservationStockOutOrder.setOrderTypeCode("pu_tong_chu_ku");
reservationStockOutOrder.setOrderTypeName("普通出库");
reservationStockOutOrder.setReservationOrderSource("客户预约");
reservationStockOutOrderService.save(reservationStockOutOrder);
String outOrderNumber = reservationStockOutOrder.getOutOrderNumber();
List<ReserveOutMaterialDetail> materialDetailList = outMaterialDetailService.list(new QueryWrapper<ReserveOutMaterialDetail>().lambda().eq(ReserveOutMaterialDetail::getOutOrderNumber, outOrderNumber));
List<ReservationOutMaterialDetail> inMaterialDetailList = new ArrayList<>();
int index = 1;
for (ReserveOutMaterialDetail reserveOutMaterialDetail : materialDetailList) {
ReservationOutMaterialDetail reservationOutMaterialDetail = new ReservationOutMaterialDetail();
BeanUtils.copyProperties(reserveOutMaterialDetail, reservationOutMaterialDetail,"materialDetailId");
String lot = generateDateSerialNumber();
lot = lot+"-"+index;
index++;
reservationOutMaterialDetail.setLotNo(lot);
inMaterialDetailList.add(reservationOutMaterialDetail);
}
reservationOutMaterialDetailService.saveBatch(inMaterialDetailList);
@@ -291,6 +297,20 @@ public class ReserveStockOutOrderDomainService {
return update;
}
public String generateDateSerialNumber() {
// 1. 获取当前时间格式化为yyMMdd (2位年+2位月+2位日)
SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
String datePart = sdf.format(new Date());
// 2. 生成 000~999 3 位随机数不足补零
Random random = new Random();
int randomNum = random.nextInt(1000); // 0~999
String randomPart = String.format("%03d", randomNum); // 自动补前导零
// 3. 拼接结果
return datePart + randomPart;
}
/**
* @description 审核入库单
* @author ZhouGY
@@ -5,13 +5,17 @@ import com.mhd.common.core.web.controller.BaseController;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.core.web.page.TableDataInfo;
import com.mhd.oms.domain.reserveOutMaterialDetail.repository.po.ReserveOutMaterialDetailPO;
import com.mhd.oms.domain.reserveStockInOrder.repository.listener.ValidationException;
import com.mhd.oms.domain.reserveStockInOrder.repository.todo.ReserveStockInOrderDO;
import com.mhd.oms.domain.reserveStockInOrder.repository.todo.ReserveStockInOrderDTO;
import com.mhd.oms.domain.reserveStockOutOrder.repository.util.ExcelParseUtil;
import com.mhd.oms.domain.reserveStockInOrder.repository.vo.ReservedInventory;
import com.mhd.oms.domain.reserveStockOutOrder.entity.ReserveStockOutOrder;
import com.mhd.oms.domain.reserveStockOutOrder.repository.facade.IReserveStockOutOrderService;
import com.mhd.oms.domain.reserveStockOutOrder.repository.po.ReserveStockOutOrderPO;
import com.mhd.oms.domain.reserveStockOutOrder.repository.todo.ReserveStockOutOrderDO;
import com.mhd.oms.domain.reserveStockOutOrder.repository.todo.ReserveStockOutOrderDTO;
import com.mhd.oms.domain.reserveStockOutOrder.repository.vo.ReservedInventoryOut;
import com.mhd.oms.domain.reserveStockOutOrder.service.ReserveStockOutOrderApplicationService;
import com.mhd.oms.domain.reserveStockOutOrder.service.ReserveStockOutOrderAssembler;
import com.mhd.system.api.domain.OutMaterialDetailTZPD;
@@ -19,9 +23,13 @@ import com.mhd.system.api.domain.StockOutOrderTZPD;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -231,4 +239,45 @@ public class ReserveStockOutOrderApi extends BaseController {
return AjaxResult.success(result);
}
@PostMapping("/import")
public ResponseEntity<Map<String, Object>> importExcel(@RequestParam("file") MultipartFile file) {
try {
List<ReservedInventoryOut> dataList = ExcelParseUtil.parseExcel(file);
stockOutOrderApplicationService.importInData(dataList);
Map<String, Object> successResponse = new HashMap<>();
successResponse.put("code", 200);
successResponse.put("message", "Excel导入成功");
successResponse.put("dataCount", dataList.size());
successResponse.put("details", dataList);
return ResponseEntity.ok(successResponse);
} catch (ValidationException e) {
// 数据验证失败响应
Map<String, Object> errorResponse = new HashMap<>();
errorResponse.put("code", 400);
errorResponse.put("message", "数据验证失败");
errorResponse.put("errorDetails", e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
} catch (IOException e) {
// 文件处理失败响应
Map<String, Object> errorResponse = new HashMap<>();
errorResponse.put("code", 500);
errorResponse.put("message", "文件处理失败");
errorResponse.put("errorDetails", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
} catch (Exception e) {
// 其他未知错误响应
Map<String, Object> errorResponse = new HashMap<>();
errorResponse.put("code", 500);
errorResponse.put("message", e.getMessage());
errorResponse.put("errorDetails", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
}
}
}
@@ -4,19 +4,26 @@ import com.mhd.common.core.web.controller.BaseController;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.core.web.page.TableDataInfo;
import com.mhd.oms.domain.reserveInMaterialDetail.repository.po.ReserveInMaterialDetailPO;
import com.mhd.oms.domain.reserveStockInOrder.repository.listener.ValidationException;
import com.mhd.oms.domain.reserveStockInOrder.repository.po.ReserveStockInOrderPO;
import com.mhd.oms.domain.reserveStockInOrder.repository.todo.ReserveStockInOrderDO;
import com.mhd.oms.domain.reserveStockInOrder.repository.todo.ReserveStockInOrderDTO;
import com.mhd.oms.domain.reserveStockInOrder.repository.util.ExcelParseUtil;
import com.mhd.oms.domain.reserveStockInOrder.repository.vo.InAndOutListVo;
import com.mhd.oms.domain.reserveStockInOrder.repository.vo.ReservedInventory;
import com.mhd.oms.domain.reserveStockInOrder.service.ReserveStockInOrderApplicationService;
import com.mhd.oms.domain.reserveStockInOrder.service.ReserveStockInOrderAssembler;
import com.mhd.system.api.domain.InMaterialDetailTZPD;
import com.mhd.system.api.domain.StockInOrderTZPD;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -192,4 +199,44 @@ public class ReserveStockInOrderApi extends BaseController {
return AjaxResult.success(result);
}
@PostMapping("/import")
public ResponseEntity<Map<String, Object>> importExcel(@RequestParam("file") MultipartFile file) {
try {
List<ReservedInventory> dataList = ExcelParseUtil.parseExcel(file);
stockInOrderApplicationService.importInData(dataList);
Map<String, Object> successResponse = new HashMap<>();
successResponse.put("code", 200);
successResponse.put("message", "Excel导入成功");
successResponse.put("dataCount", dataList.size());
successResponse.put("details", dataList);
return ResponseEntity.ok(successResponse);
} catch (ValidationException e) {
// 数据验证失败响应
Map<String, Object> errorResponse = new HashMap<>();
errorResponse.put("code", 400);
errorResponse.put("message", "数据验证失败");
errorResponse.put("errorDetails", e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
} catch (IOException e) {
// 文件处理失败响应
Map<String, Object> errorResponse = new HashMap<>();
errorResponse.put("code", 500);
errorResponse.put("message", "文件处理失败");
errorResponse.put("errorDetails", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
} catch (Exception e) {
// 其他未知错误响应
Map<String, Object> errorResponse = new HashMap<>();
errorResponse.put("code", 500);
errorResponse.put("message", e.getMessage());
errorResponse.put("errorDetails", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
}
}
}
@@ -562,6 +562,10 @@
<select id="getinfo" parameterType="java.lang.Long" resultType="com.mhd.oms.domain.reservationStockInOrder.repository.po.MaterialBaseInfoPO">
select * from "NGWL_TEST_WMS".MATERIAL_BASE_INFO where MATERIAL_BASE_INFO_ID = #{id}
</select>
<select id="getByName" parameterType="java.lang.String" resultType="com.mhd.oms.domain.reservationStockInOrder.repository.po.MaterialBaseInfoPO">
select * from "NGWL_TEST_WMS".MATERIAL_BASE_INFO where MATERIAL_NAME = #{name}
</select>
<select id="getMaterialBaseInfoList" parameterType="java.lang.String" resultType="com.mhd.oms.domain.reservationStockInOrder.repository.po.MaterialBaseInfoPO">
select * from "NGWL_TEST_WMS".MATERIAL_BASE_INFO where material_code = #{id}
</select>
@@ -776,7 +776,7 @@ public class MaterialInventoryImpl extends ServiceImpl<MaterialInventoryMapper,
com.mhd.system.api.domain.InventoryAdjustmentRecord inventoryAdjustmentRecordOMS = new com.mhd.system.api.domain.InventoryAdjustmentRecord();
BeanUtils.copyProperties(inventoryAdjustmentRecord, inventoryAdjustmentRecordOMS);
//推送库存调整记录到oms
omsServiceFeign.inventoryAdjustmentRecordInsert(inventoryAdjustmentRecordOMS);
//omsServiceFeign.inventoryAdjustmentRecordInsert(inventoryAdjustmentRecordOMS);
inventoryAdjustmentRecordMapper.insert(inventoryAdjustmentRecord);
}
@@ -1266,6 +1266,7 @@ public class StockShelfOrderDomainService {
BeanUtils.copyProperties(inventoryParamDO, materialInventoryOmsParamDO);
materialInventoryOmsParamDO.setKctzType("入库");
materialInventoryOmsParamDO.setLoginUser(loginUser);
materialInventoryOmsParamDO.setMaterialInventoryId(null);
omsServiceFeign.omsEdit(materialInventoryOmsParamDO);
//抄码商品对照数据插入
copyCodeProductComparison(materialBaseInfo,shelfMaterialDetail,inventoryParamDO);
@@ -1328,6 +1329,13 @@ public class StockShelfOrderDomainService {
BeanUtils.copyProperties(inventoryParamDO, materialInventoryOmsParamDO);
materialInventoryOmsParamDO.setKctzType("入库");
materialInventoryOmsParamDO.setLoginUser(loginUser);
materialInventoryOmsParamDO.setMaterialInventoryId(null);
materialInventoryOmsParamDO.setWarehouseId(shelfMaterialDetail.getWarehouseId());
materialInventoryOmsParamDO.setWarehouseName(shelfMaterialDetail.getWarehouseName());
materialInventoryOmsParamDO.setWarehouseCode(shelfMaterialDetail.getWarehouseCode());
materialInventoryOmsParamDO.setTopOrganizationId(shelfMaterialDetail.getTopOrganizationId());
materialInventoryOmsParamDO.setOrganizationId(shelfMaterialDetail.getOrganizationId());
materialInventoryOmsParamDO.setOrganizationName(shelfMaterialDetail.getOrganizationName());
omsServiceFeign.omsEdit(materialInventoryOmsParamDO);
//抄码商品对照数据插入
copyCodeProductComparison(materialBaseInfo,shelfMaterialDetail,inventoryParamDO);