oms出入库预约单导入接口开发;
This commit is contained in:
@@ -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";
|
||||
/**
|
||||
|
||||
+11
-4
@@ -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();
|
||||
|
||||
+89
@@ -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);
|
||||
}
|
||||
}
|
||||
+20
@@ -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);
|
||||
}
|
||||
}
|
||||
+2
@@ -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);
|
||||
|
||||
+49
@@ -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 格式
|
||||
}
|
||||
}
|
||||
+79
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
+125
@@ -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("验证通过");
|
||||
}
|
||||
}
|
||||
+103
@@ -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 → Excel(3.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("");
|
||||
}
|
||||
}
|
||||
+135
@@ -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;
|
||||
}
|
||||
}
|
||||
+71
@@ -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;
|
||||
}
|
||||
+129
-4
@@ -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;
|
||||
}
|
||||
}
|
||||
+31
-26
@@ -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
|
||||
|
||||
+89
@@ -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);
|
||||
}
|
||||
}
|
||||
+20
@@ -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);
|
||||
}
|
||||
}
|
||||
+78
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
+73
@@ -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("验证通过");
|
||||
}
|
||||
}
|
||||
+104
@@ -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 → Excel(3.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("");
|
||||
}
|
||||
}
|
||||
+40
@@ -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;
|
||||
}
|
||||
+121
-4
@@ -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;
|
||||
}
|
||||
}
|
||||
+24
-4
@@ -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
|
||||
|
||||
+49
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -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>
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+8
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user