Compare commits

...

3 Commits

Author SHA1 Message Date
曹鹏飞 4b5f2d1864 Merge branch 'feature/bug-841' into develop 2025-11-25 15:17:44 +08:00
曹鹏飞 efdccae817 feat: bug-841 钢结构订单批量导入功能及非采购订单关联的订单 2025-11-25 15:17:23 +08:00
曹鹏飞 08066941c8 feat: 一些优化 2025-11-25 13:53:40 +08:00
4 changed files with 196 additions and 181 deletions

View File

@ -2,7 +2,6 @@ package com.nflg.wms.admin.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
@ -52,7 +51,6 @@ import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
@ -73,8 +71,6 @@ import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.stream.Collectors;
@ -122,9 +118,6 @@ public class StructuralPackageOrderController extends BaseController {
@Resource
private IUserSupplierService userSupplierService;
@Resource
private IWmsStorageService storageService;
@Resource
private BinService binService;
@ -140,179 +133,6 @@ public class StructuralPackageOrderController extends BaseController {
@Resource
private IWmsWorkbenchService workbenchService;
/**
* 导出订单创建模板
*/
@GetMapping("exportOrderTemplate")
public void exportOrderTemplate(HttpServletResponse response) throws IOException {
List<Map<String, Object>> datas = new LinkedList<>();
Map<String, Object> map = new LinkedHashMap<>();
map.put("*钢构包料号", "必填");
map.put("*供应商编号", "必填");
map.put("*机型", "必填");
map.put("*机台序号", "必填");
map.put("*期望交期", "必填,格式2025-10-01");
map.put("采购单号", "");
map.put("采购单行号", "");
map.put("数量", "");
datas.add(map);
EecExcelUtil.eecExcel("钢构件订单创建模板", new ListMapSheet<>(datas), response);
}
/**
* 导入订单创建数据
* @param file excel文件
* @response {@link List<StructuralPackageOrderImportDTO>}
*/
@PostMapping(value = "importForOrder")
public ApiResult importForOrder(HttpServletResponse response, @RequestParam(name = "file") MultipartFile file) throws IOException {
List<StructuralPackageOrderImportDTO> datas = new ArrayList<>();
List<Map<String, Object>> maps = EecExcelUtil.handlerExcel(file.getInputStream());
maps.forEach(map -> {
StructuralPackageOrderImportDTO dto = new StructuralPackageOrderImportDTO();
StringBuilder sb = new StringBuilder();
String data = StrUtil.trim(map.get("*钢构包料号").toString());
if (StrUtil.isBlank(data)) {
sb.append("钢构包料号不能为空;");
} else {
PackageVO packageVO = structuralPackageService.getCurrent(data);
if (Objects.isNull(packageVO)) {
sb.append("钢构包不存在;");
} else {
dto.setMaterialNo(data);
dto.setPackageId(packageVO.getId());
}
}
data = StrUtil.trim(map.get("*供应商编号").toString());
if (StrUtil.isBlank(data)) {
sb.append("供应商编号不能为空;");
} else {
UserSupplier supplier = userSupplierService.getByCode(data);
if (Objects.isNull(supplier)) {
sb.append("供应商不存在;");
} else {
dto.setSupplierId(supplier.getId());
dto.setSupplierCode(supplier.getSupplierCode());
dto.setSupplierName(supplier.getSupplierName());
}
}
data = StrUtil.trim(map.get("*机型").toString());
if (StrUtil.isBlank(data)) {
sb.append("机型不能为空;");
} else {
WmsModel model = modelService.lambdaQuery().eq(WmsModel::getNo, data).eq(WmsModel::getEnable, true).one();
if (Objects.isNull(model)) {
sb.append("机型不存在;");
} else {
dto.setModelId(model.getId());
dto.setModelNo(model.getNo());
}
}
data = StrUtil.trim(map.get("*机台序号").toString());
if (StrUtil.isBlank(data)) {
sb.append("机台序号不能为空;");
} else {
WmsWorkbench workbench = workbenchService.lambdaQuery().eq(WmsWorkbench::getNo, data).eq(WmsWorkbench::getEnable, true).one();
if (Objects.isNull(workbench)) {
sb.append("机台不存在;");
} else {
dto.setWorkbenchId(workbench.getId());
dto.setWorkbenchNo(workbench.getNo());
}
}
data = StrUtil.trim(map.get("*期望交期").toString());
if (StrUtil.isBlank(data)) {
sb.append("期望交期不能为空;");
} else {
try {
if (data.contains(" ")) {
data = data.split(" ")[0];
}
LocalDate date = LocalDate.parse(data, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
dto.setDeliveryDate(LocalDateTimeUtil.formatNormal(date));
} catch (DateTimeParseException e) {
log.error("期望交期格式错误", e);
map.put("*期望交期", data);
sb.append("期望交期格式错误;");
}
}
if (StrUtil.isBlank(sb.toString())) {
data = StrUtil.trim(map.get("采购单号").toString());
if (StrUtil.isNotBlank(data)) {
try {
List<SAPMaterialInfoInOrderDTO> orders = sapService.zim004(data, dto.getSupplierCode(), dto.getMaterialNo());
if (CollectionUtil.isEmpty(orders)) {
sb.append("采购单号无效;");
} else {
dto.setExternalOrderNo(data);
data = getData(map, "采购单行号");
if (StrUtil.isNotBlank(data)) {
String finalData = data;
SAPMaterialInfoInOrderDTO order = orders.stream()
.filter(it -> StrUtil.equals(it.getEbelp(), finalData))
.findFirst()
.orElse(null);
if (Objects.isNull(order)) {
sb.append("采购单行号无效;");
} else {
dto.setRowNo(data);
data = getData(map, "数量");
if (StrUtil.isNotBlank(data)) {
if (!NumberUtils.isCreatable(data)) {
sb.append("数量无效;");
} else {
BigDecimal num = new BigDecimal(data);
if (order.getTransportNum().compareTo(num) < 0) {
sb.append("数量不能大于未收货数量(").append(order.getTransportNum()).append(");");
} else {
dto.setNum(num);
}
}
}
}
}
}
} catch (NflgException e) {
sb.append(e.getMsg()).append(";");
}
}
}
if (StrUtil.isBlank(sb.toString())) {
datas.add(dto);
} else {
map.put("错误信息", sb.toString());
}
});
if (datas.size() != maps.size()) {
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(getResultName(file.getOriginalFilename()), StandardCharsets.UTF_8));
try (ByteArrayOutputStream osOut = new ByteArrayOutputStream()) {
new Workbook()
.addSheet(new ListMapSheet<>(maps))
.writeTo(osOut);
try (ByteArrayInputStream isIn = new ByteArrayInputStream(osOut.toByteArray())) {
return ApiResult.error(STATE.DataNoCheckPass, "导入文件失败"
, fileUploadService.upload("temp/" + DateTimeUtil.format(LocalDate.now(), "yyyyMMdd") + "/" + IdUtil.fastUUID() + ".xlsx"
, isIn
, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
}
} catch (Exception e) {
return ApiResult.error(STATE.BusinessError, "保存文件出错");
}
} else {
return ApiResult.success(datas);
}
}
private String getData(Map<String, Object> map, String key) {
return StrUtil.trim(Optional.ofNullable(map.get(key)).orElse("").toString());
}
private String getResultName(String name) {
int index = name.lastIndexOf(".");
return name.substring(0, index) + "_结果" + "." + name.substring(index + 1);
}
/**
* 搜索SAP订单
* @param request 请求参数
@ -1103,4 +923,176 @@ public class StructuralPackageOrderController extends BaseController {
public ApiResult<List<WmsInTaskItem>> getTicketItems(@Valid @RequestParam @NotBlank String taskNo) {
return ApiResult.success(inTaskItemService.getByNo(taskNo));
}
/**
* 导出钢构件订单导入模板
*/
@PostMapping("exportTemplate")
public void exportTemplate(HttpServletResponse response) throws IOException {
Map<String, Object> datas = new LinkedHashMap<>();
datas.put("供应商编码*", "必填");
datas.put("机型*", "必填");
datas.put("机台序号*", "必填");
datas.put("钢构包物料*", "必填");
datas.put("期望交期", "不填为今天格式2025-10-05");
datas.put("采购订单号*", "必填");
datas.put("行项目*", "0010");
datas.put("数量*", "必填");
EecExcelUtil.eecExcel("钢构件订单导入模板", new ListMapSheet<>(List.of(datas)), response);
}
/**
* 导入钢构件订单
* @response {@link List<StructuralPackageOrderImportDTO>}
*/
@PostMapping("importOrder")
public ApiResult importOrder(MultipartFile file) throws IOException {
List<Map<String, Object>> datas = EecExcelUtil.handlerExcel(file.getInputStream());
List<StructuralPackageOrderImportDTO> list = new ArrayList<>();
StringBuilder sb = new StringBuilder();
datas.forEach(data -> {
sb.setLength(0);
String supplierCode = StrUtil.trim(data.get("供应商编码*").toString());
Long supplierId = null;
if (StrUtil.isBlank(supplierCode)) {
sb.append("供应商编码不能为空;");
} else {
UserSupplier supplier = userSupplierService.getByCode(supplierCode);
if (Objects.isNull(supplier)) {
sb.append("供应商编码无效;");
} else {
supplierId = supplier.getId();
}
}
String modelNo = StrUtil.trim(data.get("机型*").toString());
Long modelId = null;
if (StrUtil.isBlank(modelNo)) {
sb.append("机型不能为空;");
} else {
WmsModel model = modelService.lambdaQuery()
.eq(WmsModel::getEnable, true)
.eq(WmsModel::getNo, modelNo)
.one();
if (Objects.isNull(model)) {
sb.append("机型无效;");
} else {
modelId = model.getId();
}
}
String workbenchNo = StrUtil.trim(data.get("机台序号*").toString());
Long workbenchId = null;
if (StrUtil.isBlank(workbenchNo)) {
sb.append("机台序号不能为空;");
} else {
WmsWorkbench workbench = workbenchService.lambdaQuery()
.eq(WmsWorkbench::getEnable, true)
.eq(WmsWorkbench::getNo, workbenchNo)
.one();
if (Objects.isNull(workbench)) {
sb.append("机台序号无效;");
} else {
workbenchId = workbench.getId();
}
}
String materialNo = StrUtil.trim(data.get("钢构包物料*").toString());
Long materialId = null;
if (StrUtil.isBlank(materialNo)) {
sb.append("钢构包物料不能为空;");
} else {
PackageVO packageVO = structuralPackageService.getCurrent(materialNo);
if (Objects.isNull(packageVO)) {
sb.append("钢构包物料无效;");
} else {
materialId = packageVO.getId();
}
}
String expectDeliveryDate = StrUtil.trim(data.get("期望交期").toString());
if (StrUtil.isBlank(expectDeliveryDate)) {
expectDeliveryDate = DateTimeUtil.format(LocalDate.now(), "yyyy-MM-dd");
} else if (!DateTimeUtil.isValidDate(expectDeliveryDate)) {
sb.append("期望交期无效;");
}
String rowNo = StrUtil.trim(data.get("行项目*").toString());
if (StrUtil.isBlank(rowNo)) {
sb.append("行项目不能为空;");
}
String snum = StrUtil.trim(data.get("数量*").toString());
BigDecimal num = null;
if (StrUtil.isBlank(snum)) {
sb.append("数量不能为空;");
} else if (!NumberUtil.isNumber(snum)) {
sb.append("数量无效;");
} else {
num = new BigDecimal(snum);
if (num.compareTo(BigDecimal.ZERO) <= 0) {
sb.append("数量必须大于0;");
}
}
String poNum = StrUtil.trim(data.get("采购订单号*").toString());
BigDecimal transportNum = num;
if (StrUtil.isBlank(poNum)) {
sb.append("采购订单号不能为空;");
} else {
if (sb.isEmpty() && poNum.startsWith("75")) {
try {
List<SAPMaterialInfoInOrderDTO> orders = sapService.zim004(poNum, supplierCode, materialNo);
if (CollectionUtil.isEmpty(orders)) {
sb.append("采购订单号无效;");
} else {
SAPMaterialInfoInOrderDTO order = orders.stream()
.filter(it -> StrUtil.equals(it.getEbelp(), rowNo))
.findFirst()
.orElse(null);
if (Objects.isNull(order)) {
sb.append("行项目无效;");
} else {
transportNum = order.getTransportNum();
if (transportNum.compareTo(num) < 0) {
sb.append("数量不能大于未收货数量(").append(transportNum).append(");");
}
}
}
} catch (NflgException e) {
sb.append(e.getMsg()).append(";");
}
}
}
if (sb.isEmpty()) {
list.add(new StructuralPackageOrderImportDTO()
.setSupplierCode(supplierCode)
.setSupplierId(supplierId)
.setModelId(modelId)
.setModelNo(modelNo)
.setWorkbenchId(workbenchId)
.setWorkbenchNo(workbenchNo)
.setPackageId(materialId)
.setMaterialNo(materialNo)
.setDeliveryDate(expectDeliveryDate)
.setExternalOrderNo(poNum)
.setRowNo(rowNo)
.setNum(num)
.setTransportNum(transportNum)
);
} else {
data.put("错误信息", sb.toString());
}
});
if (list.size() != datas.size()) {
try (ByteArrayOutputStream osOut = new ByteArrayOutputStream()) {
new Workbook()
.addSheet(new ListMapSheet<>(datas))
.writeTo(osOut);
try (ByteArrayInputStream isIn = new ByteArrayInputStream(osOut.toByteArray())) {
return ApiResult.error(STATE.DataNoCheckPass, "导入文件失败", fileUploadService.upload("temp/" + DateTimeUtil.format(LocalDate.now(), "yyyyMMdd") + "/" + IdUtil.fastUUID() + ".xlsx", isIn, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
}
} catch (Exception e) {
return ApiResult.error(STATE.BusinessError, "保存文件出错");
}
} else {
list.forEach(item -> {
item.setTray(generateTray(item.getPackageId(), item.getNum(), item.getTransportNum()));
});
return ApiResult.success(list);
}
}
}

View File

@ -1,10 +1,13 @@
package com.nflg.wms.admin.pojo.dto;
import com.nflg.wms.common.pojo.vo.GenerateTrayVO;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
@Data
@Accessors(chain = true)
public class StructuralPackageOrderImportDTO {
/**
@ -71,4 +74,14 @@ public class StructuralPackageOrderImportDTO {
* 数量
*/
private BigDecimal num;
/**
* 未收货数量
*/
private BigDecimal transportNum;
/**
* 托盘信息
*/
private GenerateTrayVO tray;
}

View File

@ -10,6 +10,7 @@ import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Objects;
public class DateTimeUtil {
@ -83,4 +84,13 @@ public class DateTimeUtil {
}
return LocalDateTimeUtil.format(LocalDateTimeUtil.of(Long.parseLong(millis)), format);
}
public static boolean isValidDate(String date) {
try {
LocalDate.parse(date, FORMATTER_DATE);
return true;
} catch (DateTimeParseException e) {
return false;
}
}
}

View File

@ -240,7 +240,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<version>3.5.2</version>
<configuration>
<includes>
<include>**/**.java</include>