Compare commits

...

2 Commits

Author SHA1 Message Date
tzy
b297a172fe feat(common): 添加 SMB 文件传输工具类
- 新增 SmbUtil 类,实现 SMB 协议的文件下载功能
- 优化 ExcelUtil 类,增加多个 Sheet 的导出方法
- 更新 BomDetailsController,改进 BOM 校验逻辑
- 调整 WxRobotUtil 类的代码格式
2025-05-20 08:48:06 +08:00
tzy
918935b13a feat(system): 新增物料BOM相关功能
- 新增物料BOM校验逻辑
- 添加货主信息更新功能
- 实现安全库存更新
- 优化物料导入导出功能
- 新增双单位支持
2025-03-20 08:41:48 +08:00
57 changed files with 3536 additions and 697 deletions

View File

@ -1,5 +1,7 @@
package com.ruoyi.common.core.domain; package com.ruoyi.common.core.domain;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
@ -27,30 +29,35 @@ public class BaseEntity implements Serializable {
*/ */
@JsonIgnore @JsonIgnore
@TableField(exist = false) @TableField(exist = false)
@ExcelIgnore
private String searchValue; private String searchValue;
/** /**
* 创建者 * 创建者
*/ */
@TableField(fill = FieldFill.INSERT) @TableField(fill = FieldFill.INSERT)
@ExcelIgnore
private String createBy; private String createBy;
/** /**
* 创建时间 * 创建时间
*/ */
@TableField(fill = FieldFill.INSERT) @TableField(fill = FieldFill.INSERT)
@ExcelIgnore
private Date createTime; private Date createTime;
/** /**
* 更新者 * 更新者
*/ */
@TableField(fill = FieldFill.INSERT_UPDATE) @TableField(fill = FieldFill.INSERT_UPDATE)
@ExcelIgnore
private String updateBy; private String updateBy;
/** /**
* 更新时间 * 更新时间
*/ */
@TableField(fill = FieldFill.INSERT_UPDATE) @TableField(fill = FieldFill.INSERT_UPDATE)
@ExcelIgnore
private Date updateTime; private Date updateTime;
/** /**
@ -58,6 +65,7 @@ public class BaseEntity implements Serializable {
*/ */
@JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonInclude(JsonInclude.Include.NON_EMPTY)
@TableField(exist = false) @TableField(exist = false)
@ExcelIgnore
private Map<String, Object> params = new HashMap<>(); private Map<String, Object> params = new HashMap<>();
} }

View File

@ -92,6 +92,11 @@ public class DefaultExcelListener<T> extends AnalysisEventListener<T> implements
} }
excelResult.getList().add(data); excelResult.getList().add(data);
} }
@Override
public boolean hasNext(AnalysisContext context) {
return super.hasNext(context);
}
@Override @Override
public void doAfterAllAnalysed(AnalysisContext context) { public void doAfterAllAnalysed(AnalysisContext context) {

View File

@ -94,19 +94,27 @@ public class WxRobotUtil {
*/ */
public void sendMarkdownMsgToWeChatGroup(String markdownMsg, String robotId) { public void sendMarkdownMsgToWeChatGroup(String markdownMsg, String robotId) {
String messageContent = markdownMsg.toString();
if (messageContent.length() > 4096) {
messageContent = messageContent.substring(0, 4096); // 截断到最大长度
}
HashMap<String, Object> paramMap = new HashMap<>(); HashMap<String, Object> paramMap = new HashMap<>();
HashMap<String, Object> markdownMap = new HashMap<>(); HashMap<String, Object> markdownMap = new HashMap<>();
markdownMap.put("content", markdownMsg); markdownMap.put("content", messageContent);
paramMap.put("msgtype", "markdown"); paramMap.put("msgtype", "markdown");
paramMap.put("markdown", markdownMap); paramMap.put("markdown", markdownMap);
String sendUrl = SEND_MESSAGE_URL + "?key=" + robotId; String sendUrl = SEND_MESSAGE_URL + "?key=" + robotId;
log.info("发送URL: {}", sendUrl);
log.info("发送参数: {}", paramMap);
ResponseEntity<Object> result = httpRequestUtil.doPost(sendUrl, paramMap); ResponseEntity<Object> result = httpRequestUtil.doPost(sendUrl, paramMap);
JSONObject dataObject = JSONObject.parseObject(JSONObject.toJSONString(result.getBody())); JSONObject dataObject = JSONObject.parseObject(JSONObject.toJSONString(result.getBody()));
Integer errcode = Integer.valueOf(dataObject.get("errcode").toString()); Integer errcode = Integer.valueOf(dataObject.get("errcode").toString());
if (errcode.equals(0)) { if (errcode.equals(0)) {
log.info("企业微信推送Markdown消息成功时间" + new Date()); log.info("企业微信推送Markdown消息成功时间" + new Date());
} else { } else {
log.error("企业微信推送Markdown消息失败时间" + new Date()); log.error("企业微信推送Markdown消息失败时间" + new Date() + ",错误信息:" + dataObject.toJSONString());
} }
} }

View File

@ -0,0 +1,143 @@
package com.ruoyi.common.utils.file;
import jcifs.CIFSContext;
import jcifs.Configuration;
import jcifs.config.PropertyConfiguration;
import jcifs.context.BaseContext;
import jcifs.smb.SmbFile;
import java.io.*;
import java.nio.file.Files;
import java.util.Properties;
public class SmbUtil {
// 配置常量
private static final String TARGET_FOLDER = "CP-25-103-XCL"; // 需要进入的远程子目录
private static final String FILE_EXTENSION = ".xlsx"; // 目标文件后缀
private static final String LOCAL_DIR = "D:/file";
public static void main(String[] args) {
String name = "CP-25-103-XCL";
downloadExcelFiles(name);
}
public static void downloadExcelFiles1(String targetFolder) {
try {
// 初始化SMB配置
Properties ps = new Properties();
ps.setProperty("jcifs.smb.client.username", "admin");
ps.setProperty("jcifs.smb.client.password", "hbyt2025");
ps.setProperty("jcifs.smb.client.dfs.disabled", "true");
Configuration config = new PropertyConfiguration(ps);
CIFSContext cifs = new BaseContext(config);
// 创建本地保存目录
File localDir = new File(LOCAL_DIR);
if (!localDir.exists() && !localDir.mkdirs()) {
throw new IOException("无法创建本地目录: " + localDir.getAbsolutePath());
}
// 定位到远程目标子目录
SmbFile remoteDir = new SmbFile("smb://192.168.5.18/2025/" + targetFolder + "/", cifs);
if (!remoteDir.exists() || !remoteDir.isDirectory()) {
System.err.println("远程目录不存在: " + remoteDir.getCanonicalPath());
return;
}
for (SmbFile remoteFile : remoteDir.listFiles()) {
// 过滤非目标文件
if (remoteFile.isFile() && remoteFile.getName().toLowerCase().endsWith(FILE_EXTENSION)) {
// 提取原文件扩展名
String originalName = remoteFile.getName();
int dotIndex = originalName.lastIndexOf('.');
String extension = (dotIndex != -1) ? originalName.substring(dotIndex) : "";
// 使用指定名称 + 原扩展名构造本地文件名
String localFileName = targetFolder + extension;
File localFile = new File(localDir, localFileName);
transferFile(remoteFile, localFile);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void downloadExcelFiles(String targetFolder) {
try {
// 初始化SMB配置
Properties ps = new Properties();
ps.setProperty("jcifs.smb.client.username", "admin");
ps.setProperty("jcifs.smb.client.password", "hbyt2025");
ps.setProperty("jcifs.smb.client.dfs.disabled", "true");
Configuration config = new PropertyConfiguration(ps);
CIFSContext cifs = new BaseContext(config);
// 创建本地保存目录
File localDir = new File(LOCAL_DIR);
if (!localDir.exists() && !localDir.mkdirs()) {
throw new IOException("无法创建本地目录: " + localDir.getAbsolutePath());
}
// 定位到远程目标子目录
SmbFile remoteDir = new SmbFile("smb://192.168.5.18/2025/" + targetFolder + "/", cifs);
if (!remoteDir.exists() || !remoteDir.isDirectory()) {
System.err.println("远程目录不存在或不是一个目录: " + remoteDir.getCanonicalPath());
return;
}
// 指定要下载的文件名
String targetFileName = targetFolder+"汇总表.xlsx";
// 构造远程文件路径
SmbFile remoteFile = new SmbFile(remoteDir, targetFileName);
if (!remoteFile.exists() || !remoteFile.isFile()) {
System.err.println("目标文件不存在: " + remoteFile.getCanonicalPath());
return;
}
// 本地保存路径D:/file/项目生产数据表.xlsx
File localFile = new File(localDir, targetFileName);
transferFile(remoteFile, localFile);
} catch (Exception e) {
System.err.println("操作失败: " + e.getMessage());
e.printStackTrace();
}
}
private static void transferFile(SmbFile remoteFile, File localFile) {
System.out.printf("正在下载 [%s] => [%s]%n",
remoteFile.getName(),
localFile.getAbsolutePath());
try (InputStream is = remoteFile.getInputStream();
OutputStream os = Files.newOutputStream(localFile.toPath())) {
// 使用8KB缓冲区提升传输效率
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
System.out.println("√ 下载成功: " + remoteFile.getName());
} catch (IOException e) {
System.err.println("× 下载失败: " + remoteFile.getName());
e.printStackTrace();
// 清理失败文件
if (localFile.exists() && !localFile.delete()) {
System.err.println("! 无法清理残留文件: " + localFile.getName());
}
}
}
}

View File

@ -5,12 +5,7 @@ import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder; import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig; import com.alibaba.excel.write.metadata.fill.FillConfig;
@ -25,6 +20,8 @@ import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils; import com.ruoyi.common.utils.file.FileUtils;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Data;
import lombok.AllArgsConstructor;
import javax.servlet.ServletOutputStream; import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -32,6 +29,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -139,39 +137,64 @@ public class ExcelUtil {
} }
} }
/** /**
* 导出excel * 导出多个sheet的Excel
* *
* @param list1 导出数据集合1 * @param list1 第一个sheet的数据集合
* @param sheetName1 工作表的名称1 * @param sheetName1 第一个sheet的名称
* @param clazz1 实体类1 * @param clazz1 第一个sheet的实体类
* @param list2 导出数据集合2 * @param list2 第二个sheet的数据集合
* @param sheetName2 工作表的名称2 * @param sheetName2 第二个sheet的名称
* @param clazz2 实体类2 * @param clazz2 第二个sheet的实体类
* @param response 响应体 * @param response HTTP响应对象
*/ */
public static <T1, T2> void exportExcelWithMultipleSheets(List<T1> list1, String sheetName1, Class<T1> clazz1, public static <T1, T2> void exportExcelWithMultipleSheets(List<T1> list1, String sheetName1, Class<T1> clazz1,
List<T2> list2, String sheetName2, Class<T2> clazz2, List<T2> list2, String sheetName2, Class<T2> clazz2,
HttpServletResponse response) { HttpServletResponse response) {
ServletOutputStream os = null;
ExcelWriter excelWriter = null;
try { try {
resetResponse(sheetName1, response); // 设置响应头
ServletOutputStream os = response.getOutputStream(); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
// 使用 EasyExcel Apache POI 自定义导出 response.setCharacterEncoding("utf-8");
ExcelWriter excelWriter = EasyExcel.write(os, clazz1).build(); String fileName = URLEncoder.encode(sheetName1, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
// 写入第一个 sheet os = response.getOutputStream();
WriteSheet writeSheet1 = EasyExcel.writerSheet(sheetName1).build();
// 创建ExcelWriter
excelWriter = EasyExcel.write(os)
.autoCloseStream(false) // 防止自动关闭流
.build();
// 写入第一个sheet
WriteSheet writeSheet1 = EasyExcel.writerSheet(0, sheetName1)
.head(clazz1)
.build();
excelWriter.write(list1, writeSheet1); excelWriter.write(list1, writeSheet1);
// 写入第二个 sheet // 写入第二个sheet
WriteSheet writeSheet2 = EasyExcel.writerSheet(sheetName2).build(); WriteSheet writeSheet2 = EasyExcel.writerSheet(1, sheetName2)
.head(clazz2)
.build();
excelWriter.write(list2, writeSheet2); excelWriter.write(list2, writeSheet2);
} catch (Exception e) {
throw new RuntimeException("导出Excel异常: " + e.getMessage(), e);
} finally {
// 确保资源正确关闭
if (excelWriter != null) {
excelWriter.finish(); excelWriter.finish();
} catch (IOException e) {
throw new RuntimeException("导出Excel异常");
} }
} if (os != null) {
try {
os.close();
} catch (IOException e) {
// 忽略关闭时的异常
}
}
}
}
/** /**
* 导出excel * 导出excel
@ -404,4 +427,109 @@ public static <T1, T2> void exportExcelWithMultipleSheets(List<T1> list1, String
return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx"; return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx";
} }
/**
* 导出多个sheet的Excel(相同对象)
*
* @param list 导出数据集合的集合(每个元素代表一个sheet的数据)
* @param sheetNames sheet名称的集合(与list一一对应)
* @param clazz 实体类
* @param response 响应体
*/
public static <T> void exportExcelWithSheets(List<List<T>> list, List<String> sheetNames, Class<T> clazz, HttpServletResponse response) {
try {
if (CollUtil.isEmpty(list) || CollUtil.isEmpty(sheetNames) || list.size() != sheetNames.size()) {
throw new IllegalArgumentException("数据列表或sheet名称列表不能为空且两者长度必须相等");
}
resetResponse(sheetNames.get(0), response);
ServletOutputStream os = response.getOutputStream();
// 创建ExcelWriter
ExcelWriter excelWriter = EasyExcel.write(os)
.autoCloseStream(false)
// 自动适配
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
// 大数值自动转换 防止失真
.registerConverter(new ExcelBigNumberConvert())
.build();
try {
// 循环写入每个sheet
for (int i = 0; i < list.size(); i++) {
WriteSheet writeSheet = EasyExcel.writerSheet(i, sheetNames.get(i))
.head(clazz)
.build();
excelWriter.write(list.get(i), writeSheet);
}
} finally {
// 确保ExcelWriter被正确关闭
if (excelWriter != null) {
excelWriter.finish();
}
}
} catch (Exception e) {
throw new RuntimeException("导出Excel异常", e);
}
}
/**
* 通用多sheet导出方法
*
* @param sheetDataList sheet数据列表每个元素包含数据列表sheet名称数据类型
* @param response HTTP响应对象
*/
public static void exportExcelWithSheets(List<SheetData<?>> sheetDataList, HttpServletResponse response) {
ServletOutputStream os = null;
ExcelWriter excelWriter = null;
try {
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("导出数据", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
os = response.getOutputStream();
// 创建ExcelWriter
excelWriter = EasyExcel.write(os)
.autoCloseStream(false) // 防止自动关闭流
.build();
// 循环写入每个sheet
for (int i = 0; i < sheetDataList.size(); i++) {
SheetData<?> sheetData = sheetDataList.get(i);
WriteSheet writeSheet = EasyExcel.writerSheet(i, sheetData.getSheetName())
.head(sheetData.getClazz())
.build();
excelWriter.write(sheetData.getData(), writeSheet);
}
} catch (Exception e) {
throw new RuntimeException("导出Excel异常: " + e.getMessage(), e);
} finally {
// 确保资源正确关闭
if (excelWriter != null) {
excelWriter.finish();
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
// 忽略关闭时的异常
}
}
}
}
/**
* Sheet数据包装类
*/
@Data
@AllArgsConstructor
public static class SheetData<T> {
private List<T> data;
private String sheetName;
private Class<T> clazz;
}
} }

View File

@ -23,7 +23,8 @@ import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.BomDetails; import com.ruoyi.system.domain.BomDetails;
import com.ruoyi.system.domain.MaterialProperties; import com.ruoyi.system.domain.MaterialProperties;
import com.ruoyi.system.domain.bo.BomDetailsBo; import com.ruoyi.system.domain.bo.BomDetailsBo;
import com.ruoyi.system.domain.dto.JDBom; import com.ruoyi.system.domain.dto.JdValidateBomDTO;
import com.ruoyi.system.domain.dto.JdChildDTO;
import com.ruoyi.system.domain.vo.BomDetailsVo; import com.ruoyi.system.domain.vo.BomDetailsVo;
import com.ruoyi.system.runner.JdUtil; import com.ruoyi.system.runner.JdUtil;
import com.ruoyi.system.service.IBomDetailsService; import com.ruoyi.system.service.IBomDetailsService;
@ -31,13 +32,13 @@ import com.ruoyi.system.service.IMaterialPropertiesService;
import com.ruoyi.system.service.IMaterialTotalService; import com.ruoyi.system.service.IMaterialTotalService;
import com.ruoyi.system.service.IProcessRouteService; import com.ruoyi.system.service.IProcessRouteService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.WorkbookFactory; import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -61,6 +62,7 @@ import static org.aspectj.bridge.MessageUtil.fail;
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@RequestMapping("/system/details") @RequestMapping("/system/details")
@Slf4j
public class BomDetailsController extends BaseController { public class BomDetailsController extends BaseController {
private final IBomDetailsService iBomDetailsService; private final IBomDetailsService iBomDetailsService;
@ -70,7 +72,8 @@ public class BomDetailsController extends BaseController {
private final IProcessRouteService iProcessRouteService; private final IProcessRouteService iProcessRouteService;
private final IMaterialTotalService iMaterialTotalService; private final IMaterialTotalService iMaterialTotalService;
private static final Logger log = LoggerFactory.getLogger(BomDetailsController.class);
/** /**
* 查询bom明细列表 * 查询bom明细列表
@ -197,7 +200,6 @@ public class BomDetailsController extends BaseController {
/** /**
* 导入BOM * 导入BOM
* daorubaon * daorubaon
*
* @param file 导入文件 * @param file 导入文件
*/ */
@ -214,28 +216,21 @@ public class BomDetailsController extends BaseController {
if (loadChengPinMaterialPreservation(bomFinishedProduct) == 1) { if (loadChengPinMaterialPreservation(bomFinishedProduct) == 1) {
log.info("新增成品父级物流成功"); log.info("新增成品父级物流成功");
} }
// loadChengPinMaterialPreservation()
for (BomDetailsVo bomDetailsvo : bomDetailsVos) { for (BomDetailsVo bomDetailsvo : bomDetailsVos) {
BomDetails bomDetails = BeanUtil.toBean(bomDetailsvo, BomDetails.class); BomDetails bomDetails = BeanUtil.toBean(bomDetailsvo, BomDetails.class);
// 校验属性材质数量是否为空并记录提示信息 // 校验属性材质数量是否为空并记录提示信息
if (bomDetails.getStats() == null || bomDetails.getMaterial() == null || bomDetails.getQuantity() == null) { if (bomDetails.getStats() == null || bomDetails.getMaterial() == null || bomDetails.getQuantity() == null) {
String warningMessage = String.format("记录 %s 缺少必要字段: 属性=%s, 材质=%s, 数量=%s", String warningMessage = String.format("记录 %s 缺少必要字段: 属性=%s, 材质=%s, 数量=%s", bomDetails.getPartNumber(), bomDetails.getStats(), bomDetails.getMaterial(), bomDetails.getQuantity());
bomDetails.getPartNumber(), bomDetails.getStats(), bomDetails.getMaterial(),
bomDetails.getQuantity());
missingFieldsWarnings.add(warningMessage); missingFieldsWarnings.add(warningMessage);
} }
// 验证物料是否存在 // 验证物料是否存在
if (bomDetails.getFNumber() != null && bomDetails.getFName() != null && bomDetails.getPartNumber() != null if (bomDetails.getFNumber() != null && bomDetails.getFName() != null && bomDetails.getPartNumber() != null && bomDetails.getName() != null) {
&& bomDetails.getName() != null) {
int verification = isMaterialVerification(bomDetails.getPartNumber(), bomDetails.getName()); int verification = isMaterialVerification(bomDetails.getPartNumber(), bomDetails.getName());
if (verification == 1) { if (verification == 1) {
bomDetails.setUnitWeight(""); bomDetails.setUnitWeight("");
} else if (verification == 3) { } else if (verification == 3) {
if (bomDetails.getStats() == null || bomDetails.getStats().equals("外购") if (bomDetails.getStats() == null || bomDetails.getStats().equals("外购") || bomDetails.getFName().startsWith("009") || bomDetails.getFName().startsWith("AA") || bomDetails.getFName().startsWith("AB") || bomDetails.getFName().startsWith("AC") || bomDetails.getFName().startsWith("015")) {
|| bomDetails.getFName().startsWith("009") || bomDetails.getFName().startsWith("AA")
|| bomDetails.getFName().startsWith("AB") || bomDetails.getFName().startsWith("AC")
|| bomDetails.getFName().startsWith("015")) {
materialsToAdd.add(bomDetails); materialsToAdd.add(bomDetails);
} else if (bomDetails.getStats().equals("自制")) { } else if (bomDetails.getStats().equals("自制")) {
materialsToAdd.add(bomDetails); materialsToAdd.add(bomDetails);
@ -244,10 +239,7 @@ public class BomDetailsController extends BaseController {
} }
bomDetails.setUnitWeight("编码名称不符"); bomDetails.setUnitWeight("编码名称不符");
} else { } else {
if (bomDetails.getStats() == null || bomDetails.getStats().equals("外购") if (bomDetails.getStats() == null || bomDetails.getStats().equals("外购") || bomDetails.getFName().startsWith("009") || bomDetails.getFName().startsWith("AA") || bomDetails.getFName().startsWith("AB") || bomDetails.getFName().startsWith("AC") || bomDetails.getFName().startsWith("015")) {
|| bomDetails.getFName().startsWith("009") || bomDetails.getFName().startsWith("AA")
|| bomDetails.getFName().startsWith("AB") || bomDetails.getFName().startsWith("AC")
|| bomDetails.getFName().startsWith("015")) {
materialsToAdd.add(bomDetails); materialsToAdd.add(bomDetails);
} else if (bomDetails.getStats().equals("自制")) { } else if (bomDetails.getStats().equals("自制")) {
materialsToAdd.add(bomDetails); materialsToAdd.add(bomDetails);
@ -288,6 +280,8 @@ public class BomDetailsController extends BaseController {
log.info("开始新增不存在的物料==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName()); log.info("开始新增不存在的物料==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
result = loadMaterialPreservation(material, state, a); result = loadMaterialPreservation(material, state, a);
} }
if (result == 1) { if (result == 1) {
log.info("新增物料成功==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName()); log.info("新增物料成功==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
material.setUnitWeight("新增成功"); material.setUnitWeight("新增成功");
@ -378,6 +372,7 @@ public class BomDetailsController extends BaseController {
public R updateFBMaterial(@RequestBody List<Map<String, String>> bomDetailParams) { public R updateFBMaterial(@RequestBody List<Map<String, String>> bomDetailParams) {
List<BomDetails> bomDetailsList = new ArrayList<>(); List<BomDetails> bomDetailsList = new ArrayList<>();
Set<String> processedMaterials = new HashSet<>(); // 用于跟踪已处理的物料编码 Set<String> processedMaterials = new HashSet<>(); // 用于跟踪已处理的物料编码
List<String> failedMaterials = new ArrayList<>(); // 用于跟踪处理失败的物料
// 遍历前端传来的数据 // 遍历前端传来的数据
for (Map<String, String> param : bomDetailParams) { for (Map<String, String> param : bomDetailParams) {
@ -393,18 +388,20 @@ public class BomDetailsController extends BaseController {
for (BomDetails material : bomDetails) { for (BomDetails material : bomDetails) {
// 只在第一次遇到该物料时新增父级物料 // 只在第一次遇到该物料时新增父级物料
if (!processedMaterials.contains(material.getFNumber())) { if (!processedMaterials.contains(material.getFNumber())) {
try { log.info("开始新增不存在的物料 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName()); try {
log.info("开始新增不存在的物料 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName());
Double fbWorkTime = iProcessRouteService.getFaWorkTime(material); Double fbWorkTime = iProcessRouteService.getFaWorkTime(material);
JdUtil.loadChengPinMaterialPreservation(material,fbWorkTime); JdUtil.loadChengPinMaterialPreservation(material, fbWorkTime);
processedMaterials.add(material.getFNumber()); // 标记为已处理 processedMaterials.add(material.getFNumber()); // 标记为已处理
} catch (Exception e) { } catch (Exception e) {
log.error("新增父级物料失败: {}", e.getMessage()); log.error("新增父级物料失败: {}", e.getMessage());
failedMaterials.add(material.getPartNumber());
} }
} }
// 获取工艺表中的非委外工时 // 获取工艺表中的非委外工时
Double fbWorkTime = iProcessRouteService.getFbWorkTime(material); Double fbWorkTime = iProcessRouteService.getFbWorkTime(material);
if (material.getPartNumber() != null && material.getName() != null&& material.getUnitWeight().equals("")) { if (material.getPartNumber() != null && material.getName() != null && material.getUnitWeight().equals("")) {
String state = determineState(material); String state = determineState(material);
log.info("开始新增不存在的物料 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName()); log.info("开始新增不存在的物料 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName());
@ -414,27 +411,84 @@ public class BomDetailsController extends BaseController {
log.info("新增物料成功 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName()); log.info("新增物料成功 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName());
material.setUnitWeight("新增成功"); material.setUnitWeight("新增成功");
} else { } else {
log.error("新增物料失败 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), log.error("新增物料失败 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName());
material.getName()); failedMaterials.add(material.getPartNumber());
} }
// 更新物料状态 // 更新物料状态
iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class)); iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class));
} catch (Exception e) { } catch (Exception e) {
log.error("处理物料时发生异常: {}", e.getMessage()); log.error("处理物料时发生异常: {}", e.getMessage());
failedMaterials.add(material.getPartNumber());
} }
} else { } else {
log.error("物料信息不完整,无法新增物料"); log.error("物料信息不完整,无法新增物料");
failedMaterials.add(material.getPartNumber());
} }
} }
//保存物料之前进行BOM校验
List<JDBom> selectBomList = JdUtil.getSelectBomList(fnumber); // 保存物料清单之前进行BOM校验
if (validateBOM(fnumber, bomDetails)) {
log.error("BOM校验失败物料编码: {}", fnumber);
failedMaterials.add(fnumber);
continue; // 跳过保存
}
// 物料清单保存方法 // 物料清单保存方法
FBloadBillOfMaterialsPreservation(bomDetails); FBloadBillOfMaterialsPreservation(bomDetails);
bomDetailsList.addAll(bomDetails); bomDetailsList.addAll(bomDetails);
} }
} }
// 返回处理结果
return R.ok("成功", bomDetailsList); return R.ok("成功", bomDetailsList);
}
private boolean validateBOM(String fnumber, List<BomDetails> bomDetails) {
List<JdValidateBomDTO> JDBomList = JdUtil.getSelectBomList(fnumber);
// 1. 判断BOM是否为空
if (JDBomList == null || JDBomList.isEmpty()) {
log.error("BOM为空物料编码: {}", fnumber);
return false; // BOM为空,需要上传
}
for (JdValidateBomDTO jdBom : JDBomList) {
// 3. 检查子项数量是否一致
if (jdBom.getChilds().size() != bomDetails.size()) {
continue; // 数量不一致,跳过这个BOM继续检查下一个
}
// 4. 比较每个子项的内容
boolean isMatch = true;
for (int i = 0; i < jdBom.getChilds().size(); i++) {
JdChildDTO jdChild = jdBom.getChilds().get(i);
BomDetails inputBomDetail = bomDetails.get(i);
// 比较物料编码和名称
if (!jdChild.getPartNumber().equals(inputBomDetail.getPartNumber()) ||
!jdChild.getName().equals(inputBomDetail.getName())) {
isMatch = false;
break;
}
// 比较分子和分母
if (!jdChild.getDenominator().equals(inputBomDetail.getDenominator()) || !jdChild.getQuantity().equals(inputBomDetail.getQuantity())) {
isMatch = false;
break;
}
}
if (isMatch) {
// 找到匹配的BOM无需上传
log.info("BOM完全相同物料编码: {},无需上传", fnumber);
return true;
}
}
// 所有BOM都不匹配需要上传
log.info("BOM不存在或不一致物料编码: {},需要上传", fnumber);
return false;
} }
@ -671,10 +725,10 @@ public class BomDetailsController extends BaseController {
fTreeEntityItem.addProperty("FNUMERATOR", details.getQuantity()); fTreeEntityItem.addProperty("FNUMERATOR", details.getQuantity());
fTreeEntityItem.addProperty("FDENOMINATOR", details.getDenominator()); fTreeEntityItem.addProperty("FDENOMINATOR", details.getDenominator());
//添加货主信息 查看这个bom中是否符合货主信息 // 添加货主信息 查看这个bom中是否符合货主信息
String materialCode = details.getPartNumber(); String materialCode = details.getPartNumber();
Boolean vmiByCode = iMaterialTotalService.getVMIByCode(materialCode); Boolean vmiByCode = iMaterialTotalService.getVMIByCode(materialCode);
if (vmiByCode){ if (vmiByCode) {
fTreeEntityItem.addProperty("FOWNERTYPEID", "BD_Supplier"); fTreeEntityItem.addProperty("FOWNERTYPEID", "BD_Supplier");
JsonObject FOWNERID = new JsonObject(); JsonObject FOWNERID = new JsonObject();
fTreeEntityItem.add("FOWNERID", FOWNERID); fTreeEntityItem.add("FOWNERID", FOWNERID);
@ -684,7 +738,7 @@ public class BomDetailsController extends BaseController {
fTreeEntityList.add(fTreeEntityItem); fTreeEntityList.add(fTreeEntityItem);
} }
String jsonData = json.toString(); String jsonData = json.toString();
log.debug("打印json:" + jsonData); log.info("打印json:" + jsonData);
try { try {
// 业务对象标识 // 业务对象标识
String formId = "ENG_BOM"; String formId = "ENG_BOM";
@ -1083,7 +1137,6 @@ public class BomDetailsController extends BaseController {
/* /*
* FB父级物料保存接口 * FB父级物料保存接口
* 单位 是台
*/ */
public int loadChengPinMaterialPreservation(HashMap<String, String> bomDetail) { public int loadChengPinMaterialPreservation(HashMap<String, String> bomDetail) {
K3CloudApi client = new K3CloudApi(); K3CloudApi client = new K3CloudApi();
@ -1307,19 +1360,18 @@ public class BomDetailsController extends BaseController {
public int loadMaterialPreservation(BomDetails bomDetails1, String states, Double fbWorkTime) { public int loadMaterialPreservation(BomDetails bomDetails1, String states, Double fbWorkTime) {
K3CloudApi client = new K3CloudApi(); K3CloudApi client = new K3CloudApi();
// 创建一个空的JsonObject
JsonObject json = new JsonObject(); JsonObject json = new JsonObject();
// 添加IsAutoSubmitAndAudit字段
json.addProperty("IsAutoSubmitAndAudit", "true"); json.addProperty("IsAutoSubmitAndAudit", "true");
// 创建Model对象并加入JsonObject
JsonObject model = new JsonObject(); JsonObject model = new JsonObject();
json.add("Model", model); json.add("Model", model);
// 添加Model字段
model.addProperty("FMATERIALID", 0); model.addProperty("FMATERIALID", 0);
if(!(bomDetails1.getDanzhong() ==null)){ //单重
model.addProperty("F_HBYT_DZ", bomDetails1.getDanzhong()); if (!(bomDetails1.getDanZhong() == null) && !(bomDetails1.getSingleWeghit() == null)) {
model.addProperty("F_HBYT_DZ", bomDetails1.getSingleWeghit());
}else {
model.addProperty("F_HBYT_DZ", bomDetails1.getDanZhong());
} }
model.addProperty("FSpecification", bomDetails1.getRemarks()); model.addProperty("FSpecification", bomDetails1.getRemarks());
model.addProperty("FNumber", bomDetails1.getPartNumber()); model.addProperty("FNumber", bomDetails1.getPartNumber());
@ -1335,21 +1387,18 @@ public class BomDetailsController extends BaseController {
FSVRIAssistant.addProperty("FNumber", "17"); FSVRIAssistant.addProperty("FNumber", "17");
model.add("F_SVRI_Assistant", FSVRIAssistant); model.add("F_SVRI_Assistant", FSVRIAssistant);
} }
// 创建FMaterialGroup对象并加入Model
JsonObject fMaterialGroup = new JsonObject(); JsonObject fMaterialGroup = new JsonObject();
fMaterialGroup.addProperty("FNumber", "YT100.01"); fMaterialGroup.addProperty("FNumber", "YT100.01");
model.add("FMaterialGroup", fMaterialGroup); model.add("FMaterialGroup", fMaterialGroup);
model.addProperty("FIsHandleReserve", true); model.addProperty("FIsHandleReserve", true);
// 创建SubHeadEntity对象并加入Model
JsonObject subHeadEntity = new JsonObject(); JsonObject subHeadEntity = new JsonObject();
model.add("SubHeadEntity", subHeadEntity); model.add("SubHeadEntity", subHeadEntity);
subHeadEntity.addProperty("FErpClsID", states); subHeadEntity.addProperty("FErpClsID", states);
subHeadEntity.addProperty("FFeatureItem", "1"); subHeadEntity.addProperty("FFeatureItem", "1");
// 创建FCategoryID对象并加入SubHeadEntity
JsonObject fCategoryID = new JsonObject(); JsonObject fCategoryID = new JsonObject();
if (states.equals("2") || states.equals("3")) { if (states.equals("2") || states.equals("3")) {
fCategoryID.addProperty("FNumber", "007"); fCategoryID.addProperty("FNumber", "007");
@ -1359,15 +1408,28 @@ public class BomDetailsController extends BaseController {
subHeadEntity.add("FCategoryID", fCategoryID); subHeadEntity.add("FCategoryID", fCategoryID);
// 创建FTaxRateId对象并加入SubHeadEntity
JsonObject fTaxRateId = new JsonObject(); JsonObject fTaxRateId = new JsonObject();
fTaxRateId.addProperty("FNUMBER", "SL02_SYS"); fTaxRateId.addProperty("FNUMBER", "SL02_SYS");
subHeadEntity.add("FTaxRateId", fTaxRateId); subHeadEntity.add("FTaxRateId", fTaxRateId);
// 创建FBaseUnitId对象并加入SubHeadEntity
JsonObject fBaseUnitId = new JsonObject(); JsonObject fBaseUnitId = new JsonObject();
fBaseUnitId.addProperty("FNumber", "jian");
subHeadEntity.add("FBaseUnitId", fBaseUnitId); subHeadEntity.add("FBaseUnitId", fBaseUnitId);
if (bomDetails1.getPartNumber().startsWith("015") || bomDetails1.getName().contains("磨光棒")) {
if (bomDetails1.getWareHouse() != null) {
if (bomDetails1.getWareHouse().equals("KG")) {
fBaseUnitId.addProperty("FNumber", "004");
}
if (bomDetails1.getWareHouse().equals("")) {
fBaseUnitId.addProperty("FNumber", "003");
}
if (bomDetails1.getWareHouse().equals("mm")) {
fBaseUnitId.addProperty("FNumber", "005");
}
}
} else {
fBaseUnitId.addProperty("FNumber", "jian");
}
if (states.equals("1")) { if (states.equals("1")) {
subHeadEntity.addProperty("FIsPurchase", true); subHeadEntity.addProperty("FIsPurchase", true);
subHeadEntity.addProperty("FIsSale", true); subHeadEntity.addProperty("FIsSale", true);
@ -1385,8 +1447,24 @@ public class BomDetailsController extends BaseController {
JsonObject subHeadEntity1 = new JsonObject(); JsonObject subHeadEntity1 = new JsonObject();
model.add("SubHeadEntity1", subHeadEntity1); model.add("SubHeadEntity1", subHeadEntity1);
JsonObject fStoreUnitId = new JsonObject(); JsonObject fStoreUnitId = new JsonObject();
fStoreUnitId.addProperty("FNumber", "jian");
subHeadEntity1.add("FStoreUnitID", fStoreUnitId); subHeadEntity1.add("FStoreUnitID", fStoreUnitId);
// 如果是原材料的话且
if (bomDetails1.getPartNumber().startsWith("015") || bomDetails1.getName().contains("磨光棒")) {
if (bomDetails1.getWareHouse() != null) {
if (bomDetails1.getWareHouse().equals("KG")) {
fStoreUnitId.addProperty("FNumber", "004");
}
if (bomDetails1.getWareHouse().equals("")) {
fStoreUnitId.addProperty("FNumber", "003");
}
if (bomDetails1.getWareHouse().equals("mm")) {
fStoreUnitId.addProperty("FNumber", "005");
}
}
} else {
fStoreUnitId.addProperty("FNumber", "jian");
}
subHeadEntity1.addProperty("FUnitConvertDir", "1"); subHeadEntity1.addProperty("FUnitConvertDir", "1");
// 创建FStockId对象并加入SubHeadEntity1 // 创建FStockId对象并加入SubHeadEntity1
@ -1407,6 +1485,21 @@ public class BomDetailsController extends BaseController {
// 创建FPurchaseUnitId对象并加入SubHeadEntity1 // 创建FPurchaseUnitId对象并加入SubHeadEntity1
JsonObject fPurchaseUnitId = new JsonObject(); JsonObject fPurchaseUnitId = new JsonObject();
fPurchaseUnitId.addProperty("FNumber", "jian"); fPurchaseUnitId.addProperty("FNumber", "jian");
if (bomDetails1.getPartNumber().startsWith("015") || bomDetails1.getName().contains("磨光棒")) {
if (bomDetails1.getWareHouse() != null) {
if (bomDetails1.getWareHouse().equals("KG")) {
fPurchaseUnitId.addProperty("FNumber", "004");
}
if (bomDetails1.getWareHouse().equals("")) {
fPurchaseUnitId.addProperty("FNumber", "003");
}
if (bomDetails1.getWareHouse().equals("mm")) {
fPurchaseUnitId.addProperty("FNumber", "005");
}
}
} else {
fPurchaseUnitId.addProperty("FNumber", "jian");
}
subHeadEntity1.add("FPurchaseUnitId", fPurchaseUnitId); subHeadEntity1.add("FPurchaseUnitId", fPurchaseUnitId);
// 创建SubHeadEntity3对象并加入Model // 创建SubHeadEntity3对象并加入Model
@ -1416,6 +1509,22 @@ public class BomDetailsController extends BaseController {
// 创建FPurchasePriceUnitId对象并加入SubHeadEntity3 // 创建FPurchasePriceUnitId对象并加入SubHeadEntity3
JsonObject fPurchasePriceUnitId = new JsonObject(); JsonObject fPurchasePriceUnitId = new JsonObject();
fPurchasePriceUnitId.addProperty("FNumber", "jian"); fPurchasePriceUnitId.addProperty("FNumber", "jian");
if (bomDetails1.getPartNumber().startsWith("015") || bomDetails1.getName().contains("磨光棒")) {
if (bomDetails1.getWareHouse() != null) {
if (bomDetails1.getWareHouse().equals("KG")) {
fPurchasePriceUnitId.addProperty("FNumber", "004");
}
if (bomDetails1.getWareHouse().equals("")) {
fPurchasePriceUnitId.addProperty("FNumber", "003");
}
if (bomDetails1.getWareHouse().equals("mm")) {
fPurchasePriceUnitId.addProperty("FNumber", "005");
}
}
} else {
fPurchasePriceUnitId.addProperty("FNumber", "jian");
}
subHeadEntity3.add("FPurchasePriceUnitId", fPurchasePriceUnitId); subHeadEntity3.add("FPurchasePriceUnitId", fPurchasePriceUnitId);
subHeadEntity3.addProperty("FIsQuota", false); subHeadEntity3.addProperty("FIsQuota", false);
@ -1450,6 +1559,21 @@ public class BomDetailsController extends BaseController {
// 创建FProduceUnitId对象并加入SubHeadEntity5 // 创建FProduceUnitId对象并加入SubHeadEntity5
JsonObject fProduceUnitId = new JsonObject(); JsonObject fProduceUnitId = new JsonObject();
fProduceUnitId.addProperty("FNumber", "jian"); fProduceUnitId.addProperty("FNumber", "jian");
if (bomDetails1.getPartNumber().startsWith("015") || bomDetails1.getName().contains("磨光棒")) {
if (bomDetails1.getWareHouse() != null) {
if (bomDetails1.getWareHouse().equals("KG")) {
fProduceUnitId.addProperty("FNumber", "004");
}
if (bomDetails1.getWareHouse().equals("")) {
fProduceUnitId.addProperty("FNumber", "003");
}
if (bomDetails1.getWareHouse().equals("mm")) {
fProduceUnitId.addProperty("FNumber", "005");
}
}
} else {
fProduceUnitId.addProperty("FNumber", "jian");
}
subHeadEntity5.add("FProduceUnitId", fProduceUnitId); subHeadEntity5.add("FProduceUnitId", fProduceUnitId);
// 实际作工时并加入SubHeadEntity5 // 实际作工时并加入SubHeadEntity5
@ -1461,7 +1585,24 @@ public class BomDetailsController extends BaseController {
// 创建FBOMUnitId对象并加入SubHeadEntity5 // 创建FBOMUnitId对象并加入SubHeadEntity5
JsonObject fBOMUnitId = new JsonObject(); JsonObject fBOMUnitId = new JsonObject();
fBOMUnitId.addProperty("FNumber", "jian"); fBOMUnitId.addProperty("FNumber", "jian");
if (bomDetails1.getPartNumber().startsWith("015") || bomDetails1.getName().contains("磨光棒")) {
if (bomDetails1.getWareHouse() != null) {
if (bomDetails1.getWareHouse().equals("KG")) {
fBOMUnitId.addProperty("FNumber", "004");
}
if (bomDetails1.getWareHouse().equals("")) {
fBOMUnitId.addProperty("FNumber", "003");
}
if (bomDetails1.getWareHouse().equals("mm")) {
fBOMUnitId.addProperty("FNumber", "005");
}
}
} else {
fBOMUnitId.addProperty("FNumber", "jian");
}
subHeadEntity5.add("FBOMUnitId", fBOMUnitId); subHeadEntity5.add("FBOMUnitId", fBOMUnitId);
if (states.equals("1")) { if (states.equals("1")) {
subHeadEntity5.addProperty("FIsMainPrd", false); subHeadEntity5.addProperty("FIsMainPrd", false);
} else { } else {
@ -1880,11 +2021,7 @@ public class BomDetailsController extends BaseController {
break; break;
} }
subHeadEntity5.add("FBOMUnitId", fBOMUnitId); subHeadEntity5.add("FBOMUnitId", fBOMUnitId);
if (states.equals("1")) { subHeadEntity5.addProperty("FIsMainPrd", !states.equals("1"));
subHeadEntity5.addProperty("FIsMainPrd", false);
} else {
subHeadEntity5.addProperty("FIsMainPrd", true);
}
subHeadEntity5.addProperty("FIssueType", "1"); subHeadEntity5.addProperty("FIssueType", "1");
// 创建FPickStockId对象并加入SubHeadEntity5 // 创建FPickStockId对象并加入SubHeadEntity5

View File

@ -6,6 +6,8 @@ import java.util.Arrays;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutionException;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.kingdee.bos.webapi.entity.SuccessEntity; import com.kingdee.bos.webapi.entity.SuccessEntity;
@ -53,6 +55,7 @@ public class EleMaterialsController extends BaseController {
private final IEleMaterialsService iEleMaterialsService; private final IEleMaterialsService iEleMaterialsService;
private static final Logger log = LoggerFactory.getLogger(EleMaterialsController.class); private static final Logger log = LoggerFactory.getLogger(EleMaterialsController.class);
/** /**
* 查询电器物料管理列表 * 查询电器物料管理列表
*/ */
@ -81,8 +84,7 @@ public class EleMaterialsController extends BaseController {
*/ */
@SaCheckPermission("system:materials:query") @SaCheckPermission("system:materials:query")
@GetMapping("/{id}") @GetMapping("/{id}")
public R<EleMaterialsVo> getInfo(@NotNull(message = "主键不能为空") public R<EleMaterialsVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
@PathVariable Long id) {
return R.ok(iEleMaterialsService.queryById(id)); return R.ok(iEleMaterialsService.queryById(id));
} }
@ -116,12 +118,10 @@ public class EleMaterialsController extends BaseController {
@SaCheckPermission("system:materials:remove") @SaCheckPermission("system:materials:remove")
@Log(title = "电器物料管理", businessType = BusinessType.DELETE) @Log(title = "电器物料管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空") public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
@PathVariable Long[] ids) {
return toAjax(iEleMaterialsService.deleteWithValidByIds(Arrays.asList(ids), true)); return toAjax(iEleMaterialsService.deleteWithValidByIds(Arrays.asList(ids), true));
} }
/** /**
* 将物料上传至金蝶 * 将物料上传至金蝶
*/ */
@ -133,6 +133,7 @@ public class EleMaterialsController extends BaseController {
return iEleMaterialsService.addToJindie(); return iEleMaterialsService.addToJindie();
} }
@Log(title = "电器物料导入", businessType = BusinessType.IMPORT) @Log(title = "电器物料导入", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:materials:importData") @SaCheckPermission("system:materials:importData")
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ -145,7 +146,8 @@ public class EleMaterialsController extends BaseController {
throw new RuntimeException("上传的文件为空"); throw new RuntimeException("上传的文件为空");
} }
// 导入 Excel 数据 // 导入 Excel 数据
ExcelResult<EleMaterialsVo> eleMaterialsVoExcelResult = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class, true); ExcelResult<EleMaterialsVo> eleMaterialsVoExcelResult = ExcelUtil.importExcelSheet1(file.getInputStream(),
EleMaterialsVo.class, true);
// 检查导入结果 // 检查导入结果
if (eleMaterialsVoExcelResult.getList() == null || eleMaterialsVoExcelResult.getList().isEmpty()) { if (eleMaterialsVoExcelResult.getList() == null || eleMaterialsVoExcelResult.getList().isEmpty()) {
throw new RuntimeException("导入的 Excel 文件没有有效数据"); throw new RuntimeException("导入的 Excel 文件没有有效数据");
@ -161,7 +163,7 @@ public class EleMaterialsController extends BaseController {
@PostMapping(value = "/exportData") @PostMapping(value = "/exportData")
public void importData1(@RequestBody ExcelVo excelVo, HttpServletResponse response) throws Exception { public void importData1(@RequestBody ExcelVo excelVo, HttpServletResponse response) throws Exception {
// result 返回 // result 返回
try { try {
// 保存数据并导出 Excel // 保存数据并导出 Excel
if (iEleMaterialsService.saveData(excelVo.getList(), response)) { if (iEleMaterialsService.saveData(excelVo.getList(), response)) {
@ -189,16 +191,17 @@ public class EleMaterialsController extends BaseController {
} }
return R.ok("更新成功"); return R.ok("更新成功");
} }
@Log(title = "禁用子项中包含的物料", businessType = BusinessType.IMPORT) @Log(title = "禁用子项中包含的物料", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:materials:importDataTime") @SaCheckPermission("system:materials:importDataTime")
@PostMapping(value = "/importMA1", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PostMapping(value = "/importMA1", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importMA1(@RequestParam("file") MultipartFile file) throws Exception { public R<Void> importMA1(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename(); String originalFilename = file.getOriginalFilename();
log.info("读取文件名: " + originalFilename); log.info("读取文件名: " + originalFilename);
ExcelResult<EleMaterialsVo> result = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class, true); ExcelResult<EleMaterialsVo> result = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class,
true);
List<EleMaterialsVo> list = result.getList(); List<EleMaterialsVo> list = result.getList();
// 创建一个固定大小的线程池 // 创建一个固定大小的线程池
ExecutorService executorService = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数 ExecutorService executorService = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数
@ -238,7 +241,8 @@ public class EleMaterialsController extends BaseController {
public R<Void> updaDateGongshi(@RequestParam("file") MultipartFile file) throws Exception { public R<Void> updaDateGongshi(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename(); String originalFilename = file.getOriginalFilename();
log.info("读取文件名: " + originalFilename); log.info("读取文件名: " + originalFilename);
ExcelResult<EleMaterialsVo> result = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class, true); ExcelResult<EleMaterialsVo> result = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class,
true);
List<EleMaterialsVo> list = result.getList(); List<EleMaterialsVo> list = result.getList();
// 创建固定大小的线程池 // 创建固定大小的线程池
@ -255,7 +259,8 @@ public class EleMaterialsController extends BaseController {
log.info("物料编码: " + processRouteVo.getMaterialValue()); log.info("物料编码: " + processRouteVo.getMaterialValue());
log.info("工时: " + processRouteVo.getMaterialCode()); log.info("工时: " + processRouteVo.getMaterialCode());
try { try {
JdUtil.atestSaveMaterial(FMATERIALID, fEntryId, processRouteVo.getMaterialCode(), Double.parseDouble(processRouteVo.getMaterialValue())); JdUtil.atestSaveMaterial(FMATERIALID, fEntryId, processRouteVo.getMaterialCode(),
Double.parseDouble(processRouteVo.getMaterialValue()));
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -290,10 +295,10 @@ public class EleMaterialsController extends BaseController {
for (JdHuoZhu jdEntryVmi : entryID) { for (JdHuoZhu jdEntryVmi : entryID) {
int fmaterialid = jdEntryVmi.getFID(); int fmaterialid = jdEntryVmi.getFID();
int fEntryId1 = jdEntryVmi.getFTreeEntityFENTRYID(); int fEntryId1 = jdEntryVmi.getFTreeEntityFENTRYID();
log.info("物料"+vmi.getMaterialCode()+"的FId: " + fmaterialid); log.info("物料" + vmi.getMaterialCode() + "的FId: " + fmaterialid);
log.info("物料"+vmi.getMaterialCode()+"fEntryId: " + fEntryId1); log.info("物料" + vmi.getMaterialCode() + "fEntryId: " + fEntryId1);
try { try {
JdUtil.updateHuozhu(fmaterialid, fEntryId1,vmi.getMaterialCode()); JdUtil.updateHuozhu(fmaterialid, fEntryId1, vmi.getMaterialCode());
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -308,6 +313,7 @@ public class EleMaterialsController extends BaseController {
return R.ok("更新成功"); return R.ok("更新成功");
} }
@Log(title = "更新VMI仓位", businessType = BusinessType.IMPORT) @Log(title = "更新VMI仓位", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:updaDateCangwei") @SaCheckPermission("system:route:updaDateCangwei")
@PostMapping(value = "/updaDateCangwei", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PostMapping(value = "/updaDateCangwei", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ -318,10 +324,10 @@ public class EleMaterialsController extends BaseController {
List<JdVMIVo> list = result.getList(); List<JdVMIVo> list = result.getList();
// 创建固定大小的线程池 // 创建固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数 ExecutorService executor = Executors.newFixedThreadPool(10);
list.forEach(vmi -> executor.submit(() -> { list.forEach(vmi -> executor.submit(() -> {
log.info("===============>开始查询物料编码: " + vmi.getMaterialCode()+"的entryID"); log.info("===============>开始查询物料编码: " + vmi.getMaterialCode() + "的entryID");
List<JdEntryVmi> entryID = JdUtil.getEntryID2(vmi.getMaterialCode()); List<JdEntryVmi> entryID = JdUtil.getEntryID2(vmi.getMaterialCode());
entryID.forEach(jdEntryVmi -> { entryID.forEach(jdEntryVmi -> {
int fmaterialid = jdEntryVmi.getFMATERIALID(); int fmaterialid = jdEntryVmi.getFMATERIALID();
@ -356,14 +362,15 @@ public class EleMaterialsController extends BaseController {
public R<Void> updaDateKuCun(@RequestParam("file") MultipartFile file) throws Exception { public R<Void> updaDateKuCun(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename(); String originalFilename = file.getOriginalFilename();
log.info("读取文件名: " + originalFilename); log.info("读取文件名: " + originalFilename);
ExcelResult<JDSafeStockDTO> result = ExcelUtil.importExcelSheet1(file.getInputStream(), JDSafeStockDTO.class, true); ExcelResult<JDSafeStockDTO> result = ExcelUtil.importExcelSheet1(file.getInputStream(), JDSafeStockDTO.class,
true);
List<JDSafeStockDTO> list = result.getList(); List<JDSafeStockDTO> list = result.getList();
// 创建固定大小的线程池 // 创建固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数 ExecutorService executor = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数
list.forEach(vmi -> executor.submit(() -> { list.forEach(vmi -> executor.submit(() -> {
log.info("===============>开始查询物料编码: " + vmi.getMaterialCode()+"的entryID"); log.info("===============>开始查询物料编码: " + vmi.getMaterialCode() + "的entryID");
List<SubHeadEntityDTO> entryID = JdUtil.getSubHeadEntity1Id(vmi.getMaterialCode()); List<SubHeadEntityDTO> entryID = JdUtil.getSubHeadEntity1Id(vmi.getMaterialCode());
entryID.forEach(jdEntryVmi -> { entryID.forEach(jdEntryVmi -> {
int fmaterialid = jdEntryVmi.getFMATERIALID(); int fmaterialid = jdEntryVmi.getFMATERIALID();
@ -392,4 +399,90 @@ public class EleMaterialsController extends BaseController {
return R.ok("更新成功"); return R.ok("更新成功");
} }
@Log(title = "更新安全库存", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:updateFOldNumber")
@PostMapping(value = "/updateFOldNumber", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> updateFOldNumber(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
log.info("读取文件名: {}", originalFilename);
ExcelResult<JDMaterialOldNumber> result = ExcelUtil.importExcelSheet1(file.getInputStream(), JDMaterialOldNumber.class, true);
List<JDMaterialOldNumber> list = result.getList();
// 创建固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数
try {
List<Future<Void>> futures = new ArrayList<>();
for (JDMaterialOldNumber vmi : list) {
futures.add(executor.submit(() -> {
JdUtil.updateOldFuNumber(vmi.getFMATERIALID(), vmi.getFNumber(), vmi.getFOldNumber());
return null; // 返回值可以是 Void
}));
}
// 等待所有任务完成并处理异常
for (Future<Void> future : futures) {
try {
future.get(); // 获取结果如果有异常会抛出
} catch (ExecutionException e) {
log.error("更新物料时发生异常: {}", e.getCause().getMessage());
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 保留中断状态
log.error("线程被中断: {}", e.getMessage());
} finally {
executor.shutdown(); // 确保线程池关闭
try {
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow(); // 超时后强制关闭
}
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt(); // 保留中断状态
}
}
return R.ok("更新成功");
}
@Log(title = "更新物料单重", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:updateDanzhong")
@PostMapping(value = "/updateDanzhong", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> updateDanzhong(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
log.info("读取文件名: " + originalFilename);
ExcelResult<JdDanZhong> result = ExcelUtil.importExcelSheet1(file.getInputStream(), JdDanZhong.class, true);
List<JdDanZhong> list = result.getList();
// 创建固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(10);
list.forEach(vmi -> executor.submit(() -> {
List<JdEntryVmi> entryID = JdUtil.getEntryID2(vmi.getMaterialCode());
entryID.forEach(jdEntryVmi -> {
int fmaterialid = jdEntryVmi.getFMATERIALID();
try {
log.info("=====================>开始更新 " + vmi.getMaterialCode() + " 的单重");
JdUtil.updateDanzhong(fmaterialid,vmi.getDanzhong() );
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}));
// 关闭线程池并等待所有任务完成
executor.shutdown();
try {
if (!executor.awaitTermination(60, TimeUnit.MINUTES)) {
executor.shutdownNow(); // 超时后强制关闭
}
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt(); // 保留中断状态
}
return R.ok("更新成功");
}
} }

View File

@ -188,20 +188,7 @@ public class ImMaterialController extends BaseController {
e.printStackTrace(); e.printStackTrace();
} }
} }
// 更新数据库中物料单重的示例方法
/* private void updateMaterialWeight(String materialCode, Double weight) {
ImMaterial materialByCode = iImMaterialService.getMaterialByCode(materialCode);
if (materialByCode != null) {
materialByCode.setSingleWeight(BigDecimal.valueOf(weight));
imMaterialMapper.updateById(materialByCode);
} else {
// 处理物料编码不存在的情况
}
} catch (Exception e) {
// 处理数据库操作的异常
e.printStackTrace();
}
}*/
/** /**
* 导入数据 * 导入数据
* *

View File

@ -8,22 +8,31 @@ import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.JdUtils; import com.ruoyi.common.utils.JdUtils;
import com.ruoyi.system.domain.ImMaterial;
import com.ruoyi.system.domain.bo.ImMaterialBo; import com.ruoyi.system.domain.bo.ImMaterialBo;
import com.ruoyi.system.domain.bo.ImProductionPlanBo; import com.ruoyi.system.domain.bo.ImProductionPlanBo;
import com.ruoyi.system.domain.dto.JDInventoryDTO;
import com.ruoyi.system.domain.dto.JDProductionDTO;
import com.ruoyi.system.domain.dto.ProMoDTO;
import com.ruoyi.system.domain.dto.PurchaseOrderDTO;
import com.ruoyi.system.domain.vo.ImMaterialVo; import com.ruoyi.system.domain.vo.ImMaterialVo;
import com.ruoyi.system.domain.vo.InventoryInfoVO; import com.ruoyi.system.domain.vo.InventoryInfoVO;
import com.ruoyi.system.runner.JdUtil;
import com.ruoyi.system.service.IImMaterialService; import com.ruoyi.system.service.IImMaterialService;
import com.ruoyi.system.service.IImProductionPlanService; import com.ruoyi.system.service.IImProductionPlanService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.Optional;
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@RequestMapping("/index") @RequestMapping("/index")
@Slf4j
public class IndexController { public class IndexController {
private final IImMaterialService iImMaterialService; private final IImMaterialService iImMaterialService;
private final IImProductionPlanService imProductionPlanService; private final IImProductionPlanService imProductionPlanService;
@ -39,19 +48,47 @@ public class IndexController {
@GetMapping("/inventory") @GetMapping("/inventory")
public R<InventoryInfoVO> handleData(String materialCode) { public R<InventoryInfoVO> handleData(String materialCode) {
Map<String, String> marilMap = JdUtils.selectKuCun(materialCode); double inventoryQty = Optional.ofNullable(JdUtil.getKuCun(materialCode))
if (marilMap.isEmpty() ) { .map(list ->list.stream()
// 处理查询失败的情况 .mapToDouble(JDInventoryDTO::getFBaseQty)
return R.fail("库存信息未找到"); .sum())
} .orElse(0.0);
log.info("查询子项物料的未领料量=============>"+System.currentTimeMillis());
// 查询子项物料的未领料量
double fNoPickedQty = Optional.ofNullable(JdUtil.getWeiLingliao(materialCode))
.map(list ->list.stream()
.mapToDouble(JDProductionDTO::getFNoPickedQty)
.sum())
.orElse(0.0);
System.out.println("获取生产订单未入库数量数量=============>"+System.currentTimeMillis());
// 获取生产订单未入库数量数量
double productionQty = Optional.ofNullable(JdUtil.getProMoList(materialCode))
.map(list -> list.stream()
.mapToDouble(ProMoDTO::getFQty)
.sum())
.orElse(0.0);
System.out.println("获取采购订单未入库数量=============>"+System.currentTimeMillis());
// 获取采购订单未入库数量
double purchaseQty = Optional.ofNullable(JdUtil.getPurchaseOrderList(materialCode))
.map(list -> list.stream()
.mapToDouble(PurchaseOrderDTO::getFRemainStockINQty)
.sum())
.orElse(0.0);
// 计算预计可用库存
System.out.println("计算预计可用库存=============>"+System.currentTimeMillis());
Double keyong = inventoryQty + productionQty + purchaseQty - fNoPickedQty;
InventoryInfoVO inventoryInfoVO = new InventoryInfoVO(); InventoryInfoVO inventoryInfoVO = new InventoryInfoVO();
inventoryInfoVO.setMaterialCode(marilMap.get("materialCode")); inventoryInfoVO.setMaterialCode(materialCode);
inventoryInfoVO.setQuantity(marilMap.get("inventory")); inventoryInfoVO.setKucun(String.valueOf(inventoryQty));
inventoryInfoVO.setMaterialName(marilMap.get("materialName")); inventoryInfoVO.setQuantity(String.valueOf(fNoPickedQty));
inventoryInfoVO.setStockName(marilMap.get("stockName")); inventoryInfoVO.setMaterialName(String.valueOf(purchaseQty));
inventoryInfoVO.setStockUnit(marilMap.get("stockUnit")); inventoryInfoVO.setStockName(String.valueOf(productionQty));
inventoryInfoVO.setStockUnit(String.valueOf(keyong));
return R.ok(inventoryInfoVO); return R.ok(inventoryInfoVO);
} }
@Log(title = "生产计划") @Log(title = "生产计划")
@PostMapping("/JDList") @PostMapping("/JDList")
public void synchronize_lists() { public void synchronize_lists() {

View File

@ -1,14 +1,12 @@
package com.ruoyi.system.controller; package com.ruoyi.system.controller;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.*;
import java.util.Date;
import java.util.List;
import java.util.Arrays;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
@ -21,16 +19,30 @@ import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.kingdee.bos.webapi.sdk.K3CloudApi; import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ruoyi.common.utils.HttpRequestUtil; import com.ruoyi.common.utils.HttpRequestUtil;
import com.ruoyi.common.utils.WxRobotUtil; import com.ruoyi.common.utils.WxRobotUtil;
import com.ruoyi.system.domain.SafetyStock;
import com.ruoyi.system.domain.WlStockData;
import com.ruoyi.system.domain.dto.JDInventoryDTO;
import com.ruoyi.system.domain.dto.JDProductionDTO;
import com.ruoyi.system.domain.dto.ProMoDTO;
import com.ruoyi.system.domain.dto.PurchaseOrderDTO;
import com.ruoyi.system.domain.vo.SafetyStockVo;
import com.ruoyi.system.domain.vo.WlStockDataVo;
import com.ruoyi.system.mapper.SafetyStockMapper;
import com.ruoyi.system.mapper.WlStockDataMapper;
import com.ruoyi.system.runner.JdUtil;
import com.ruoyi.system.service.ISafetyStockService;
import com.xxl.job.core.handler.annotation.XxlJob; import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*; import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
@ -70,6 +82,8 @@ public class KingdeeWorkCenterDataController extends BaseController {
private final IKingdeeWorkCenterDataService iKingdeeWorkCenterDataService; private final IKingdeeWorkCenterDataService iKingdeeWorkCenterDataService;
private final HttpRequestUtil httpRequestUtil; private final HttpRequestUtil httpRequestUtil;
private static final Logger log = LoggerFactory.getLogger(KingdeeWorkCenterDataController.class); private static final Logger log = LoggerFactory.getLogger(KingdeeWorkCenterDataController.class);
private final WlStockDataMapper baseMapper;
private final ISafetyStockService iSafetyStockService;
/** /**
* 查询金蝶工段数据列表 * 查询金蝶工段数据列表
@ -142,13 +156,13 @@ public class KingdeeWorkCenterDataController extends BaseController {
@SaCheckPermission("system:workCenterData:remove") @SaCheckPermission("system:workCenterData:remove")
@Log(title = "金蝶工段数据提前2天", businessType = BusinessType.DELETE) @Log(title = "金蝶工段数据提前2天", businessType = BusinessType.DELETE)
@PostMapping("/getKingdeeWorkCenterData") @PostMapping("/getKingdeeWorkCenterData")
public R<List<KingdeeWorkCenterDataBo>> getKingdeeWorkCenterData(@RequestParam(value="workCenter") String workCenter) { public R<List<KingdeeWorkCenterDataBo>> getKingdeeWorkCenterData(@RequestParam(value = "workCenter") String workCenter) {
try { try {
K3CloudApi client = new K3CloudApi(); K3CloudApi client = new K3CloudApi();
JsonObject parameter = new JsonObject(); JsonObject parameter = new JsonObject();
List<KingdeeWorkCenterDataBo> kingdeeWorkCenterDataVos = new ArrayList<>(); List<KingdeeWorkCenterDataBo> kingdeeWorkCenterDataVos = new ArrayList<>();
parameter.addProperty("FWorkCenterName", workCenter); parameter.addProperty("FWorkCenterName", workCenter);
Object[] parameters = new Object[] { parameter.toString() }; Object[] parameters = new Object[]{parameter.toString()};
String execute = client.execute( String execute = client.execute(
"Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi", "Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi",
parameters); parameters);
@ -263,7 +277,12 @@ public class KingdeeWorkCenterDataController extends BaseController {
"> 数量信息:计划<font color=\"comment\">1.00</font>,已转入<font color=\"comment\">1.00</font>,已转出<font color=\"comment\">0.00</font>\n\n" "> 数量信息:计划<font color=\"comment\">1.00</font>,已转入<font color=\"comment\">1.00</font>,已转出<font color=\"comment\">0.00</font>\n\n"
+ +
"请相关部门负责人关注并及时处理!"; "请相关部门负责人关注并及时处理!";
wxRobotUtil.sendMarkdownMsgToWeChatGroup(markdownMsg, robotId); String messageContent = markdownMsg;
int maxLength = 4096;
for (int i = 0; i < messageContent.length(); i += maxLength) {
String part = messageContent.substring(i, Math.min(i + maxLength, messageContent.length()));
wxRobotUtil.sendMarkdownMsgToWeChatGroup(part, robotId);
}
return R.ok(); return R.ok();
} }
@ -279,7 +298,7 @@ public class KingdeeWorkCenterDataController extends BaseController {
K3CloudApi client = new K3CloudApi(); K3CloudApi client = new K3CloudApi();
JsonObject parameter = new JsonObject(); JsonObject parameter = new JsonObject();
parameter.addProperty("FWorkCenterName", "委外中心"); parameter.addProperty("FWorkCenterName", "委外中心");
Object[] parameters = new Object[] { parameter.toString() }; Object[] parameters = new Object[]{parameter.toString()};
String execute = client.execute( String execute = client.execute(
"Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi", "Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi",
parameters); parameters);
@ -336,7 +355,12 @@ public class KingdeeWorkCenterDataController extends BaseController {
// 添加结束语 // 添加结束语
markdownMsg.append("请相关部门负责人关注并及时处理!"); markdownMsg.append("请相关部门负责人关注并及时处理!");
// 发送消息 // 发送消息
wxRobotUtil.sendMarkdownMsgToWeChatGroup(markdownMsg.toString(), robotId); String messageContent = markdownMsg.toString();
int maxLength = 4096;
for (int i = 0; i < messageContent.length(); i += maxLength) {
String part = messageContent.substring(i, Math.min(i + maxLength, messageContent.length()));
wxRobotUtil.sendMarkdownMsgToWeChatGroup(part, robotId);
}
return R.ok(); return R.ok();
@ -412,13 +436,13 @@ public class KingdeeWorkCenterDataController extends BaseController {
@SaCheckPermission("system:workCenterData:remove") @SaCheckPermission("system:workCenterData:remove")
@Log(title = "金蝶工段数据延期数据", businessType = BusinessType.DELETE) @Log(title = "金蝶工段数据延期数据", businessType = BusinessType.DELETE)
@PostMapping("/getKingdeeDelayData") @PostMapping("/getKingdeeDelayData")
public R<List<KingdeeWorkCenterDataBo>> getKingdeeDelayData(@RequestParam(value="workCenter") String workCenter) { public R<List<KingdeeWorkCenterDataBo>> getKingdeeDelayData(@RequestParam(value = "workCenter") String workCenter) {
try { try {
K3CloudApi client = new K3CloudApi(); K3CloudApi client = new K3CloudApi();
JsonObject parameter = new JsonObject(); JsonObject parameter = new JsonObject();
List<KingdeeWorkCenterDataBo> kingdeeWorkCenterDataVos = new ArrayList<>(); List<KingdeeWorkCenterDataBo> kingdeeWorkCenterDataVos = new ArrayList<>();
parameter.addProperty("FWorkCenterName", workCenter); parameter.addProperty("FWorkCenterName", workCenter);
Object[] parameters = new Object[] { parameter.toString() }; Object[] parameters = new Object[]{parameter.toString()};
String execute = client.execute( String execute = client.execute(
"Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi", "Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi",
parameters); parameters);
@ -557,4 +581,255 @@ public class KingdeeWorkCenterDataController extends BaseController {
} }
} }
@Log(title = "金蝶安全库存数据", businessType = BusinessType.OTHER)
@XxlJob("getKuCun")
public R<Void> getKuCun() {
String robotId = "0d2390e0-3e74-49fc-bd02-900b86bf0f55";
StringBuilder markdownMsg = new StringBuilder();
// 获取今天的日期
Date today = new Date();
Date sixAM = DateUtil.parse(DateUtil.format(today, "yyyy-MM-dd") + " 06:00:00");
// 创建查询条件
LambdaQueryWrapper<WlStockData> safetyStockLambdaQueryWrapper = new LambdaQueryWrapper<>();
// 获取时间在今天6点以后的数据
safetyStockLambdaQueryWrapper.ge(WlStockData::getCreateTime, sixAM);
List<WlStockData> safetyStocks = baseMapper.selectList(safetyStockLambdaQueryWrapper);
log.info("查询安全库存结果===========>{}", safetyStocks);
// 处理物料分组
safetyStocks = processMaterialGroups(safetyStocks);
//对数据进行排序
safetyStocks.sort(Comparator.comparing(WlStockData::getMaterialCode));
try {
if (CollUtil.isEmpty(safetyStocks)) {
markdownMsg.append("## 🚀 安全库存提醒\n\n")
.append("今日暂无安全库存预警数据。");
} else {
markdownMsg.append("## 🚀 安全库存提醒\n\n")
.append("以下是今日的安全库存预警数据:\n\n");
// 只显示前三个安全库存数据
int count = Math.min(3, safetyStocks.size());
for (int i = 0; i < count; i++) {
WlStockData safetyStock = safetyStocks.get(i);
markdownMsg.append("### 物料信息\n")
.append("#### 物料编号: **").append(safetyStock.getMaterialCode()).append("**\n")
.append("> **物料名称:** ").append(safetyStock.getMaterialName()).append("\n")
.append("> **预计可用量:** ").append(String.format("%.2f", safetyStock.getCurrentStock())).append("\n")
.append("> **即时库存:** ").append(String.format("%.2f", safetyStock.getSecAvbqty())).append("\n")
.append("> **最大库存:** ").append(String.format("%.2f", safetyStock.getMaxsafetyStock())).append("\n")
.append("> **创建时间:** ").append(DateUtil.formatDateTime(safetyStock.getCreateTime())).append("\n")
.append("---\n"); // 添加分隔线
}
// 添加总数汇总
markdownMsg.append("### 总数汇总\n")
.append("> 今日安全库存预警数据总数: **").append(safetyStocks.size()).append("**\n");
}
// 生成Excel文件
String fileName = String.format("%s安全预警数据_%s.xlsx", "企标", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
String filePath = FileUtils.getTempDirectoryPath() + File.separator + fileName;
// 使用EasyExcel写入数据
EasyExcel.write(filePath, WlStockDataVo.class)
.sheet("工段数据")
.doWrite(BeanUtil.copyToList(safetyStocks, WlStockDataVo.class));
// 发送Excel文件
File excelFile = new File(filePath);
wxRobotUtil.sendFileToWeChatGroup(excelFile, robotId);
// 删除临时文件
FileUtils.deleteQuietly(excelFile);
markdownMsg.append("\n详细数据请查看发送的Excel文件");
String messageContent = markdownMsg.toString();
int maxLength = 1000;
for (int i = 0; i < messageContent.length(); i += maxLength) {
String part = messageContent.substring(i, Math.min(i + maxLength, messageContent.length()));
wxRobotUtil.sendMarkdownMsgToWeChatGroup(part, robotId);
}
return R.ok();
} catch (Exception e) {
markdownMsg.append("- ").append("安全库存").append(" (获取失败: ").append(e.getMessage()).append(")\n");
return R.fail("发送安全库存数据失败:" + e.getMessage());
}
}
private List<WlStockData> processMaterialGroups(List<WlStockData> originalStocks) {
if (CollUtil.isEmpty(originalStocks)) {
return new ArrayList<>();
}
// 创建新的结果列表
List<WlStockData> allStocks = new ArrayList<>(originalStocks);
// 定义四种类型
Map<String, List<String>> typeGroups = new HashMap<>();
typeGroups.put("行程检测白模具三", Arrays.asList("ELS-MJ.00.3-WH", "ELS-MJ.00.4-WH"));
typeGroups.put("行程检测灰模具三", Arrays.asList("ELS-MJ.00.3-GY", "ELS-MJ.00.4-GY"));
typeGroups.put("行程检测模具四", Arrays.asList("ELS-MJ.00.5", "ELS-MJ.00.6", "ELS-MJ.00.7", "ELS-MJ.00.8"));
typeGroups.put("行程检测模具五", Arrays.asList("ELS-MJ.00.9", "ELS-MJ.00.10", "ELS-MJ.00.11", "ELS-MJ.00.12", "ELS-MJ.00.13", "ELS-MJ.00.14"));
// 遍历原始数据检查每个物料所属的组
Map<String, Map<String, WlStockData>> groupMaterials = new HashMap<>();
for (WlStockData stock : originalStocks) {
String materialCode = stock.getMaterialCode();
// 检查该物料属于哪个组
for (Map.Entry<String, List<String>> entry : typeGroups.entrySet()) {
String groupType = entry.getKey();
List<String> groupCodes = entry.getValue();
if (groupCodes.contains(materialCode)) {
// 将物料添加到对应组的Map中
groupMaterials.computeIfAbsent(groupType, k -> new HashMap<>())
.put(materialCode, stock);
break;
}
}
}
// 处理每个有物料的组
for (Map.Entry<String, Map<String, WlStockData>> entry : groupMaterials.entrySet()) {
String groupType = entry.getKey();
Map<String, WlStockData> existingMaterials = entry.getValue();
List<String> groupAllMaterials = typeGroups.get(groupType);
if (!existingMaterials.isEmpty()) {
log.info("处理{}组, 已存在的物料: {}", groupType, existingMaterials.keySet());
// 获取该组的安全库存配置
List<SafetyStock> safetyStocks = iSafetyStockService.selectByType(groupType);
if (CollUtil.isEmpty(safetyStocks)) {
log.warn("{}组无安全库存配置数据", groupType);
continue;
}
// 找出该组中缺失的物料
for (String materialCode : groupAllMaterials) {
if (!existingMaterials.containsKey(materialCode)) {
log.info("{}组缺少物料: {}, 准备补充", groupType, materialCode);
// 查找对应的安全库存配置
SafetyStock matchingSafetyStock = safetyStocks.stream()
.filter(s -> s.getMaterialCode().equals(materialCode))
.findFirst()
.orElse(null);
if (matchingSafetyStock == null) {
log.warn("物料 {} 未找到对应的安全库存配置", materialCode);
continue;
}
// 获取同组中任意一个已存在的物料作为模板
WlStockData template = existingMaterials.values().iterator().next();
// 创建新的物料记录
WlStockData newStock = new WlStockData();
BeanUtil.copyProperties(template, newStock);
// 设置新物料的特定属性
newStock.setId(null);
newStock.setCreateTime(new Date());
newStock.setMaterialCode(materialCode);
newStock.setMaterialName(matchingSafetyStock.getMaterialName());
newStock.setWlMaterial(groupType);
newStock.setDocumentType(matchingSafetyStock.getWlMaterial());
// 复制模板物料的数量相关属性
newStock.setRequiredStock(template.getRequiredStock());
newStock.setCurrentStock(template.getCurrentStock());
newStock.setAvailableStock(template.getAvailableStock());
newStock.setProductionQty(template.getProductionQty());
newStock.setPurchaseQty(template.getPurchaseQty());
newStock.setMinsafetyStock(template.getMinsafetyStock());
newStock.setMaxsafetyStock(template.getMaxsafetyStock());
newStock.setSecAvbqty(template.getSecAvbqty());
try {
int result = baseMapper.insert(newStock);
if (result > 0) {
log.info("成功补充物料到数据库: 物料编码={}, 组={}, 使用模板物料={}",
materialCode, groupType, template.getMaterialCode());
allStocks.add(newStock);
} else {
log.error("补充物料到数据库失败: 物料编码={}, 组={}", materialCode, groupType);
}
} catch (Exception e) {
log.error("补充物料到数据库失败: 物料编码={}, 组={}, 错误信息={}",
materialCode, groupType, e.getMessage(), e);
}
}
}
} else {
log.info("{}组无任何物料存在,跳过处理", groupType);
}
}
log.info("物料处理完成,最终物料总数: {}", allStocks.size());
return allStocks;
}
@Log(title = "金蝶安全库存数据", businessType = BusinessType.OTHER)
@XxlJob("getKuCunTo40SB")
public R<Void> getKuCunTo40SB() {
String robotId = "0d2390e0-3e74-49fc-bd02-900b86bf0f55";
// 获取今天的日期
Date today = new Date();
Date sixAM = DateUtil.parse(DateUtil.format(today, "yyyy-MM-dd") + " 06:00:00");
//指定此物料:40SB/L
String materialCode = "40SB/L";
// 获取即时库存
double inventoryQty = Optional.ofNullable(JdUtil.getKuCun(materialCode))
.map(list ->list.stream()
.mapToDouble(JDInventoryDTO::getFBaseQty)
.sum())
.orElse(0.0);
// 查询子项物料的未领料量
double fNoPickedQty = Optional.ofNullable(JdUtil.getWeiLingliao(materialCode))
.map(list ->list.stream()
.mapToDouble(JDProductionDTO::getFNoPickedQty)
.sum())
.orElse(0.0);
// 获取生产订单未入库数量
double productionQty = Optional.ofNullable(JdUtil.getProMoList(materialCode))
.map(list -> list.stream()
.mapToDouble(ProMoDTO::getFQty)
.sum())
.orElse(0.0);
// 获取采购订单未入库数量
double purchaseQty = Optional.ofNullable(JdUtil.getPurchaseOrderList(materialCode))
.map(list -> list.stream()
.mapToDouble(PurchaseOrderDTO::getFRemainStockINQty)
.sum())
.orElse(0.0);
// 计算预计可用库存
double availableStock = inventoryQty + productionQty + purchaseQty - fNoPickedQty;
//生产订单未入库数量
//采购订单未入库数量
//子项物料的未领料量
//即时库存
//监控数量
// 构建Markdown消息
StringBuilder markdownMsg = new StringBuilder();
markdownMsg.append("# 实时库存告警通知\n\n")
.append("> **物料编码:** <font color=\"warning\">").append(materialCode).append("</font>\n")
.append("> **生产订单未入库:** <font color=\"comment\">").append(String.format("%.2f", productionQty)).append("</font>\n")
.append("> **采购订单未入库:** <font color=\"comment\">").append(String.format("%.2f", purchaseQty)).append("</font>\n")
.append("> **子项未领料数量:** <font color=\"warning\">").append(String.format("%.2f", fNoPickedQty)).append("</font>\n")
.append("> **当 前 库 存:** <font color=\"info\">").append(String.format("%.2f", inventoryQty)).append("</font>\n")
.append("> **预计可用库存:** <font color=\"warning\">").append(String.format("%.2f", availableStock)).append("</font>\n\n")
.append("> **创建时间:** ").append(DateUtil.formatDateTime(new Date())).append("\n");
String part = markdownMsg.toString();
wxRobotUtil.sendMarkdownMsgToWeChatGroup(part, robotId);
return R.ok();
}
} }

View File

@ -4,10 +4,11 @@ import java.io.*;
import java.util.List; import java.util.List;
import java.util.Arrays; import java.util.Arrays;
import com.alibaba.excel.EasyExcel;
import com.ruoyi.common.excel.DefaultExcelListener;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.file.SmbUtil;
import com.ruoyi.system.domain.ProcessRoute; import com.ruoyi.system.domain.ProcessRoute;
import com.ruoyi.system.domain.ProductionOrder;
import com.ruoyi.system.domain.bo.ProcessRouteBo;
import com.ruoyi.system.domain.dto.CombinedDTO;
import com.ruoyi.system.service.impl.ProductionOrderServiceImpl; import com.ruoyi.system.service.impl.ProductionOrderServiceImpl;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -117,5 +118,41 @@ public class ProcessOrderProController extends BaseController {
return iProcessOrderProService.deleteWithValidByIds(Arrays.asList(ids), true); return iProcessOrderProService.deleteWithValidByIds(Arrays.asList(ids), true);
} }
@SaCheckPermission("system:orderPro:getExcel")
@Log(title = "获取项目生产数据表", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/getExcel")
public R<Void> getExcel(@Validated(AddGroup.class) @RequestBody ProcessOrderProBo bo) {
// 获取项目生产数据表 获取项目令号 也是文件夹的名称
SmbUtil.downloadExcelFiles(bo.getProductionOrderNo());
// 在本地读取EXCEL 文件
String ExcelName = "D:\\file\\" + bo.getProductionOrderNo() + ".xlsx";
try {
File file = new File(ExcelName);
if (file.exists()) {
// 读取Excel的sheet6 从第三行开始 读取到第4列 无数据的跳过
DefaultExcelListener<ProcessRoute> listener = new DefaultExcelListener<>(true);
EasyExcel.read(ExcelName, ProcessRoute.class,listener).sheet(6).headRowNumber(3).doRead();
List<ProcessRoute> list = listener.getExcelResult().getList();
for (ProcessRoute processRoute : list) {
System.out.println(processRoute.getMaterialCode());
System.out.println(processRoute.getMaterialName());
System.out.println(processRoute.getMaterial());
System.out.println(processRoute.getDiscWeight());
System.out.println("===================================================================");
}
}else{
throw new ServiceException("没有数据");
}
} catch (Exception e) {
throw new RuntimeException(e);
}
//读取excel文件sheet
return toAjax(iProcessOrderProService.insertByBo(bo));
}
} }

View File

@ -1,6 +1,10 @@
package com.ruoyi.system.controller; package com.ruoyi.system.controller;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
@ -10,28 +14,26 @@ import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup; import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.excel.DefaultExcelListener;
import com.ruoyi.common.excel.ExcelResult; import com.ruoyi.common.excel.ExcelResult;
import com.ruoyi.common.utils.HttpRequestUtil; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.WxRobotUtil; import com.ruoyi.common.utils.file.SmbUtil;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.*; import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.bo.ProcessRouteBo; import com.ruoyi.system.domain.bo.ProcessRouteBo;
import com.ruoyi.system.domain.dto.*; import com.ruoyi.system.domain.dto.*;
import com.ruoyi.system.domain.vo.PlannedProcessVo; import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.jdmain.rouplan.Model; import com.ruoyi.system.jdmain.rouplan.Model;
import com.ruoyi.system.domain.vo.ProcessRouteVo;
import com.ruoyi.system.domain.vo.ProductionOrderVo;
import com.ruoyi.system.mapper.BomDetailsMapper; import com.ruoyi.system.mapper.BomDetailsMapper;
import com.ruoyi.system.mapper.ImMaterialMapper; import com.ruoyi.system.mapper.ImMaterialMapper;
import com.ruoyi.system.mapper.MaterialBomMapper; import com.ruoyi.system.mapper.MaterialBomMapper;
import com.ruoyi.system.mapper.ProcessRouteMapper; import com.ruoyi.system.mapper.ProcessRouteMapper;
import com.ruoyi.system.runner.JdUtil;
import com.ruoyi.system.service.IProcessRouteService; import com.ruoyi.system.service.IProcessRouteService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@ -45,8 +47,11 @@ import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.io.*; import java.io.*;
import java.nio.file.Files; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
/** /**
* 工艺路线 * 工艺路线
@ -217,19 +222,124 @@ public class ProcessRouteController extends BaseController {
child.setXuEndTime(processRouteVo.getXuEndTime()); child.setXuEndTime(processRouteVo.getXuEndTime());
return child; return child;
} }
/** /**
* 导出工艺路线列表 * 导出工艺路线列表
*/ */
@SaCheckPermission("system:route:export") @SaCheckPermission("system:route:export")
@Log(title = "工艺路线", businessType = BusinessType.EXPORT) @Log(title = "工艺路线", businessType = BusinessType.EXPORT)
@PostMapping("/export2")
public void export2(ProcessRouteBo bo, HttpServletResponse response) {
log.info("获取项目生产数据表:{}", bo);
List<ProcessRoute> list = iProcessRouteService.queryList(bo);
List<MaterialUsageDTO2> bomlist = JdUtil.getPRD_PPBOM(bo.getRouteDescription());
//过滤bomlist 只要009开头的标准件
bomlist = bomlist.stream()
.filter(bom -> bom.getMaterialCode().startsWith("009"))
.collect(Collectors.toList());
if (list.isEmpty() && bomlist.isEmpty()) {
throw new ServiceException("没有数据");
}
try {
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("工艺路线", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
ServletOutputStream os = response.getOutputStream();
// 创建ExcelWriter
try (com.alibaba.excel.ExcelWriter excelWriter = EasyExcel.write(os)
.autoCloseStream(false) // 防止自动关闭流
.build()) {
// 写入工艺路线sheet
if (!list.isEmpty()) {
WriteSheet writeSheet1 = EasyExcel.writerSheet(0, "工艺路线")
.head(ProcessRoute.class)
.build();
excelWriter.write(list, writeSheet1);
}
// 写入标准件清单sheet
if (!bomlist.isEmpty()) {
WriteSheet writeSheet2 = EasyExcel.writerSheet(1, "标准件清单")
.head(MaterialUsageDTO2.class)
.build();
excelWriter.write(bomlist, writeSheet2);
}
}
} catch (Exception e) {
throw new RuntimeException("导出Excel异常: " + e.getMessage(), e);
}
}
@SaCheckPermission("system:route:export")
@Log(title = "工艺路线", businessType = BusinessType.EXPORT)
@PostMapping("/export") @PostMapping("/export")
public void export(ProcessRouteBo bo, HttpServletResponse response) { public void export(ProcessRouteBo bo, HttpServletResponse response) {
List<ProcessRouteVo> list = iProcessRouteService.queryList(bo); log.info("获取项目生产数据表:{}", bo);
List<ProcessRouteVo> list2 = iProcessRouteService.queryList2(bo); // 下载Excel模板
SmbUtil.downloadExcelFiles(bo.getRouteDescription());
ExcelUtil.exportExceluseRoute(list, "工艺路线", ProcessRouteVo.class, response); // 构建Excel文件路径
String ExcelName = "D:\\file\\" + bo.getRouteDescription() + "汇总表.xlsx";
File file = new File(ExcelName);
if (!file.exists()) {
throw new ServiceException("文件不存在,请确认路径是否正确");
} }
//读取file的所有的物料编码
try {
if (file.exists()) {
// 读取Excel的sheet6 从第三行开始 读取到第4列 无数据的跳过
DefaultExcelListener<ProcessRoute> listener = new DefaultExcelListener<>(true);
EasyExcel.read(ExcelName, ProcessRoute.class,listener)
.sheet(6)
.headRowNumber(3)
.doRead();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
// 查询要写入的数据是否
List<ProcessRoute> list = iProcessRouteService.queryList(bo);
try {
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("工艺路线", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
ServletOutputStream os = response.getOutputStream();
// 使用 EasyExcel 写入已有Excel的第七个sheetindex=6
try (com.alibaba.excel.ExcelWriter excelWriter = EasyExcel.write(os)
.withTemplate(file) // 指定模板文件
.autoCloseStream(true)
.build()) {
// 写入到第七个 sheetindex=6并命名为工艺路线
WriteSheet writeSheet = EasyExcel.writerSheet( "已有工艺路线")
.head(ProcessRoute.class)
.needHead(true)
.build();
excelWriter.write(list, writeSheet);
}
os.flush();
} catch (Exception e) {
log.error("导出Excel异常", e);
throw new RuntimeException("导出Excel异常: " + e.getMessage(), e);
}
}
/** /**
* 获取工艺路线详细信息 * 获取工艺路线详细信息
@ -253,7 +363,7 @@ public class ProcessRouteController extends BaseController {
return toAjax(iProcessRouteService.insertByBo(bo)); return toAjax(iProcessRouteService.insertByBo(bo));
} }
/** /**导出
* 修改工艺路线 * 修改工艺路线
*/ */
@SaCheckPermission("system:route:edit") @SaCheckPermission("system:route:edit")
@ -448,8 +558,7 @@ public class ProcessRouteController extends BaseController {
@RequestParam(value = "materialName") String materialName, @RequestParam(value = "materialName") String materialName,
@RequestParam(value = "productionOrderNo") String productionOrderNo) { @RequestParam(value = "productionOrderNo") String productionOrderNo) {
return ResponseEntity return ResponseEntity.ok(iProcessRouteService.getProcessRouteList(materialCode, materialName, productionOrderNo));
.ok(iProcessRouteService.getProcessRouteList(materialCode, materialName, productionOrderNo));
} }
@Log(title = "导入时间", businessType = BusinessType.IMPORT) @Log(title = "导入时间", businessType = BusinessType.IMPORT)
@ -465,6 +574,25 @@ public class ProcessRouteController extends BaseController {
return R.ok("更新成功"); return R.ok("更新成功");
} }
@Log(title = "导入时间", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:importDataTime")
@PostMapping(value = "/importDataTime123", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importDataTime123(@RequestParam("file") MultipartFile file) throws Exception {
DefaultExcelListener<PcRigidChainVO> listener = new DefaultExcelListener<>(true);
EasyExcel.read(file.getInputStream(), PcRigidChainVO.class,listener) .excelType(ExcelTypeEnum.XLS).sheet(1).headRowNumber(4).doRead();
List<PcRigidChainVO> list1 = listener.getExcelResult().getList();
for (PcRigidChainVO pcRigidChainVO : list1) {
log.info("数据 ===============>: " + JSONUtil.toJsonStr(pcRigidChainVO));
}
return R.ok("更新成功");
}
@Log(title = "获取金蝶工艺路线") @Log(title = "获取金蝶工艺路线")
@SaCheckPermission("system:route:getSelectProcessRoute") @SaCheckPermission("system:route:getSelectProcessRoute")
@PostMapping("/getSelectProcessRout1e") @PostMapping("/getSelectProcessRout1e")
@ -472,8 +600,7 @@ public class ProcessRouteController extends BaseController {
return iProcessRouteService.getSelectProcessRoute(materilCode); return iProcessRouteService.getSelectProcessRoute(materilCode);
} }
private void processCombinedDTO(CombinedDTO combinedDTO, List<BomDetails> bomDetailsList, private void processCombinedDTO(CombinedDTO combinedDTO, List<BomDetails> bomDetailsList, List<ProcessRoute> routeList, List<MaterialBom> materialBoms, String productionOrderNo) {
List<ProcessRoute> routeList, List<MaterialBom> materialBoms, String productionOrderNo) {
// 处理工序列表 // 处理工序列表
combinedDTO.getProcesses().forEach(process -> { combinedDTO.getProcesses().forEach(process -> {
ProcessRoute processRoute = createProcessRoute(process, combinedDTO, productionOrderNo); ProcessRoute processRoute = createProcessRoute(process, combinedDTO, productionOrderNo);
@ -491,6 +618,106 @@ public class ProcessRouteController extends BaseController {
}); });
} }
private void processMaterAndRoute(JDMaterialAndRoute materialAndRoute, List<BomDetails> bomDetailsList, List<ProcessRoute> routeList, List<MaterialBom> materialBoms, String productionOrderNo) {
// 处理工序列表
materialAndRoute.getPlannedProcessVos().forEach(processRouteDTO -> {
ProcessRoute processRoute = createProcessRoute1(processRouteDTO, materialAndRoute, productionOrderNo);
routeList.add(processRoute);
});
// 处理物料清单
materialAndRoute.getMaterialUseDTOS().forEach(materialUsageDTO -> {
BomDetails bomDetails = createBomDetails1(materialUsageDTO, materialAndRoute, productionOrderNo);
bomDetailsList.add(bomDetails);
});
// 处理材料BOM
materialAndRoute.getMaterialUseDTOS().forEach(materialUsageDTO -> {
MaterialBom materialBom = creatBomMaterial1(materialUsageDTO, materialAndRoute, productionOrderNo);
materialBoms.add(materialBom);
});
}
private MaterialBom creatBomMaterial1(MaterialUseDTO materialUsageDTO, JDMaterialAndRoute materialAndRoute, String productionOrderNo) {
MaterialBom materialBom = new MaterialBom();
materialBom.setProjectNumber(productionOrderNo);
materialBom.setParentMaterialCode(materialAndRoute.getMaterialCode());
materialBom.setParentMaterialName(materialAndRoute.getMaterialName());
materialBom.setMaterialCode(materialUsageDTO.getMaterialCode());
materialBom.setMaterialName(materialUsageDTO.getMaterialName());
materialBom.setUnit(materialUsageDTO.getChildUnit());
materialBom.setMaterialType(materialUsageDTO.getCaizhi());
//保留四位小数
materialBom.setQuantity( new BigDecimal(materialUsageDTO.getFenzi()).divide(new BigDecimal(materialUsageDTO.getFenmu()),2, RoundingMode.HALF_UP));
return materialBom;
}
private BomDetails createBomDetails1(MaterialUseDTO materialUsageDTO, JDMaterialAndRoute materialAndRoute, String productionOrderNo) {
BomDetails bomDetails = new BomDetails();
bomDetails.setTotalWeight(productionOrderNo);
bomDetails.setFNumber(materialAndRoute.getMaterialCode());
bomDetails.setFName(materialAndRoute.getMaterialName());
bomDetails.setPartNumber(materialUsageDTO.getMaterialCode());
bomDetails.setUnitWeight("");
//子项分子
bomDetails.setQuantity(Double.valueOf(materialUsageDTO.getFenzi()));
//子项分母
bomDetails.setDenominator(Double.valueOf(materialUsageDTO.getFenmu()));
bomDetails.setName(materialUsageDTO.getMaterialName());
/* if (materialUsageDTO.getItemType().equals("1")){
bomDetails.setStats("外购");
}else{
bomDetails.setStats("自制");
}*/
bomDetails.setMaterial(materialUsageDTO.getCaizhi());
return bomDetails;
}
private ProcessRoute createProcessRoute1(ProcessRouteDTO processRouteDTO, JDMaterialAndRoute materialAndRoute, String productionOrderNo) {
ProcessRoute processRoute = new ProcessRoute();
// 设置路线描述为生产订单号
processRoute.setRouteDescription(productionOrderNo);
// 设置工序号
processRoute.setProcessNo(processRouteDTO.getProcessNo());
// 设置工序名称
processRoute.setProcessName(processRouteDTO.getProcessName());
processRoute.setDiscWeight(Double.valueOf(materialAndRoute.getDanzhong()));
processRoute.setMaterial(materialAndRoute.getCaizhi());
// 设置物料代码
processRoute.setMaterialCode(materialAndRoute.getMaterialCode());
processRoute.setMaterialName(materialAndRoute.getMaterialName());
processRoute.setWorkCenter(processRouteDTO.getWorkCenter());
// 基本时长
processRoute.setActivityDuration(processRouteDTO.getActivityDuration());
processRoute.setProcessDescription(processRouteDTO.getProcessDescription());
processRoute.setProcessControl(processRouteDTO.getProcessControl());
processRoute.setXuStartTime(null);
processRoute.setXuEndTime(null);
processRoute.setActivityUnit("");
// 本批数量对应
processRoute.setBatchQuantity(materialAndRoute.getBenpi());
processRoute.setFirstBatchQuantity(Double.valueOf(materialAndRoute.getDantai()));
List<MaterialUseDTO> materialUsageDTOList = materialAndRoute.getMaterialUseDTOS();
for (MaterialUseDTO materialUsageDTO : materialUsageDTOList) {
processRoute.setUnitQuantity(Double.valueOf(materialUsageDTO.getFenzi()));
processRoute.setRawMaterialCode(materialUsageDTO.getMaterialCode());
processRoute.setRawMaterialName(materialUsageDTO.getMaterialName());
processRoute.setBomUnit(materialUsageDTO.getChildUnit());
if (materialUsageDTO.getChildUnit().equals("")) {
processRoute.setDiscUsage(Double.valueOf(materialUsageDTO.getFenmu()));
} else {
processRoute.setDiscUsage((double) (materialUsageDTO.getFenzi() / materialUsageDTO.getFenmu()));
}
processRoute.setMaterial(materialUsageDTO.getCaizhi());
}
return processRoute;
}
@Log(title = "生成金蝶标准工艺") @Log(title = "生成金蝶标准工艺")
@SaCheckPermission("system:route:getKindeeExcel") @SaCheckPermission("system:route:getKindeeExcel")
@ -519,8 +746,7 @@ public class ProcessRouteController extends BaseController {
} }
} }
private ProcessRoute createProcessRoute(PlannedProcessVo process, CombinedDTO combinedDTO, private ProcessRoute createProcessRoute(PlannedProcessVo process, CombinedDTO combinedDTO, String productionOrderNo) {
String productionOrderNo) {
ProcessRoute processRoute = new ProcessRoute(); ProcessRoute processRoute = new ProcessRoute();
// 设置路线描述为生产订单号 // 设置路线描述为生产订单号
processRoute.setRouteDescription(productionOrderNo); processRoute.setRouteDescription(productionOrderNo);
@ -572,8 +798,7 @@ public class ProcessRouteController extends BaseController {
return processRoute; return processRoute;
} }
private BomDetails createBomDetails(MaterialUsageDTO materialUsageDTO, CombinedDTO combinedDTO, private BomDetails createBomDetails(MaterialUsageDTO materialUsageDTO, CombinedDTO combinedDTO, String productionOrderNo) {
String productionOrderNo) {
BomDetails bomDetails = new BomDetails(); BomDetails bomDetails = new BomDetails();
bomDetails.setTotalWeight(productionOrderNo); bomDetails.setTotalWeight(productionOrderNo);
bomDetails.setFNumber(combinedDTO.getMaterialCode()); bomDetails.setFNumber(combinedDTO.getMaterialCode());
@ -605,8 +830,58 @@ public class ProcessRouteController extends BaseController {
materialBom.setMaterialName(materialUsageDTO.getMaterialName()); materialBom.setMaterialName(materialUsageDTO.getMaterialName());
materialBom.setUnit(materialUsageDTO.getUnit()); materialBom.setUnit(materialUsageDTO.getUnit());
materialBom.setMaterialType(materialUsageDTO.getItemType()); materialBom.setMaterialType(materialUsageDTO.getItemType());
materialBom.setQuantity(String.valueOf(materialUsageDTO.getRequiredQty())); materialBom.setQuantity(BigDecimal.valueOf(materialUsageDTO.getFNumerator()));
return materialBom; return materialBom;
} }
/**
* 导出工艺路线列表
*/
@SaCheckPermission("system:route:getAllRouteAndUse")
@Log(title = "获取全部工艺路线和物料清单", businessType = BusinessType.OTHER)
@PostMapping("/getAllRouteAndUse")
public void getAllRouteAndUse(@RequestParam("rooteProdet") String rooteProdet) {
log.info("获取项目生产数据表:{}", rooteProdet);
// 下载Excel模板
SmbUtil.downloadExcelFiles(rooteProdet);
// 构建Excel文件路径
String ExcelName = "D:\\file\\" + rooteProdet + "汇总表.xlsx";
File file = new File(ExcelName);
if (!file.exists()) {
throw new ServiceException("文件不存在,请确认路径是否正确");
}
List<ProcessRoute> processRoutes = new ArrayList<>();
//读取file的所有的物料编码
try {
if (file.exists()) {
// 读取Excel的sheet6 从第三行开始 读取到第4列 无数据的跳过
DefaultExcelListener<ProcessRouteVo> listener = new DefaultExcelListener<>(true);
EasyExcel.read(ExcelName, ProcessRouteVo.class, listener)
.sheet(6)
.headRowNumber(3)
.doRead();
List<ProcessRouteVo> list = listener.getExcelResult().getList();
List<JDMaterialAndRoute> list1 = iProcessRouteService.getProcessRouteGD(list);
List<BomDetails> bomDetailsList = new ArrayList<>();
List<ProcessRoute> routeList = new ArrayList<>();
List<MaterialBom> materialBoms = new ArrayList<>();
for (JDMaterialAndRoute materialAndRoute : list1) {
processMaterAndRoute(materialAndRoute, bomDetailsList, routeList, materialBoms, rooteProdet);
}
bomDetailsMapper.insertBatch(bomDetailsList);
baseMapper.insertBatch(routeList);
materialBomMapper.insertBatch(materialBoms);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
} }

View File

@ -67,7 +67,6 @@ public class WlStockDataController extends BaseController {
/** /**
* 获取安全库存单据详细信息 * 获取安全库存单据详细信息
*
* @param id 主键 * @param id 主键
*/ */
@SaCheckPermission("system:stockData:query") @SaCheckPermission("system:stockData:query")
@ -101,7 +100,6 @@ public class WlStockDataController extends BaseController {
/** /**
* 删除安全库存单据 * 删除安全库存单据
*
* @param ids 主键串 * @param ids 主键串
*/ */
@SaCheckPermission("system:stockData:remove") @SaCheckPermission("system:stockData:remove")
@ -114,8 +112,6 @@ public class WlStockDataController extends BaseController {
/** /**
* 生成安全库存单据 * 生成安全库存单据
*
* @return
*/ */
@SaCheckPermission("system:stockData:generateDoc") @SaCheckPermission("system:stockData:generateDoc")
@Log(title = "安全库存单据", businessType = BusinessType.OTHER) @Log(title = "安全库存单据", businessType = BusinessType.OTHER)
@ -128,10 +124,21 @@ public class WlStockDataController extends BaseController {
return R.ok(result); return R.ok(result);
} }
@Log(title = "安全库存")
@XxlJob("generateDoc2")
public R<List<WlStockData>> generateDoc1() {
List<WlStockData> result = iWlStockDataService.generateDoc();
if (result.isEmpty()) {
return R.fail("没有生成任何数据");
}
return R.ok(result);
}
@GetMapping("/logs") @GetMapping("/logs")
public List<String> getLogs(@RequestParam(value = "lastIndex", defaultValue = "0") int lastIndex) { public List<String> getLogs(@RequestParam(value = "lastIndex", defaultValue = "0") int lastIndex) {
List<String> logs = iWlStockDataService.getLogs(lastIndex); List<String> logs = iWlStockDataService.getLogs(lastIndex);
int nextIndex = lastIndex + logs.size(); int nextIndex = lastIndex + logs.size();
return logs; return logs;
} }
} }

View File

@ -45,7 +45,7 @@ import java.util.Map;
/** /**
* 工序任务 * 工序任务
* *
* @author ruoyi * @author tzy
* @date 2024-06-27 * @date 2024-06-27
*/ */
@Validated @Validated
@ -54,7 +54,7 @@ import java.util.Map;
@RequestMapping("/system/procedure") @RequestMapping("/system/procedure")
public class WorkProcedureController extends BaseController { public class WorkProcedureController extends BaseController {
private static final Logger log = LoggerFactory.getLogger(KingdeeWorkCenterDataController.class); private static final Logger log = LoggerFactory.getLogger(WorkProcedureController.class);
private final IWorkProcedureService iWorkProcedureService; private final IWorkProcedureService iWorkProcedureService;
private final IKingdeeWorkCenterDataService iKingdeeWorkCenterDataService; private final IKingdeeWorkCenterDataService iKingdeeWorkCenterDataService;

View File

@ -96,5 +96,9 @@ public class BomDetails extends BaseEntity {
/** /**
* 单重 * 单重
*/ */
private Double danzhong; private Double danZhong;
/**
* 子项单重
*/
private Double singleWeghit;
} }

View File

@ -1,5 +1,6 @@
package com.ruoyi.system.domain; package com.ruoyi.system.domain;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.*;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data; import lombok.Data;
@ -28,37 +29,46 @@ public class MaterialBom extends BaseEntity {
/** /**
* 项目令号 * 项目令号
*/ */
@ExcelProperty("项目令号")
private String projectNumber; private String projectNumber;
/** /**
* 物料编码 * 物料编码
*/ */
@ExcelProperty("物料编码")
private String materialCode; private String materialCode;
/** /**
* 物料名称 * 物料名称
*/ */
@ExcelProperty("物料名称")
private String materialName; private String materialName;
/** /**
* 用量 * 用量
*/ */
private String quantity; @ExcelProperty("用量")
private BigDecimal quantity;
/** /**
* 单位 * 单位
*/ */
@ExcelProperty("单位")
private String unit; private String unit;
/** /**
* 材质 * 材质
*/ */
@ExcelProperty("材质")
private String materialType; private String materialType;
/** /**
* 父级物料编码 * 父级物料编码
*/ */
@ExcelProperty("父级物料编码")
private String parentMaterialCode; private String parentMaterialCode;
/** /**
* 父级物料名称 * 父级物料名称
*/ */
@ExcelProperty("父级物料名称")
private String parentMaterialName; private String parentMaterialName;
/** /**
* 库存 * 库存
*/ */
private Double stock; private Double stock;
} }

View File

@ -1,8 +1,12 @@
package com.ruoyi.system.domain; package com.ruoyi.system.domain;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -23,104 +27,159 @@ public class ProcessRoute extends BaseEntity {
private static final long serialVersionUID=1L; private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO) @TableId(value = "id", type = IdType.AUTO)
@ExcelIgnore
private Long id; private Long id;
/** /**
* 工艺路线描述 * 工艺路线描述
*/ */
@ColumnWidth(15)
@ExcelProperty(value={"生产令号","生产令号"},index=0)
private String routeDescription; private String routeDescription;
/** /**
* 物料编码 * 物料编码
*/ */
@ColumnWidth(20)
@ExcelProperty(value ={"物料编码","物料编码"},index=1 )
private String materialCode; private String materialCode;
/** /**
* 物料名称 * 物料名称
*/ */
@ColumnWidth(25)
@ExcelProperty(value ={"名称","名称"},index=2)
private String materialName; private String materialName;
/** /**
* 材料BOM单位 * 材料BOM单位
*/ */
@ColumnWidth(10)
@ExcelProperty(value={ "材料BOM","单位"},index=10)
private String bomUnit; private String bomUnit;
/**
* 材料BOM单位
*/
@ExcelProperty(value={ "材料BOM","材料单重KG"},index=8)
private Double bomDanZhong;
/** /**
* 工序号 * 工序号
*/ */
@ColumnWidth(10)
@ExcelProperty(value ={ "工序号","工序号"},index = 11)
private Long processNo; private Long processNo;
/** /**
* 工作中心加工车间 * 工作中心加工车间
*/ */
@ColumnWidth(20)
@ExcelProperty(value ={ "工作中心(加工车间)","工作中心(加工车间)"},index = 12)
private String workCenter; private String workCenter;
/** /**
* 工序名称 * 工序名称
*/ */
@ColumnWidth(20)
@ExcelProperty(value ={ "工序名称","工序名称"},index = 13)
private String processName; private String processName;
/** /**
* 材料BOM物料编码 * 材料BOM物料编码
*/ */
@ColumnWidth(20)
@ExcelProperty(value={ "材料BOM","物料编码"}, index=5)
private String rawMaterialCode; private String rawMaterialCode;
/** /**
* 材料BOM物料名称 * 材料BOM物料名称
*/ */
@ColumnWidth(25)
@ExcelProperty(value={ "材料BOM","物料名称"},index = 6)
private String rawMaterialName; private String rawMaterialName;
/** /**
* 单重KG * 单重KG
*/ */
@ColumnWidth(10)
@ExcelProperty(value={"单重KG","单重KG"},index=4)
private Double discWeight; private Double discWeight;
/** /**
* 材料BOM用量 * 材料BOM用量
*/ */
@ColumnWidth(10)
@ExcelProperty(value = { "材料BOM","用量"},index = 9)
private Double discUsage; private Double discUsage;
/** /**
* 工序说明序描述 * 工序说明序描述
*/ */
@ColumnWidth(30)
@ExcelProperty(value ={ "工序说明(序描述)","工序说明(序描述)"},index = 14)
private String processDescription; private String processDescription;
/** /**
* 工序控制 * 工序控制
*/ */
@ColumnWidth(20)
@ExcelProperty(value ={ "工序控制","工序控制"},index = 15)
private String processControl; private String processControl;
/** /**
* 活动时长 * 活动时长
*/ */
@ColumnWidth(10)
@ExcelProperty(value={ "活动时长","活动时长"},index = 16)
private Double activityDuration; private Double activityDuration;
/** /**
* 活动单位 * 活动单位
*/ */
@ColumnWidth(10)
@ExcelProperty(value={ "活动单位","活动单位"},index =17)
private String activityUnit; private String activityUnit;
/** /**
* bom材质 * bom材质
*/ */
@ColumnWidth(15)
@ExcelProperty(value={ "材料BOM","材质"},index = 7)
private String bomMaterial; private String bomMaterial;
/** /**
* 材质 * 材质
*/ */
@ColumnWidth(15)
@ExcelProperty(value={ "材质","材质"},index=3)
private String material; private String material;
/** /**
* 单台数量 * 单台数量
*/ */
@ColumnWidth(10)
@ExcelProperty(value = {"制件数量","单台数量"},index = 18)
private Double unitQuantity; private Double unitQuantity;
/** /**
* 本批数量 * 本批数量
*/ */
@ColumnWidth(10)
@ExcelProperty(value = {"制件数量","本批数量"},index = 19)
private Long batchQuantity; private Long batchQuantity;
/** /**
* 首批数量 * 首批数量
*/ */
@ExcelIgnore
private Double firstBatchQuantity; private Double firstBatchQuantity;
/** /**
* 计划开始时间 * 计划开始时间
*/ */
@ExcelIgnore
private Date planStartTime; private Date planStartTime;
/** /**
* 计划结束时间 * 计划结束时间
*/ */
@ExcelIgnore
private Date planEndTime; private Date planEndTime;
/** /**
* 序开始时间 * 序开始时间
*/ */
@ColumnWidth(15)
@ExcelProperty(value = {"计划完成时间","起始日期"},index = 20)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date xuStartTime; private Date xuStartTime;
/** /**
* 序结束时间 * 序结束时间
*/ */
@ColumnWidth(15)
@ExcelProperty(value = {"计划完成时间","完成日期"},index = 22)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date xuEndTime; private Date xuEndTime;
} }

View File

@ -34,6 +34,10 @@ public class SafetyStock extends BaseEntity {
* 物料名称 * 物料名称
*/ */
private String materialName; private String materialName;
/**
* 材质
*/
private String wlMaterial;
/** /**
* 最低安全库存 * 最低安全库存
*/ */
@ -46,4 +50,12 @@ public class SafetyStock extends BaseEntity {
* 当前库存 * 当前库存
*/ */
private Double currentStock; private Double currentStock;
/**
*分类
*/
private String type;
/**
* 单台数量
*/
private Long singleNum;
} }

View File

@ -37,11 +37,11 @@ public class WlStockData extends BaseEntity {
*/ */
private String materialName; private String materialName;
/** /**
* 所需库存 * 预计可用量
*/ */
private Double requiredStock; private Double requiredStock;
/** /**
* 当前库存 * 即时库存
*/ */
private Double currentStock; private Double currentStock;
/** /**
@ -53,7 +53,7 @@ public class WlStockData extends BaseEntity {
*/ */
private String documentType; private String documentType;
/** /**
* 可用库存 * 用料清单未领料数量
*/ */
private BigDecimal availableStock; private BigDecimal availableStock;
/** /**
@ -61,15 +61,15 @@ public class WlStockData extends BaseEntity {
*/ */
private BigDecimal secAvbqty; private BigDecimal secAvbqty;
/** /**
* 生产订单数量 * 生产订单未入库数量
*/ */
private BigDecimal productionQty; private BigDecimal productionQty;
/** /**
* 采购订单数量 * 采购订单未入库数量
*/ */
private BigDecimal purchaseQty; private BigDecimal purchaseQty;
/** /**
* 预留量 * 预留量X
*/ */
private BigDecimal secQty; private BigDecimal secQty;
/** /**
@ -84,4 +84,13 @@ public class WlStockData extends BaseEntity {
* 金蝶单据编码 * 金蝶单据编码
*/ */
private String doucCode; private String doucCode;
/**
* 材质
*/
private String wlMaterial;
/**
* 安全库存状态(符合1,不符合0)
*/
private int safeStatus;
} }

View File

@ -38,6 +38,12 @@ public class SafetyStockBo extends BaseEntity {
*/ */
@NotBlank(message = "物料名称不能为空", groups = { AddGroup.class, EditGroup.class }) @NotBlank(message = "物料名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String materialName; private String materialName;
/**
* 材质
*/
@NotBlank(message = "材质不能为空", groups = { AddGroup.class, EditGroup.class })
private String wlMaterial;
/** /**
* 最低安全库存 * 最低安全库存
@ -54,5 +60,11 @@ public class SafetyStockBo extends BaseEntity {
* 当前库存 * 当前库存
*/ */
private Double currentStock; private Double currentStock;
/**
*类型
*/
@NotBlank(message = "类型不能为空", groups = { AddGroup.class, EditGroup.class })
private String type;
} }

View File

@ -62,6 +62,11 @@ public class WlStockDataBo extends BaseEntity {
* 单据类型 (1: 最高库存单, 0: 最低库存单) * 单据类型 (1: 最高库存单, 0: 最低库存单)
*/ */
private String documentType; private String documentType;
/**
* 材质
*/
@NotBlank(message = "材质不能为空", groups = { AddGroup.class, EditGroup.class })
private String wlMaterial;
/** /**
* 可用库存 * 可用库存
@ -109,4 +114,9 @@ public class WlStockDataBo extends BaseEntity {
*/ */
@NotBlank(message = "金蝶单据编码不能为空", groups = { AddGroup.class, EditGroup.class }) @NotBlank(message = "金蝶单据编码不能为空", groups = { AddGroup.class, EditGroup.class })
private String doucCode; private String doucCode;
/**
* 安全库存状态(符合1,不符合0)
*/
private int safeStatus;
} }

View File

@ -0,0 +1,16 @@
package com.ruoyi.system.domain.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(name = "即时库存返回值")
public class JDInventoryDTO {
@JsonProperty("FMaterialId.FNumber")
private String FMaterialIdFNumber;
@JsonProperty("FMaterialName")
private String FMaterialName;
@JsonProperty("FBaseQty")
private Double FBaseQty;
}

View File

@ -0,0 +1,25 @@
package com.ruoyi.system.domain.dto;
import com.ruoyi.system.domain.vo.PlannedProcessVo;
import lombok.Data;
import okhttp3.Route;
import java.util.List;
/*
* @Description:用在获取物料清单和工艺路线固定
* @author: tzy
* 用在获取物料清单和工艺路线固定
* @date: 2025/5/16 15:03
*/
@Data
public class JDMaterialAndRoute {
private String materialCode; // 物料编码
private String materialName;
private String caizhi;
private String danzhong;
private Long benpi;
private Long dantai;
private List<MaterialUseDTO> materialUseDTOS;
private List<ProcessRouteDTO> plannedProcessVos;
}

View File

@ -0,0 +1,25 @@
package com.ruoyi.system.domain.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
@Data
public class JDMaterialOldNumber {
/**
* 编码
*/
@ExcelProperty(value = "FMATERIALID")
private String FMATERIALID;
/**
* 安全库存
*/
@ExcelProperty(value = "FNumber")
private String FNumber;
/**
* 最高库存
*/
@ExcelProperty(value = "FOldNumber")
private String FOldNumber;
}

View File

@ -0,0 +1,16 @@
package com.ruoyi.system.domain.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(name = "生产用料清单返回值获取")
public class JDProductionDTO {
@JsonProperty("FMaterialID2.FNumber")
private String FMaterialIdFNumber;
@JsonProperty("FMaterialName1")
private String FMaterialName;
@JsonProperty("FNoPickedQty")
private Double FNoPickedQty;
}

View File

@ -0,0 +1,50 @@
package com.ruoyi.system.domain.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class JdChildDTO {
/**
* 部件图号
*/
@JsonProperty("F_HBYT_BJBM")
private String partdiagramCode;
/**
* 部件名称
*/
@JsonProperty("F_HBYT_BJMC")
private String partdiagramName;
/**
* 子项物料单位
*/
@JsonProperty("FUNITID.FName")
private String wareHouse;
/**
*子项物料编码
*/
@JsonProperty("FMATERIALIDCHILD.FNumber")
private String partNumber;
/**
*子项物料名称
*/
@JsonProperty("FCHILDITEMNAME")
private String name;
/**
*属性
*/
@JsonProperty("FCHILDITEMPROPERTY")
private String stats;
/**
* 子项分子
*/
@JsonProperty("FNUMERATOR")
private Double quantity;
/**
* 子项分母
*/
@JsonProperty("FDENOMINATOR")
private Double denominator;
}

View File

@ -0,0 +1,25 @@
package com.ruoyi.system.domain.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
@Data
public class JdDanZhong {
/**
* 编码
*/
@ExcelProperty(value = "物料编码")
private String materialCode;
/**
* 名称
*/
@ExcelProperty(value = "物料名称")
private String materialName;
/**
* 仓库编码
*/
@ExcelProperty(value = "单重")
private String Danzhong;
}

View File

@ -0,0 +1,27 @@
package com.ruoyi.system.domain.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
@Data
public class JdValidateBomDTO {
/**
* FID
*/
@JsonProperty("FID")
private String FID;
/**
* 父级物料编码
*/
@JsonProperty("FMATERIALID.FNumber")
private String fNumber;
/**
* 父级物料名称
*/
@JsonProperty("FITEMNAME")
private String fName;
private List<JdChildDTO> childs;
}

View File

@ -0,0 +1,64 @@
package com.ruoyi.system.domain.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.Date;
/**
* @author tzy
* @version 1.0
* @date 2021/4/26 14:01
* 生产用料清单用作导出用料
*/
@Data
public class MaterialUsageDTO2 {
@JsonProperty("F_HBYT_SCLH")
@ExcelProperty("生产令号")
private String planCode;
@JsonProperty("FMaterialID2.FNumber")
@ExcelProperty("子项物料编码")
private String materialCode;
// 子物料编码
@JsonProperty("FMaterialName1")
@ExcelProperty("子物料名称")
private String materialName;// 子物料名称
// 物料名称
@JsonProperty("FNumerator")
@ExcelProperty("单台数量")
private double FNumerator;
@JsonProperty("FMustQty")
@ExcelProperty("本批数量")
private double FMustQty;
@JsonProperty("FUnitID2.FName")
@ExcelProperty("单位")
private String unit;
// 单位
@JsonProperty("F_HBYT_DZ")
@ExcelProperty("单重")
private String danzhong; // 单重
// 应发数量
@JsonProperty("FPickedQty")
@ExcelProperty("已领数量")
private double FPickedQty;
// 已领数量
@JsonProperty("F_HBYT_CZ")
@ExcelProperty("材质")
private String materialCZ; // 材质
@JsonProperty("FDenominator") // 分子
private double FDenominator;
// 分母
@JsonProperty("FMaterialName")
@ExcelProperty("父级物料名称")
private String FMaterialName1;
// 父级物料名称
@JsonProperty("FMaterialID.FNumber")
@ExcelProperty("父级物料编码")
private String FNumber; // 父级物料编码
}

View File

@ -0,0 +1,39 @@
package com.ruoyi.system.domain.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/*
* @Description:物料清单
* 物料清单映射对象
* @author 田志阳
* @date 2025/5/25
*/
@Data
public class MaterialUseDTO
{
//BOM版本
@JsonProperty("FNumber")
private String fnumber;
//子项物料编码
@JsonProperty("FMATERIALIDCHILD.FNumber")
private String materialCode;
//子项物料名称
@JsonProperty("FCHILDITEMNAME")
private String materialName;
//分子
@JsonProperty("FNUMERATOR")
private Integer fenzi;
//分母
@JsonProperty("FDENOMINATOR")
private Integer fenmu;
//单重
@JsonProperty("F_HBYT_DZ")
private Double danzhong;
//材质
@JsonProperty("F_HBYT_CZ")
private String caizhi;
//子项物料单位
@JsonProperty("FCHILDUNITID.FName")
private String childUnit;
}

View File

@ -9,6 +9,6 @@ public class ProMoDTO {
private String FMaterialIdFNumber; private String FMaterialIdFNumber;
@JsonProperty("FMaterialName") @JsonProperty("FMaterialName")
private String FMaterialName; private String FMaterialName;
@JsonProperty("FQty") @JsonProperty("FNoStockInQty")
private Double FQty; private Double FQty;
} }

View File

@ -1,40 +1,48 @@
package com.ruoyi.system.domain.dto; package com.ruoyi.system.domain.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
@Data @Data
public class ProcessRouteDTO { public class ProcessRouteDTO {
/**
* 工序名称描述
*/
@JsonProperty("FNumber")
private String processNameDescription;
/** /**
* 工序号 * 工序号
*/ */
@JsonProperty("FOperNumber")
private Long processNo; private Long processNo;
/** /**
* 工作中心加工车间 * 工作中心加工车间
*/ */
@JsonProperty("FWorkCenterId.FName")
private String workCenter; private String workCenter;
/** /**
* 工序名称 * 工序名称
*/ */
@JsonProperty("FProcessId.FName")
private String processName; private String processName;
/** /**
* 工序说明序描述 * 工序说明序描述
*/ */
@JsonProperty("FOperDescription")
private String processDescription; private String processDescription;
/** /**
* 工序控制 * 工序控制
*/ */
@JsonProperty("FOptCtrlCodeId.FName")
private String processControl; private String processControl;
/** /**
* 活动时长 * 活动时长
*/ */
@JsonProperty("FActivity1Qty")
private Double activityDuration; private Double activityDuration;
/** /**
* 活动单位 * 活动单位
*/ */
@JsonProperty("FActivity1UnitID.FName")
private String activityUnit; private String activityUnit;
/**
* 工序名称描述
*/
private String processNameDescription;
} }

View File

@ -14,6 +14,7 @@ public class ProductctionPlanGatteDto {
private String text; private String text;
private String start_date; private String start_date;
private String end_date; private String end_date;
//天数
private Long duration; private Long duration;
private Integer type; private Integer type;
private Boolean open; private Boolean open;

View File

@ -9,6 +9,6 @@ public class PurchaseOrderDTO {
private String FMaterialIdFNumber; private String FMaterialIdFNumber;
@JsonProperty("FMaterialName") @JsonProperty("FMaterialName")
private String FMaterialName; private String FMaterialName;
@JsonProperty("FQty") @JsonProperty("FRemainStockINQty")
private Double FQty; private Double FRemainStockINQty;
} }

View File

@ -0,0 +1,19 @@
package com.ruoyi.system.domain.dto;
import lombok.Data;
/**
* material_bom
* 单重映射对象
* @author tzy
* @date 2024-11-08
*/
@Data
public class SingleWe {
private Long sid;
private String materialCode;
private String RmaterialCode;
private String RmaterialName;
private String materialName;
private Double danZhon;
}

View File

@ -92,13 +92,15 @@ public class BomDetailsVo {
/** /**
* *仓库
*/ */
@ExcelProperty(value = "备注/仓库") @ExcelProperty(value = "备注/仓库")
private String remarks; private String remarks;
/** /**
* 单重 * 单重
*/ */
private Double danzhong; private Double danZhong;
private Double singleWeghit;
} }

View File

@ -6,6 +6,7 @@ import lombok.Data;
public class InventoryInfoVO { public class InventoryInfoVO {
private String materialCode; // 图号 private String materialCode; // 图号
private String materialName; // 名称 private String materialName; // 名称
private String kucun; // 名称
private String stockName; // 仓库 private String stockName; // 仓库
private String stockUnit; // 单位 private String stockUnit; // 单位
private String quantity; // 数量 private String quantity; // 数量

View File

@ -0,0 +1,455 @@
package com.ruoyi.system.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 销齿链型号对象 pc_rigid_chain
*
* @author zhukangchao
* @date 2020-10-22
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class PcRigidChainVO extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键 */
private Long id;
/** 类型 */
@ExcelProperty("类型")
private String type;
/** 型号全称 */
@ExcelProperty( "型号")
private String typeName;
/** 产品id */
@ExcelProperty( "产品id")
private Long productId;
/** 产品名称 */
@ExcelProperty( "产品名称")
private String productName;
/** 物料编码 */
@ExcelProperty( "物料编码")
private String materialCode;
/** 轴向 */
@ExcelProperty( "轴向")
private String axialDirection;
/** 箱体 */
@ExcelProperty( "箱体")
private String box;
/** 行程mm */
@ExcelProperty( "{V1}")
private Long journey;
/** 标记号 */
@ExcelProperty( "标记号")
private String lableNumber;
/** L1mm */
@ExcelProperty( "L1")
private Long lOne;
/** L2mm */
@ExcelProperty( "L2")
private Long lTwo;
/** L3mm */
@ExcelProperty( "L3")
private Long lThree;
/** 总重量 */
@ExcelProperty( "总重量")
private Long sumWeight;
/** 链条自重 */
@ExcelProperty( "链条自重")
private Long chainWeight;
/** 动载荷KN */
@ExcelProperty( "动载荷")
private Long dynamicLoad;
/** 静载荷KN */
@ExcelProperty( "静载荷")
private Long deadLoad;
/** 每转上升高度mm */
@ExcelProperty( "每转上升高度")
private Long riseInHeightPerRevolution;
/** 速度mm/s */
@ExcelProperty( "速度")
private Double speed;
/** 系统效率(% */
@ExcelProperty( "系统效率")
private Long efficiency;
/** 链条节距mm */
@ExcelProperty( "链条节距")
private Long chainPitch;
/** 节圆半径mm */
@ExcelProperty( "节圆半径")
private Long pitchRadius;
/** 最低高度mm */
@ExcelProperty( "最低高度")
private Long minimumAltitude;
/** 一米链条自重Kg/m */
@ExcelProperty( "一米链条自重")
private Double singleMeterChainWeight;
/** 驱动箱重量Kg */
@ExcelProperty( "驱动箱重量")
private Long drivingBoxWeight;
/** 链箱重量Kg/m */
@ExcelProperty( "链箱重量")
private Double chainBoxWeight;
/** 单价 */
@ExcelProperty( "单价")
private Double univalence;
/** 图片 */
@ExcelProperty( "图片")
private String picture;
/** 部件id集合 */
@ExcelProperty( "部件id集合")
private String partId;
/** 备用字段1 */
@ExcelProperty( "备用字段1")
private String sparedOne;
/** 备用字段2 */
@ExcelProperty( "备用字段2")
private String sparedTwo;
/** 备用字段3 */
@ExcelProperty( "备用字段3")
private Long sparedThree;
/** 备用字段4 */
@ExcelProperty( "备用字段4")
private Long sparedFour;
/** 删除标记0未删除1已删除 */
private Long delFlag;
/** 行程 */
@ExcelProperty( "{V1}")
private Long vOne;
/** 设备总长 */
@ExcelProperty( "{V2}")
private Long vTwo;
/** 地脚位置1 */
@ExcelProperty( "{V3}")
private Long vThree;
/** 地脚位置2 */
@ExcelProperty("{V4}")
private Long vFour;
/** 箱体装配长度 */
@ExcelProperty("{V5}")
private Long vFive;
/** 箱体地脚位置1 */
@ExcelProperty( "{V6}")
private Long vSix;
/** 箱体地脚位置2 */
@ExcelProperty( "{V7}")
private Long vSeven;
/** 铝箱长度1 */
@ExcelProperty( "{V8}")
private Long vEight;
/** 铝箱长度2 */
@ExcelProperty( "{V9}")
private Long vNine;
/** 导向条长度1 */
@ExcelProperty( "{V10}")
private Long vTen;
/** 导向条长度1数量 */
@ExcelProperty( "{V11}")
private Long vEleven;
/** 导向条长度2 */
@ExcelProperty( "{V12}")
private Long vTwelve;
/** 导向条长度2数量 */
@ExcelProperty( "{V13}")
//@Excel(name = "导向条2数量")
private Long vThirteen;
/** 导向条长度3 */
@ExcelProperty( "{V14}")
private Long vFourteen;
/** 导向条长度3数量 */
@ExcelProperty( "{V15}")
//@Excel(name = "导向条3数量")
private Long vFifteen;
/** 孔位总长1 */
@ExcelProperty( "{V16}")
private Long vSixteen;
/** 间隔数量1 */
@ExcelProperty( "{V17}")
private Long vSeveteen;
/** 孔位总长2 */
@ExcelProperty( "{V18}")
private Long vEighteen;
/** 间隔数量2 */
@ExcelProperty( "{V19}")
private Long vNineteen;
/** 铆钉数量 */
@ExcelProperty( "{V20}")
private Long vTwenty;
/** 待定义 */
@ExcelProperty( "{V21}")
private Long vTwentyOne;
/** 待定义 */
@ExcelProperty( "{V22}")
private Long vTwentyTwo;
/** 待定义 */
@ExcelProperty( "{V23}")
private Long vTwentyThree;
/** 待定义 */
@ExcelProperty( "{V24}")
private Long vTwentyFour;
/** 待定义 */
// @ExcelProperty( "{V25}")
private Long vTwentyFive;
/** 待定义 */
@ExcelProperty( "{V26}")
private Long vTwentySix;
/** 待定义 */
@ExcelProperty( "{V27}")
private Long vTwentySeven;
/** 待定义 */
@ExcelProperty( "{V28}")
private Long vTwentyEight;
/** 待定义 */
@ExcelProperty( "{V29}")
private Long vTwentyNine;
/** 待定义 */
@ExcelProperty( "{V30}")
private Long vThirty;
/** 待定义 */
@ExcelProperty( "{V31}")
private Long vThirtyOne;
/** 待定义 */
@ExcelProperty( "{V32}")
private Long vThirtyTwo;
/** 待定义 */
@ExcelProperty( "{V33}")
private Long vThirtyThree;
/** 待定义 */
@ExcelProperty( "{V34}")
private Long vThirtyFour;
/** 待定义 */
@ExcelProperty( "{V35}")
private Long vThirtyFive;
/** 待定义 */
@ExcelProperty( "{V36}")
private Long vThirtySix;
/** 待定义 */
@ExcelProperty( "{V37}")
private Long vThirtySeven;
/** 待定义 */
@ExcelProperty( "{V38}")
private Long vThirtyEight;
/** 待定义 */
@ExcelProperty( "{V39}")
private Long vThirtyNine;
/** 待定义 */
@ExcelProperty( "{V40}")
private Long vForty;
/** X1 */
@ExcelProperty( "{V41}")
private Long vFortyOne;
/** X2 */
@ExcelProperty( "{V42}")
private Long vFortyTwo;
/** X3 */
@ExcelProperty( "{V43}")
private Long vFortyThree;
/** X4 */
@ExcelProperty( "{V44}")
private Long vFortyFour;
/** X5 */
@ExcelProperty( "{V45}")
private Long vFortyFive;
/** X6 */
@ExcelProperty( "{V46}")
private Long vFortySix;
/** X7 */
@ExcelProperty( "{V48}")
private Long vFortySeven;
/** X8 */
@ExcelProperty( "V48")
private Long vFortyEight;
/** X9 */
@ExcelProperty( "{V49}")
private Long vFortyNine;
/** X10 */
@ExcelProperty( "{V50}")
private Long vFifty;
/** X11 */
@ExcelProperty( "{V51}")
private Long vFiftyOne;
/** X12 */
@ExcelProperty( "{V52}")
private Long vFiftyTwo;
/** X13 */
@ExcelProperty( "{V53}")
private Long vFiftyThree;
/** 重量 */
@ExcelProperty( "{G1}")
private Double gOne;
/** 重量 */
@ExcelProperty( "{G2}")
private Double gTwo;
/** 重量 */
@ExcelProperty( "{G3}")
private Double gThree;
/** 重量 */
@ExcelProperty( "{G4}")
private Double gFour;
/** 重量 */
@ExcelProperty( "{G5}")
private Double gFive;
/** 重量 */
@ExcelProperty( "{G6}")
private Double gSix;
/** 重量 */
@ExcelProperty( "{G7}")
private Double gSeven;
/** 重量 */
@ExcelProperty( "{G8}")
private Double gEight;
/** 重量 */
@ExcelProperty( "{G9}")
private Double gNine;
/** 重量 */
@ExcelProperty( "{G10}")
private Double gTen;
/** 重量 */
@ExcelProperty( "{G11}")
private Double gEleven;
/** 重量 */
@ExcelProperty( "{G12}")
private Double gTwelve;
/** 重量 */
@ExcelProperty( "{G13}")
private Double gThirteen;
/** 重量 */
@ExcelProperty( "{G14}")
private Double gFourteen;
/** 重量 */
@ExcelProperty( "{G15}")
private Double gFifteen;
/** 重量 */
@ExcelProperty( "{G16}")
private Double gSixteen;
/** 重量 */
@ExcelProperty( "{G17}")
private Double gSeveteen;
/** 重量 */
@ExcelProperty( "{G18}")
private Double gEighteen;
/** 重量 */
@ExcelProperty( "{G19}")
private Double gNineteen;
/** 重量 */
@ExcelProperty( "{G20}")
private Double gTwenty;
private Double vipLevel;
private String spline;
private Long number;
}

View File

@ -14,7 +14,7 @@ import lombok.Data;
/** /**
* 计划工序视图对象 planned_process * 计划工序视图对象 planned_process
* *
* @author ruoyi * @author tzy
* @date 2024-10-24 * @date 2024-10-24
*/ */
@Data @Data

View File

@ -0,0 +1,179 @@
package com.ruoyi.system.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
/**
* 工艺路线对象 process_route
*
* @author ruoyi
* @date 2024-10-09
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("process_route")
public class ProcessRouteStandVo extends BaseEntity {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO)
@ExcelIgnore
private Long id;
/**
* 工艺路线描述
*/
@ColumnWidth(15)
// @ExcelProperty(value={"生产令号","生产令号"},index=0)
private String routeDescription;
/**
* 物料编码
*/
@ColumnWidth(20)
@ExcelProperty(value ={"物料编码","物料编码"},index=0 )
private String materialCode;
/**
* 物料名称
*/
@ColumnWidth(25)
@ExcelProperty(value ={"名称","名称"},index=1)
private String materialName;
/**
* 材料BOM单位
*/
@ColumnWidth(10)
@ExcelProperty(value={ "材料BOM","单位"},index=10)
private String bomUnit;
/**
* 工序号
*/
@ColumnWidth(10)
@ExcelProperty(value ={ "工序号","工序号"},index = 11)
private Long processNo;
/**
* 工作中心加工车间
*/
@ColumnWidth(20)
@ExcelProperty(value ={ "工作中心(加工车间)","工作中心(加工车间)"},index = 12)
private String workCenter;
/**
* 工序名称
*/
@ColumnWidth(20)
@ExcelProperty(value ={ "工序名称","工序名称"},index = 13)
private String processName;
/**
* 材料BOM物料编码
*/
@ColumnWidth(20)
@ExcelProperty(value={ "材料BOM","物料编码"}, index=4)
private String rawMaterialCode;
/**
* 材料BOM物料名称
*/
@ColumnWidth(25)
@ExcelProperty(value={ "材料BOM","物料名称"},index = 5)
private String rawMaterialName;
/**
* 单重KG
*/
@ColumnWidth(10)
@ExcelProperty(value={"单重KG","单重KG"},index=3)
private Double discWeight;
/**
* 材料BOM用量
*/
@ColumnWidth(10)
@ExcelProperty(value = { "材料BOM","用量"},index = 9)
private Double discUsage;
/**
* 工序说明序描述
*/
@ColumnWidth(30)
@ExcelProperty(value ={ "工序说明(序描述)","工序说明(序描述)"},index = 14)
private String processDescription;
/**
* 工序控制
*/
@ColumnWidth(20)
@ExcelProperty(value ={ "工序控制","工序控制"},index = 15)
private String processControl;
/**
* 活动时长
*/
@ColumnWidth(10)
@ExcelProperty(value ={ "活动时长","活动时长"},index = 16)
private Double activityDuration;
/**
* 活动单位
*/
@ColumnWidth(10)
@ExcelProperty(value ={ "活动单位","活动单位"},index = 17)
private String activityUnit;
/**
* bom材质
*/
@ColumnWidth(15)
@ExcelProperty(value={ "材料BOM","材质"},index = 7)
private String bomMaterial;
/**
* 材质
*/
@ColumnWidth(15)
@ExcelProperty(value={ "材质","材质"},index=2)
private String material;
/**
* 单台数量
*/
@ColumnWidth(10)
@ExcelProperty(value = {"制件数量","单台数量"},index = 18)
private Double unitQuantity;
/**
* 本批数量
*/
@ColumnWidth(10)
@ExcelProperty(value = {"制件数量","本批数量"},index = 19)
private Long batchQuantity;
/**
* 首批数量
*/
@ExcelIgnore
private Double firstBatchQuantity;
/**
* 计划开始时间
*/
@ExcelIgnore
private Date planStartTime;
/**
* 计划结束时间
*/
@ExcelIgnore
private Date planEndTime;
/**
* 序开始时间
*/
@ColumnWidth(15)
@ExcelProperty(value = {"计划完成时间","起始日期"},index = 20)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date xuStartTime;
/**
* 序结束时间
*/
@ColumnWidth(15)
@ExcelProperty(value = {"计划完成时间","完成日期"},index = 22)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date xuEndTime;
}

View File

@ -3,6 +3,9 @@ package com.ruoyi.system.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.NumberFormat; import com.alibaba.excel.annotation.format.NumberFormat;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.convert.ExcelDictConvert; import com.ruoyi.common.convert.ExcelDictConvert;
import lombok.Data; import lombok.Data;
@ -21,6 +24,9 @@ import java.util.List;
*/ */
@Data @Data
@ExcelIgnoreUnannotated @ExcelIgnoreUnannotated
@ContentRowHeight(15)
@HeadRowHeight(20)
@ColumnWidth(15)
public class ProcessRouteVo { public class ProcessRouteVo {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -38,29 +44,34 @@ public class ProcessRouteVo {
/** /**
* 工艺路线描述 * 工艺路线描述
*/ */
@ExcelProperty(value={"生产令号","生产令号"},index=0) @ExcelProperty(value={"生产令号","生产令号"},index=0)
private String routeDescription; private String routeDescription;
/** /**
* 物料编码 * 物料编码
*/ */
@ExcelProperty(value ={"物料编码","物料编码"},index=1 ) @ExcelProperty(value ={"物料编码","物料编码"},index=1 )
private String materialCode; private String materialCode;
/** /**
* 物料名称 * 物料名称
*/ */
@ExcelProperty(value ={"名称","名称"},index=2) @ExcelProperty(value ={"名称","名称"},index=2)
private String materialName; private String materialName;
/** /**
* 材质 * 材质
*/ */
@ExcelProperty(value={ "材质","材质"},index=3) @ExcelProperty(value={ "材质","材质"},index=3)
private String material; private String material;
/** /**
* 单重KG * 单重KG
*/ */
@ColumnWidth(5)
@ExcelProperty(value={"单重KG","单重KG"},index=4) @ExcelProperty(value={"单重KG","单重KG"},index=4)
private Double discWeight; private Double discWeight;
/** /**
@ -79,72 +90,83 @@ public class ProcessRouteVo {
/** /**
* bom材质 * bom材质
*/ */
@ColumnWidth(7)
@ExcelProperty(value={ "材料BOM","材质"},index = 7) @ExcelProperty(value={ "材料BOM","材质"},index = 7)
private String bomMaterial; private String bomMaterial;
/**
* 材料BOM单位
*/
@ExcelProperty(value={ "材料BOM","材料单重KG"},index=8)
private Double bomDanZhong;
/** /**
* 材料BOM用量 * 材料BOM用量
*/ */
@ExcelProperty(value = { "材料BOM","用量"},index = 8) @ColumnWidth(10)
@ExcelProperty(value = { "材料BOM","用量"},index = 9)
private Double discUsage; private Double discUsage;
/** /**
* 材料BOM单位 * 材料BOM单位
*/ */
@ExcelProperty(value={ "材料BOM","单位"},index=9) @ColumnWidth(6)
@ExcelProperty(value={ "材料BOM","单位"},index=10)
private String bomUnit; private String bomUnit;
/** /**
* 工序号 * 工序号
*/ */
@ExcelProperty(value ={ "工序号","工序号"},index = 10) @ColumnWidth(10)
@ExcelProperty(value ={ "工序号","工序号"},index = 11)
private Long processNo; private Long processNo;
/** /**
* 工作中心加工车间 * 工作中心加工车间
*/ */
@ExcelProperty(value ={ "工作中心(加工车间)","工作中心(加工车间)"},index = 11) @ExcelProperty(value ={ "工作中心(加工车间)","工作中心(加工车间)"},index = 12)
private String workCenter; private String workCenter;
/** /**
* 工序名称 * 工序名称
*/ */
@ExcelProperty(value ={ "工序名称","工序名称"},index = 12) @ExcelProperty(value ={ "工序名称","工序名称"},index = 13)
private String processName; private String processName;
/** /**
* 工序说明序描述 * 工序说明序描述
*/ */
@ExcelProperty(value ={ "工序说明(序描述)","工序说明(序描述)"},index = 13) @ColumnWidth(25)
@ExcelProperty(value ={ "工序说明(序描述)","工序说明(序描述)"},index = 14)
private String processDescription; private String processDescription;
/** /**
* 工序控制 * 工序控制
*/ */
@ExcelProperty(value ={ "工序控制","工序控制"},index = 14) @ExcelProperty(value ={ "工序控制","工序控制"},index = 15)
private String processControl; private String processControl;
/** /**
* 活动时长 * 活动时长
*/ */
@ExcelProperty(value ={ "活动时长","活动时长"},index = 15) @ExcelProperty(value ={ "活动时长","活动时长"},index = 16)
private Double activityDuration; private Double activityDuration;
/** /**
* 活动单位 * 活动单位
*/ */
@ExcelProperty(value ={ "活动单位","活动单位"},index = 16) @ExcelProperty(value ={ "活动单位","活动单位"},index = 17)
private String activityUnit; private String activityUnit;
/** /**
* 单台数量 * 单台数量
*/ */
@ExcelProperty(value = {"制件数量","单台数量"},index = 17) @ExcelProperty(value = {"制件数量","单台数量"},index = 18)
private Long unitQuantity; private Long unitQuantity;
/** /**
* 本批数量 * 本批数量
*/ */
@ExcelProperty(value = {"制件数量","本批数量"},index = 18)
@ExcelProperty(value = {"制件数量","本批数量"},index = 19)
private Long batchQuantity; private Long batchQuantity;
/** /**
@ -167,14 +189,16 @@ public class ProcessRouteVo {
/** /**
* 序开始时间 * 序开始时间
*/ */
@ExcelProperty(value = {"计划完成时间","起始日期"},index = 19) @ColumnWidth(18)
@ExcelProperty(value = {"计划完成时间","起始日期"},index = 20)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date xuStartTime; private Date xuStartTime;
/** /**
* 序结束时间 * 序结束时间
*/ */
@ExcelProperty(value = {"计划完成时间","完成日期"},index = 21) @ColumnWidth(18)
@ExcelProperty(value = {"计划完成时间","完成日期"},index = 22)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date xuEndTime; private Date xuEndTime;

View File

@ -2,8 +2,12 @@ package com.ruoyi.system.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotBlank;
/** /**
* 安全库存视图对象 wl_safety_stock * 安全库存视图对象 wl_safety_stock
@ -54,5 +58,19 @@ public class SafetyStockVo {
*/ */
@ExcelProperty(value = "金蝶单据编码") @ExcelProperty(value = "金蝶单据编码")
private String doucCode; private String doucCode;
/**
* 单台数量
*/
@ExcelProperty(value = "单台数量")
private Long singleNum;
/**
*分类
*/
@ExcelProperty(value = "分类")
private String type;
/**
* 材质
*/
@ExcelProperty(value = "材质")
private String wlMaterial;
} }

View File

@ -37,53 +37,45 @@ public class WlStockDataVo {
@ExcelProperty(value = "物料名称") @ExcelProperty(value = "物料名称")
private String materialName; private String materialName;
@ExcelProperty(value = "材质")
private String documentType;
/** /**
* 所需库存 * 所需库存
*/ */
@ExcelProperty(value = "所需库存")
private Double requiredStock; private Double requiredStock;
/** /**
* 当前库存 * 当前库存
*/ */
@ExcelProperty(value = "当前库存") @ExcelProperty(value = "预计可用量")
private Double currentStock; private Double currentStock;
/**
* 触发时间
*/
@ExcelProperty(value = "触发时间")
private Date triggerTime;
/** /**
* 可用库存 * 可用库存
*/ */
@ExcelProperty(value = "可用库存") @ExcelProperty(value = "用料清单未领料数量")
private BigDecimal availableStock; private BigDecimal availableStock;
/** /**
* 库存量 * 库存量
*/ */
@ExcelProperty(value = "库存") @ExcelProperty(value = "即时库存")
private BigDecimal secAvbqty; private BigDecimal secAvbqty;
/** /**
* 生产订单数量 * 生产订单数量
*/ */
@ExcelProperty(value = "生产订单数量") @ExcelProperty(value = "生产订单未入库数量")
private BigDecimal productionQty; private BigDecimal productionQty;
/** /**
* 采购订单数量 * 采购订单数量
*/ */
@ExcelProperty(value = "采购订单数量") @ExcelProperty(value = "采购订单未入库数量")
private BigDecimal purchaseQty; private BigDecimal purchaseQty;
/** /**
* 预留量 * 预留量
*/ */
@ExcelProperty(value = "预留量") /* @ExcelProperty(value = "预留量")*/
private BigDecimal secQty; private BigDecimal secQty;
/** /**
@ -99,9 +91,19 @@ public class WlStockDataVo {
private BigDecimal minsafetyStock; private BigDecimal minsafetyStock;
/** /**
* 单据类型 (1: 最高库存单, 0: 最低库存单) * 安全库存状态(符合1,不符合0)
*/ */
@ExcelProperty(value = "金蝶相关数据") @ExcelProperty(value = "是否符合要求")
private String documentType; private int safeStatus;
/**
* 分组
*/
@ExcelProperty(value = "分组")
private String wlMaterial;
/**
* 触发时间
*/
@ExcelProperty(value = "触发时间")
private Date triggerTime;
} }

View File

@ -540,7 +540,7 @@ public class JdUtil {
} }
/** /**
* 查询生产订单单据体 * 查询生产订单单据体
* *查询
* @param materialCode * @param materialCode
* @return * @return
*/ */
@ -551,7 +551,7 @@ public class JdUtil {
JsonObject json = new JsonObject(); JsonObject json = new JsonObject();
json.addProperty("FormId", "PRD_MO"); json.addProperty("FormId", "PRD_MO");
json.addProperty("FieldKeys", json.addProperty("FieldKeys",
"FMaterialId.FNumber,FMaterialName,FQty"); "FMaterialId.FNumber,FMaterialName,FNoStockInQty");
// 创建过滤条件 // 创建过滤条件
JsonArray filterString = new JsonArray(); JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject(); JsonObject filterObject = new JsonObject();
@ -584,8 +584,16 @@ public class JdUtil {
filterObject3.addProperty("Value", 7); filterObject3.addProperty("Value", 7);
filterObject3.addProperty("Left", ""); filterObject3.addProperty("Left", "");
filterObject3.addProperty("Right", ""); filterObject3.addProperty("Right", "");
filterObject3.addProperty("Logic", 0);// PlanOrderVo 获取生产令号 filterObject3.addProperty("Logic", 0);
filterString.add(filterObject3); filterString.add(filterObject3);
JsonObject filterObject4 = new JsonObject();
filterObject4.addProperty("FieldName", "FNoStockInQty");
filterObject4.addProperty("Compare", "21"); // 改为等号运算符
filterObject4.addProperty("Value", 0);
filterObject4.addProperty("Left", "");
filterObject4.addProperty("Right", "");
filterObject4.addProperty("Logic", 0);
filterString.add(filterObject4);
json.add("FilterString", filterString); json.add("FilterString", filterString);
json.addProperty("OrderString", ""); json.addProperty("OrderString", "");
@ -616,6 +624,7 @@ public class JdUtil {
/** /**
* 查询采购订单 单据体 * 查询采购订单 单据体
* 将预留量更改为 剩余未入库数量20250325
* @param materialCode * @param materialCode
* @return * @return
*/ */
@ -628,7 +637,7 @@ public class JdUtil {
JsonObject json = new JsonObject(); JsonObject json = new JsonObject();
json.addProperty("FormId", "PUR_PurchaseOrder"); json.addProperty("FormId", "PUR_PurchaseOrder");
json.addProperty("FieldKeys", json.addProperty("FieldKeys",
"FMaterialId.FNumber,FMaterialName,FQty"); "FMaterialId.FNumber,FMaterialName,FRemainStockINQty");
// 创建过滤条件 // 创建过滤条件
JsonArray filterString = new JsonArray(); JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject(); JsonObject filterObject = new JsonObject();
@ -641,12 +650,20 @@ public class JdUtil {
filterString.add(filterObject); filterString.add(filterObject);
JsonObject filterObject1 = new JsonObject(); JsonObject filterObject1 = new JsonObject();
filterObject1.addProperty("FieldName", "FMRPCloseStatus"); filterObject1.addProperty("FieldName", "FMRPCloseStatus");
filterObject1.addProperty("Compare", "="); // 改为等号运算符 filterObject1.addProperty("Compare", "105"); // 改为等号运算符
filterObject1.addProperty("Value", "A"); filterObject1.addProperty("Value", "A");
filterObject1.addProperty("Left", ""); filterObject1.addProperty("Left", "");
filterObject1.addProperty("Right", ""); filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);// PlanOrderVo 获取生产令号 filterObject1.addProperty("Logic", 0);// PlanOrderVo 获取生产令号
filterString.add(filterObject1); filterString.add(filterObject1);
/* JsonObject filterObject2 = new JsonObject();
filterObject2.addProperty("FieldName", "FCloseStatus");
filterObject2.addProperty("Compare", "106"); // 改为等号运算符
filterObject2.addProperty("Value", "A");
filterObject2.addProperty("Left", "");
filterObject2.addProperty("Right", "");
filterObject2.addProperty("Logic", 0);// PlanOrderVo 获取生产令号
filterString.add(filterObject2);*/
json.add("FilterString", filterString); json.add("FilterString", filterString);
json.addProperty("OrderString", ""); json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0); json.addProperty("TopRowCount", 0);
@ -674,19 +691,147 @@ public class JdUtil {
return plannedProcessList; // 返回结果 return plannedProcessList; // 返回结果
} }
/**
* 查询生产用料清单单据体
* 查询子项物料的未领料量
* @param materialCode
* @return
*/
public static List<JDProductionDTO> getWeiLingliao(String materialCode) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "PRD_PPBOM");
json.addProperty("FieldKeys",
"FMaterialID2.FNumber,FMaterialName1,FNoPickedQty");
// 创建过滤条件
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMaterialID2.FNumber");
filterObject.addProperty("Compare", "67");
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
JsonObject filterObject1 = new JsonObject();
filterObject1.addProperty("FieldName", "FMoEntryStatus");
filterObject1.addProperty("Compare", "5");
filterObject1.addProperty("Value", "7");
filterObject1.addProperty("Left", "");
filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);
filterString.add(filterObject1);
JsonObject filterObject2 = new JsonObject();
filterObject2.addProperty("FieldName", "FMoEntryStatus");// 改为等号运算符
filterObject2.addProperty("Compare", "5");
filterObject2.addProperty("Value", "5");
filterObject2.addProperty("Left", "");
filterObject2.addProperty("Right", "");
filterObject2.addProperty("Logic", 0);
filterString.add(filterObject2);
JsonObject filterObject3 = new JsonObject();
filterObject3.addProperty("FieldName", "FMoEntryStatus");
filterObject3.addProperty("Compare", "5");
filterObject3.addProperty("Value", "6");
filterObject3.addProperty("Left", "");
filterObject3.addProperty("Right", "");
filterObject3.addProperty("Logic", 0);
filterString.add(filterObject3);
JsonObject filterObject4 = new JsonObject();
filterObject4.addProperty("FieldName", "FDocumentStatus");
filterObject4.addProperty("Compare", "105");
filterObject4.addProperty("Value", "C");//单据状态:已审核
filterObject4.addProperty("Left", "");
filterObject4.addProperty("Right", "");
filterObject4.addProperty("Logic", 0);
filterString.add(filterObject4);
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
json.addProperty("StartRow", 0);
json.addProperty("Limit", 2000);
json.addProperty("SubSystemId", "");
String jsonData = json.toString();
List<JDProductionDTO> plannedProcessList = null;
try {
// 调用接口
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
// 使用 ObjectMapper JsonArray 转换为 List<PlannedProcessVo>
ObjectMapper objectMapper = new ObjectMapper();
plannedProcessList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<JDProductionDTO>>() {
});
} catch (Exception e) {
e.printStackTrace(); // 输出异常日志
}
return plannedProcessList; // 返回结果
}
public static List<JDInventoryDTO> getKuCun(String materialCode) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "STK_Inventory");
json.addProperty("FieldKeys",
"FMaterialId.FNumber,FMaterialName,FBaseQty");
// 创建过滤条件
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMaterialId.FNumber");
filterObject.addProperty("Compare", "=");
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
json.addProperty("StartRow", 0);
json.addProperty("Limit", 2000);
json.addProperty("SubSystemId", "");
String jsonData = json.toString();
List<JDInventoryDTO> plannedProcessList = null;
try {
// 调用接口
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
// 使用 ObjectMapper JsonArray 转换为 List<PlannedProcessVo>
ObjectMapper objectMapper = new ObjectMapper();
plannedProcessList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<JDInventoryDTO>>() {
});
} catch (Exception e) {
e.printStackTrace(); // 输出异常日志
}
return plannedProcessList; // 返回结果
}
public static Double getKeyong(String materialCode) { public static Double getKeyong(String materialCode) {
List<InvReserveAnalyzeRptDTO> analyzeRpt =getInvReserveAnalyzeRpt(materialCode); List<InvReserveAnalyzeRptDTO> analyzeRpt =getInvReserveAnalyzeRpt(materialCode);
if (analyzeRpt == null || analyzeRpt.isEmpty()) { if (analyzeRpt.isEmpty()) {
System.err.println("No inventory data found for materialCode: " + materialCode); System.err.println("No inventory data found for materialCode: " + materialCode);
return 0.0; // 返回 0.0 而不是 null return 0.0; // 返回 0.0 而不是 null
} }
double fSecAVBQty = 0.0; double fSecAVBQty = 0.0;
double fSecQty = 0.0; double fSecQty = 0.0;
if (!analyzeRpt.isEmpty()) {
fSecAVBQty = analyzeRpt.get(0).getFSecAVBQty(); fSecAVBQty = analyzeRpt.get(0).getFSecAVBQty();
}
for (InvReserveAnalyzeRptDTO analyzeRptDTO : analyzeRpt) { for (InvReserveAnalyzeRptDTO analyzeRptDTO : analyzeRpt) {
if (analyzeRptDTO.getFSecQty() != null) { if (analyzeRptDTO.getFSecQty() != null) {
fSecQty += analyzeRptDTO.getFSecQty(); fSecQty += analyzeRptDTO.getFSecQty();
@ -703,12 +848,12 @@ public class JdUtil {
List<PurchaseOrderDTO> purchaseOrderList = getPurchaseOrderList(materialCode); List<PurchaseOrderDTO> purchaseOrderList = getPurchaseOrderList(materialCode);
if (purchaseOrderList != null) { if (purchaseOrderList != null) {
for (PurchaseOrderDTO purchaseOrderDTO : purchaseOrderList) { for (PurchaseOrderDTO purchaseOrderDTO : purchaseOrderList) {
purchaseQty += purchaseOrderDTO.getFQty(); purchaseQty += purchaseOrderDTO.getFRemainStockINQty();
} }
} }
return fSecAVBQty + productionQty + purchaseQty - fSecQty; return fSecAVBQty + productionQty + purchaseQty - fSecQty;
} }
// 金蝶物料查询
public static int isMaterialVerification(String DrawingNumber, String name) { public static int isMaterialVerification(String DrawingNumber, String name) {
if (DrawingNumber == null || DrawingNumber.isEmpty() || name == null || name.isEmpty()) { if (DrawingNumber == null || DrawingNumber.isEmpty() || name == null || name.isEmpty()) {
return 0; return 0;
@ -732,7 +877,6 @@ public class JdUtil {
return 1; // 编码未找到返回1表示正常 return 1; // 编码未找到返回1表示正常
} }
} }
/*本接口用于实现物料清单 的禁用功能*/ /*本接口用于实现物料清单 的禁用功能*/
public static void jtestForbidMaterial(String FNumber) throws Exception { public static void jtestForbidMaterial(String FNumber) throws Exception {
K3CloudApi api = new K3CloudApi(); K3CloudApi api = new K3CloudApi();
@ -747,7 +891,6 @@ public class JdUtil {
fail("物料提交接口: " + gson.toJson(repoRet.getResult())); fail("物料提交接口: " + gson.toJson(repoRet.getResult()));
} }
} }
//用料清单查询接口腹肌无聊 //用料清单查询接口腹肌无聊
public static List<JinYongDTO> getFuji(String materialCode) { public static List<JinYongDTO> getFuji(String materialCode) {
List<JinYongDTO> jinYongDTOS = new ArrayList<>(); List<JinYongDTO> jinYongDTOS = new ArrayList<>();
@ -906,8 +1049,8 @@ public class JdUtil {
// 添加Model字段 // 添加Model字段
model.addProperty("FMATERIALID", 0); model.addProperty("FMATERIALID", 0);
if(!(bomDetail.getDanzhong() ==null)){ if(!(bomDetail.getDanZhong() ==null)){
model.addProperty("F_HBYT_DZ", bomDetail.getDanzhong()); model.addProperty("F_HBYT_DZ", bomDetail.getDanZhong());
} }
model.addProperty("FNumber", bomDetail.getFNumber()); model.addProperty("FNumber", bomDetail.getFNumber());
model.addProperty("FName", bomDetail.getFName()); model.addProperty("FName", bomDetail.getFName());
@ -1086,13 +1229,13 @@ public class JdUtil {
if (jsonArray != null && jsonArray.size() > 0) { if (jsonArray != null && jsonArray.size() > 0) {
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
List<JdEntryVmi> JinYongDTOList = objectMapper.readValue(jsonArray.toString(), List<JdEntryVmi> entryVmis = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<JdEntryVmi>>() {}); new TypeReference<List<JdEntryVmi>>() {});
if (JinYongDTOList != null && !JinYongDTOList.isEmpty()) { if (entryVmis != null && !entryVmis.isEmpty()) {
jinYongDTOS.addAll(JinYongDTOList); jinYongDTOS.addAll(entryVmis);
} }
} else { } else {
log.warn("未找到与bom版本号 " + materialCode + " 相关的记录"); log.warn("未找到与 " + materialCode + " 相关的记录");
} }
} catch (Exception e) { } catch (Exception e) {
log.error("调用接口时发生异常: " + e.getMessage(), e); log.error("调用接口时发生异常: " + e.getMessage(), e);
@ -1100,8 +1243,7 @@ public class JdUtil {
return jinYongDTOS; return jinYongDTOS;
} }
//更新VMI
public static String updateVMI(int FMATERIALID, int fEntryId1, int fEntryId2, String cangkunum, String cangWeiNum) throws Exception { public static String updateVMI(int FMATERIALID, int fEntryId1, int fEntryId2, String cangkunum, String cangWeiNum) throws Exception {
K3CloudApi api = new K3CloudApi(false); K3CloudApi api = new K3CloudApi(false);
JsonObject json = new JsonObject(); JsonObject json = new JsonObject();
@ -1113,7 +1255,8 @@ public class JdUtil {
needUpDateFields.add("SubHeadEntity3"); needUpDateFields.add("SubHeadEntity3");
needUpDateFields.add("FStockPlaceId"); needUpDateFields.add("FStockPlaceId");
needUpDateFields.add("FStockId"); needUpDateFields.add("FStockId");
needUpDateFields.add("FIsVmiBusiness");
//needUpDateFields.add("FIsVmiBusiness");
json.add("NeedUpDateFields", needUpDateFields); json.add("NeedUpDateFields", needUpDateFields);
// 添加 IsDeleteEntry 属性 // 添加 IsDeleteEntry 属性
@ -1134,9 +1277,11 @@ public class JdUtil {
// 创建 FStockPlaceId 对象 // 创建 FStockPlaceId 对象
JsonObject fStockPlaceId = new JsonObject(); JsonObject fStockPlaceId = new JsonObject();
JsonObject fStockPlaceIdFF100002 = new JsonObject(); JsonObject fStockPlaceIdFF100003 = new JsonObject();
fStockPlaceIdFF100002.addProperty("FNumber", cangWeiNum); fStockPlaceIdFF100003.addProperty("FNumber", cangWeiNum);
fStockPlaceId.add("FSTOCKPLACEID__FF100002", fStockPlaceIdFF100002); //
// fStockPlaceId.add("FSTOCKPLACEID__FF100002", fStockPlaceIdFF100002);
fStockPlaceId.add("FSTOCKPLACEID__FF100003", fStockPlaceIdFF100003);
subHeadEntity1.add("FStockPlaceId", fStockPlaceId); subHeadEntity1.add("FStockPlaceId", fStockPlaceId);
model.add("SubHeadEntity1", subHeadEntity1); model.add("SubHeadEntity1", subHeadEntity1);
@ -1163,6 +1308,36 @@ public class JdUtil {
return errorMessage; return errorMessage;
} }
} }
public static void updateDanzhong(int FMATERIALID, String danzhong) throws Exception {
K3CloudApi api = new K3CloudApi(false);
JsonObject json = new JsonObject();
// 创建 NeedUpDateFields 数组
JsonArray needUpDateFields = new JsonArray();
needUpDateFields.add("FMATERIALID");
needUpDateFields.add("F_HBYT_DZ");
//needUpDateFields.add("FIsVmiBusiness");
json.add("NeedUpDateFields", needUpDateFields);
// 添加 IsDeleteEntry 属性
json.addProperty("IsDeleteEntry", "false");
JsonObject model = new JsonObject();
model.addProperty("FMATERIALID", FMATERIALID); // 创建 Model 对象
model.addProperty("F_HBYT_DZ", danzhong);
json.add("Model", model);
String data = json.toString();
String result = api.save("BD_Material", data);
Gson gson = new Gson();
RepoRet sRet = gson.fromJson(result, RepoRet.class);
if (sRet.isSuccessfully()) {
String successMessage = String.format("物料 %s 保存成功", sRet.getResult().getResponseStatus());
System.out.println(successMessage);
} else {
String errorMessage = String.format("物料 %s 保存失败: %s", FMATERIALID, gson.toJson(sRet.getResult()));
System.out.println(errorMessage);
}
}
//查询物料清单 行iD //查询物料清单 行iD
public static List<JdHuoZhu> getFID(String materialCode) { public static List<JdHuoZhu> getFID(String materialCode) {
List<JdHuoZhu> jinYongDTOS = new ArrayList<>(); List<JdHuoZhu> jinYongDTOS = new ArrayList<>();
@ -1306,7 +1481,6 @@ public class JdUtil {
return null; // 如果没有找到返回 null return null; // 如果没有找到返回 null
} }
//保存更新生产订单的开工时间 //保存更新生产订单的开工时间
public static String updateOrder(JdHuoZhu jdHuoZhu, Model numDTO, Date xuStartTime, Date xuEndTime) throws Exception { public static String updateOrder(JdHuoZhu jdHuoZhu, Model numDTO, Date xuStartTime, Date xuEndTime) throws Exception {
String planStartDate = dateFormat.format(xuStartTime); String planStartDate = dateFormat.format(xuStartTime);
@ -1433,8 +1607,8 @@ public class JdUtil {
subHeadEntity1.addProperty("FIsEnableMaxStock", true); subHeadEntity1.addProperty("FIsEnableMaxStock", true);
subHeadEntity1.addProperty("FIsEnableSafeStock", true); subHeadEntity1.addProperty("FIsEnableSafeStock", true);
subHeadEntity1.addProperty(" FMaxStock", FMaxStock); subHeadEntity1.addProperty("FMaxStock", FMaxStock);
subHeadEntity1.addProperty(" FSafeStock", FSafeStock); subHeadEntity1.addProperty("FSafeStock", FSafeStock);
@ -1456,14 +1630,14 @@ public class JdUtil {
} }
} }
//获取用料清单 根据父级物料编码,作为bom校验使用 //获取用料清单 根据父级物料编码,作为bom校验使用
public static List<JDBom> getSelectBomList(String FMaterialCode) { public static List<JdValidateBomDTO> getSelectBomList(String FMaterialCode) {
K3CloudApi client = new K3CloudApi(); K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串 // 请求参数要求为json字符串
JsonObject json = new JsonObject(); JsonObject json = new JsonObject();
json.addProperty("FormId", "PRD_PPBOM"); json.addProperty("FormId", "ENG_BOM");
json.addProperty("FieldKeys", json.addProperty("FieldKeys",
"FNumber,FMATERIALID.FNumber,FITEMNAME,FUNITID.FName,F_HBYT_CZ,FCHILDITEMNAME,FCHILDITEMPROPERTY,FCHILDUNITID.FName,FNUMERATOR,FDENOMINATOR,F_HBYT_BJBM,F_HBYT_BJMC"); "FID,FMATERIALID.FNumber,FITEMNAME,FUNITID.FName,FCHILDITEMNAME,FCHILDITEMPROPERTY,FMATERIALIDCHILD.FNumber,FNUMERATOR,FDENOMINATOR,F_HBYT_BJBM,F_HBYT_BJMC");
JsonArray filterString = new JsonArray(); JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject(); JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMATERIALID.FNumber"); filterObject.addProperty("FieldName", "FMATERIALID.FNumber");
@ -1473,6 +1647,14 @@ public class JdUtil {
filterObject.addProperty("Right", ""); filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0); filterObject.addProperty("Logic", 0);
filterString.add(filterObject); filterString.add(filterObject);
JsonObject filterObjec1 = new JsonObject();
filterObjec1.addProperty("FieldName", "FForbidStatus");
filterObjec1.addProperty("Compare", "105");
filterObjec1.addProperty("Value", "A");
filterObjec1.addProperty("Left", "");
filterObjec1.addProperty("Right", "");
filterObjec1.addProperty("Logic", 0);
filterString.add(filterObjec1);
json.add("FilterString", filterString); json.add("FilterString", filterString);
json.addProperty("OrderString", ""); json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0); json.addProperty("TopRowCount", 0);
@ -1485,14 +1667,289 @@ public class JdUtil {
try { try {
// 调用API接口 // 调用API接口
resultJson = String.valueOf(client.billQuery(jsonData)); resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); // 将JsonArray转为JdValidateBomDTO列表
// 将JsonArray转为PlanOrder列表 return JdUtil.transformToJdValidateBomDTO(resultJson);
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(jsonArray.toString(), new TypeReference<List<JDBom>>() {
});
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
} }
public static String updateOldFuNumber(String FMATERIALID, String FNumber, String FOldNumber) throws Exception {
K3CloudApi api = new K3CloudApi(false);
JsonObject json = new JsonObject();
// 创建 NeedUpDateFields 数组
JsonArray needUpDateFields = new JsonArray();
needUpDateFields.add("FMATERIALID");
needUpDateFields.add("FNumber");
needUpDateFields.add("FOldNumber");
json.add("NeedUpDateFields", needUpDateFields);
// 添加 IsDeleteEntry 属性
json.addProperty("IsDeleteEntry", "false");
// 创建 Model 对象
JsonObject model = new JsonObject();
model.addProperty("FMATERIALID", FMATERIALID);
model.addProperty("FNumber", FNumber);
model.addProperty("FOldNumber", FOldNumber);
json.add("Model", model);
String data = json.toString();
String result = api.save("BD_Material", data);
Gson gson = new Gson();
RepoRet sRet = gson.fromJson(result, RepoRet.class);
if (sRet.isSuccessfully()) {
String successMessage = String.format("物料 %s 保存成功", sRet.getResult().getResponseStatus());
return successMessage;
} else {
String errorMessage = String.format("物料 %s 保存失败: %s", FMATERIALID, gson.toJson(sRet.getResult()));
return errorMessage;
}
}
public static List<JdValidateBomDTO> transformToJdValidateBomDTO(String jsonData) {
try {
ObjectMapper objectMapper = new ObjectMapper();
JsonArray jsonArray = new Gson().fromJson(jsonData, JsonArray.class);
Map<String, JdValidateBomDTO> bomMap = new HashMap<>();
for (JsonElement element : jsonArray) {
JsonObject obj = element.getAsJsonObject();
String key = obj.get("FID").getAsString() + "_" +
obj.get("FMATERIALID.FNumber").getAsString() + "_" +
obj.get("FITEMNAME").getAsString();
JdValidateBomDTO parentDTO = bomMap.computeIfAbsent(key, k -> {
JdValidateBomDTO dto = new JdValidateBomDTO();
dto.setFID(obj.get("FID").getAsString());
dto.setFNumber(obj.get("FMATERIALID.FNumber").getAsString());
dto.setFName(obj.get("FITEMNAME").getAsString());
dto.setChilds(new ArrayList<>());
return dto;
});
JdChildDTO childDTO = new JdChildDTO();
childDTO.setPartdiagramCode(obj.get("F_HBYT_BJBM").getAsString());
childDTO.setPartdiagramName(obj.get("F_HBYT_BJMC").getAsString());
childDTO.setWareHouse(obj.get("FUNITID.FName").getAsString());
childDTO.setPartNumber(obj.get("FMATERIALIDCHILD.FNumber").getAsString());
childDTO.setName(obj.get("FCHILDITEMNAME").getAsString());
childDTO.setStats(obj.get("FCHILDITEMPROPERTY").getAsString());
childDTO.setQuantity(obj.get("FNUMERATOR").getAsDouble());
childDTO.setDenominator(obj.get("FDENOMINATOR").getAsDouble());
parentDTO.getChilds().add(childDTO);
}
return new ArrayList<>(bomMap.values());
} catch (Exception e) {
e.printStackTrace();
return new ArrayList<>();
}
}
/**
* 获取生产用料清单
* @param F_HBYT_SCLH
* @return
*/
public static List<MaterialUsageDTO2> getPRD_PPBOM(String F_HBYT_SCLH) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "PRD_PPBOM");
json.addProperty("FieldKeys",
"F_HBYT_SCLH,FMaterialID.FNumber,FMaterialName,FUnitID2.FName,FMaterialID2.FNumber,FMaterialName1,FNumerator,FDenominator,FMustQty,FPickedQty,F_HBYT_CZ,F_HBYT_DZ");
// 创建过滤条件
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "F_HBYT_SCLH");
filterObject.addProperty("Compare", "67");
filterObject.addProperty("Value", F_HBYT_SCLH);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
json.addProperty("StartRow", 0);
json.addProperty("Limit", 2000);
json.addProperty("SubSystemId", "");
String jsonData = json.toString();
List<MaterialUsageDTO2> materialUsageDTO2List = null;
try {
// 调用接口
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
// 使用 ObjectMapper JsonArray 转换为 List<PlannedProcessVo>
ObjectMapper objectMapper = new ObjectMapper();
materialUsageDTO2List = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<MaterialUsageDTO2>>() {
});
} catch (Exception e) {
e.printStackTrace(); // 输出异常日志
}
return materialUsageDTO2List; // 返回结果
}
//用料清单查询接口腹肌无聊
public static List<JinYongDTO> getEngBom(String materialCode) {
List<JinYongDTO> jinYongDTOS = new ArrayList<>();
K3CloudApi client = new K3CloudApi();
JsonObject json = new JsonObject();
json.addProperty("FormId", "ENG_BOM");
json.addProperty("FieldKeys", "FNumber");
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMATERIALIDCHILD.FNumber");
filterObject.addProperty("Compare", "=");
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
json.addProperty("StartRow", 0);
json.addProperty("Limit", 2000);
json.addProperty("SubSystemId", "");
String jsonData = json.toString();
try {
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
if (jsonArray != null && jsonArray.size() > 0) {
ObjectMapper objectMapper = new ObjectMapper();
List<JinYongDTO> JinYongDTOList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<JinYongDTO>>() {});
if (JinYongDTOList != null && !JinYongDTOList.isEmpty()) {
jinYongDTOS.addAll(JinYongDTOList);
}
} else {
log.warn("未找到与bom版本号 " + materialCode + " 相关的记录");
}
} catch (Exception e) {
log.error("调用接口时发生异常: " + e.getMessage(), e);
}
return jinYongDTOS;
}
/**
* 获取固定工艺路线
* @param FMaterialCode
* @return
*/
public static List<ProcessRouteDTO> getRouteGuDing(String FMaterialCode) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "ENG_Route");
json.addProperty("FieldKeys",
"FNumber,FOperNumber,FWorkCenterId.FName,FProcessId.FName,FOperDescription,FOptCtrlCodeId.FName,FActivity1Qty,FActivity1UnitID.FName");
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMATERIALID.FNumber");
filterObject.addProperty("Compare", "67");
filterObject.addProperty("Value", FMaterialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
JsonObject filterObject1 = new JsonObject();
filterObject1.addProperty("FieldName", "FForbidStatus");
filterObject1.addProperty("Compare", "105");
filterObject1.addProperty("Value", "A");
filterObject1.addProperty("Left", "");
filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);
filterString.add(filterObject1);
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
json.addProperty("StartRow", 0);
json.addProperty("Limit", 2000);
json.addProperty("SubSystemId", "");
String jsonData = json.toString();
try {
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
if (jsonArray != null && jsonArray.size() > 0) {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(jsonArray.toString(), new TypeReference<List<ProcessRouteDTO>>() {});
} else {
return Collections.emptyList();
}
} catch (Exception e) {
log.error("调用接口时发生异常: " + e.getMessage(), e);
}
return Collections.emptyList();
}
/**
* 获取物料清单
* @param FMaterialCode
* @return
*/
public static List<MaterialUseDTO> getMaterialUseX(String FMaterialCode) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "ENG_BOM");
json.addProperty("FieldKeys", "FNumber,FMATERIALIDCHILD.FNumber,FCHILDITEMNAME,FCHILDUNITID.FName,FNUMERATOR,FDENOMINATOR,F_HBYT_DZ,F_HBYT_CZ");
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMATERIALID.FNumber");
filterObject.addProperty("Compare", "67");
filterObject.addProperty("Value", FMaterialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
JsonObject filterObject1 = new JsonObject();
filterObject1.addProperty("FieldName", "FForbidStatus");
filterObject1.addProperty("Compare", "105");
filterObject1.addProperty("Value", "A");
filterObject1.addProperty("Left", "");
filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);
filterString.add(filterObject1);
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
json.addProperty("StartRow", 0);
json.addProperty("Limit", 2000);
json.addProperty("SubSystemId", "");
String jsonData = json.toString();
try {
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
if (jsonArray != null && jsonArray.size() > 0) {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(jsonArray.toString(), new TypeReference<List<MaterialUseDTO>>() {});
} else {
return Collections.emptyList();
}
} catch (Exception e) {
log.error("调用接口时发生异常: " + e.getMessage(), e);
}
return Collections.emptyList();
}
} }

View File

@ -39,7 +39,7 @@ public interface IProcessRouteService {
/** /**
* 查询工艺路线列表 * 查询工艺路线列表
*/ */
List<ProcessRouteVo> queryList(ProcessRouteBo bo); List<ProcessRoute> queryList(ProcessRouteBo bo);
/** /**
* 新增工艺路线 * 新增工艺路线
@ -119,6 +119,7 @@ public interface IProcessRouteService {
boolean isAnTuDingGou(String materialCode); boolean isAnTuDingGou(String materialCode);
List<ProcessRouteSelectDTO> getSelectProcessRoute(String materilCode); List<ProcessRouteSelectDTO> getSelectProcessRoute(String materilCode);
List<ProcessRouteSelectDTO> getSelectStandProcessRoute(String materilCode);
//根据项目令号删除 材料bom 总装bom 工艺路线 //根据项目令号删除 材料bom 总装bom 工艺路线
R<Void> selectByProjectCode(String productionOrderNo); R<Void> selectByProjectCode(String productionOrderNo);
@ -134,4 +135,8 @@ public interface IProcessRouteService {
List<Model> updateProcesTime(String rooteProdet) throws Exception; List<Model> updateProcesTime(String rooteProdet) throws Exception;
List<ProcessRouteVo> queryList2(ProcessRouteBo bo); List<ProcessRouteVo> queryList2(ProcessRouteBo bo);
List<MaterialBom> getProcessMaterialListAll(String routeDescription);
List<JDMaterialAndRoute> getProcessRouteGD(List<ProcessRouteVo> list);
} }

View File

@ -2,6 +2,7 @@ package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.SafetyStock;
import com.ruoyi.system.domain.bo.SafetyStockBo; import com.ruoyi.system.domain.bo.SafetyStockBo;
import com.ruoyi.system.domain.vo.SafetyStockVo; import com.ruoyi.system.domain.vo.SafetyStockVo;
@ -45,4 +46,6 @@ public interface ISafetyStockService {
* 校验并批量删除安全库存信息 * 校验并批量删除安全库存信息
*/ */
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
List<SafetyStock> selectByType(String type1);
} }

View File

@ -50,4 +50,6 @@ public interface IWorkProcedureService {
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
List<ProductctionPlanGatteDto> getGongXuTasks(String text); List<ProductctionPlanGatteDto> getGongXuTasks(String text);
List<ProductctionPlanGatteDto> getAllTasks1();
} }

View File

@ -12,11 +12,14 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.system.controller.BomDetailsController; import com.ruoyi.system.controller.BomDetailsController;
import com.ruoyi.system.domain.MaterialBom;
import com.ruoyi.system.domain.MaterialProperties; import com.ruoyi.system.domain.MaterialProperties;
import com.ruoyi.system.mapper.MaterialBomMapper;
import com.ruoyi.system.service.IMaterialPropertiesService; import com.ruoyi.system.service.IMaterialPropertiesService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.system.domain.bo.BomDetailsBo; import com.ruoyi.system.domain.bo.BomDetailsBo;
import com.ruoyi.system.domain.vo.BomDetailsVo; import com.ruoyi.system.domain.vo.BomDetailsVo;
@ -27,6 +30,7 @@ import com.ruoyi.system.service.IBomDetailsService;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Collection; import java.util.Collection;
import java.util.stream.Collectors;
import static org.aspectj.bridge.MessageUtil.fail; import static org.aspectj.bridge.MessageUtil.fail;
@ -43,7 +47,8 @@ public class BomDetailsServiceImpl implements IBomDetailsService {
private final BomDetailsMapper baseMapper; private final BomDetailsMapper baseMapper;
private final IMaterialPropertiesService iMaterialPropertiesService; private final IMaterialPropertiesService iMaterialPropertiesService;
private static final Logger log = LoggerFactory.getLogger(BomDetailsController.class); private static final Logger log = LoggerFactory.getLogger(BomDetailsController.class);
@Autowired
MaterialBomMapper materialBomMapper;
/** /**
* 查询bom明细 * 查询bom明细
*/ */
@ -186,13 +191,40 @@ public class BomDetailsServiceImpl implements IBomDetailsService {
* @param totalWeight * @param totalWeight
* @return * @return
*/ */
@Override
public List<BomDetails> selectByFNumberAndTotalWeight(String fnumber, String totalWeight) { public List<BomDetails> selectByFNumberAndTotalWeight(String fnumber, String totalWeight) {
// 查询 BomDetails
LambdaQueryWrapper<BomDetails> bomDetailsLambdaQueryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<BomDetails> bomDetailsLambdaQueryWrapper = new LambdaQueryWrapper<>();
bomDetailsLambdaQueryWrapper.eq(BomDetails::getTotalWeight,totalWeight) bomDetailsLambdaQueryWrapper.eq(BomDetails::getTotalWeight, totalWeight)
.eq(BomDetails::getFNumber,fnumber); .eq(BomDetails::getFNumber, fnumber);
return baseMapper.selectList(bomDetailsLambdaQueryWrapper); List<BomDetails> bomDetails = baseMapper.selectList(bomDetailsLambdaQueryWrapper);
// 查询 MaterialBom
LambdaQueryWrapper<MaterialBom> materialBomLambdaQueryWrapper = new LambdaQueryWrapper<>();
materialBomLambdaQueryWrapper.eq(MaterialBom::getParentMaterialCode, fnumber)
.eq(MaterialBom::getProjectNumber, totalWeight);
List<MaterialBom> materialBoms = materialBomMapper.selectList(materialBomLambdaQueryWrapper);
// 使用Map缓存MaterialBom避免双重循环带来的性能问题
if (!materialBoms.isEmpty() && !bomDetails.isEmpty()) {
Map<String, MaterialBom> materialBomMap = materialBoms.stream()
.collect(Collectors.toMap(
mb -> mb.getMaterialCode() + "-" + mb.getMaterialName(),
mb -> mb,
(existing, replacement) -> existing
));
for (BomDetails bomDetail : bomDetails) {
String key = bomDetail.getPartNumber() + "-" + bomDetail.getName();
MaterialBom matchedMaterialBom = materialBomMap.get(key);
if (matchedMaterialBom != null) {
bomDetail.setQuantity(Double.valueOf(String.valueOf(matchedMaterialBom.getQuantity())));
} }
}
}
return bomDetails;
}
public int loadMaterialPreservation(BomDetails bomDetails1) { public int loadMaterialPreservation(BomDetails bomDetails1) {
K3CloudApi client = new K3CloudApi(); K3CloudApi client = new K3CloudApi();

View File

@ -17,6 +17,7 @@ import com.ruoyi.system.runner.JdUtil;
import com.ruoyi.system.service.IMaterialPropertiesService; import com.ruoyi.system.service.IMaterialPropertiesService;
import com.ruoyi.system.service.ISysDictDataService; import com.ruoyi.system.service.ISysDictDataService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.bridge.MessageUtil; import org.aspectj.bridge.MessageUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -42,6 +43,7 @@ import java.util.*;
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
public class EleMaterialsServiceImpl implements IEleMaterialsService { public class EleMaterialsServiceImpl implements IEleMaterialsService {
private final EleMaterialsMapper baseMapper; private final EleMaterialsMapper baseMapper;
@ -145,7 +147,6 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
@Override @Override
public Boolean updateByBo(EleMaterialsBo bo) { public Boolean updateByBo(EleMaterialsBo bo) {
EleMaterials update = BeanUtil.toBean(bo, EleMaterials.class); EleMaterials update = BeanUtil.toBean(bo, EleMaterials.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0; return baseMapper.updateById(update) > 0;
} }
@ -335,7 +336,7 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
// 创建一个空的JsonObject // 创建一个空的JsonObject
JsonObject json = new JsonObject(); JsonObject json = new JsonObject();
// 添加IsAutoSubmitAndAudit字段 // 添加IsAutoSubmitAndAudit字段
json.addProperty("IsAutoSubmitAndAudit", "true"); json.addProperty("IsAutoSubmitAndAudit", "false");
// 创建Model对象并加入JsonObject // 创建Model对象并加入JsonObject
JsonObject model = new JsonObject(); JsonObject model = new JsonObject();

View File

@ -20,6 +20,10 @@ import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.controller.ImMaterialController; import com.ruoyi.system.controller.ImMaterialController;
import com.ruoyi.system.domain.ImMaterial; import com.ruoyi.system.domain.ImMaterial;
import com.ruoyi.system.domain.bo.ImMaterialBo; import com.ruoyi.system.domain.bo.ImMaterialBo;
import com.ruoyi.system.domain.dto.JDInventoryDTO;
import com.ruoyi.system.domain.dto.JDProductionDTO;
import com.ruoyi.system.domain.dto.ProMoDTO;
import com.ruoyi.system.domain.dto.PurchaseOrderDTO;
import com.ruoyi.system.domain.vo.ImMaterialVo; import com.ruoyi.system.domain.vo.ImMaterialVo;
import com.ruoyi.system.mapper.ImMaterialMapper; import com.ruoyi.system.mapper.ImMaterialMapper;
import com.ruoyi.system.runner.JdUtil; import com.ruoyi.system.runner.JdUtil;
@ -71,7 +75,7 @@ public class ImMaterialServiceImpl implements IImMaterialService {
// 添加额外的过滤条件排除售后库 // 添加额外的过滤条件排除售后库
JsonObject excludeStockFilter = new JsonObject(); JsonObject excludeStockFilter = new JsonObject();
excludeStockFilter.addProperty("FieldName", "FStockId.FNumber"); // 设置字段名称为仓库编号 excludeStockFilter.addProperty("FieldName", "FStockId.FNumber"); // 设置字段名称为仓库编号
excludeStockFilter.addProperty("Compare", "83"); // 设置比较方式为不等于 (假设 83 代表不等于) excludeStockFilter.addProperty("Compare", "83"); // 设置比较方式为"不等于" (假设 83 代表不等于)
excludeStockFilter.addProperty("Value", "CK012"); // 设置需要排除的仓库编号 excludeStockFilter.addProperty("Value", "CK012"); // 设置需要排除的仓库编号
excludeStockFilter.addProperty("Left", ""); // 保留字段不使用 excludeStockFilter.addProperty("Left", ""); // 保留字段不使用
excludeStockFilter.addProperty("Right", ""); // 保留字段不使用 excludeStockFilter.addProperty("Right", ""); // 保留字段不使用
@ -81,7 +85,7 @@ public class ImMaterialServiceImpl implements IImMaterialService {
ImMaterialVo record = records.get(i); ImMaterialVo record = records.get(i);
JsonObject filterObject = new JsonObject(); // 每次循环创建新的过滤条件对象 JsonObject filterObject = new JsonObject(); // 每次循环创建新的过滤条件对象
filterObject.addProperty("FieldName", "FMaterialId.FNumber"); // 设置字段名称为物料编码 filterObject.addProperty("FieldName", "FMaterialId.FNumber"); // 设置字段名称为物料编码
filterObject.addProperty("Compare", "67"); // 设置比较方式为等于 (假设 67 代表等于) filterObject.addProperty("Compare", "67"); // 设置比较方式为"等于" (假设 67 代表等于)
filterObject.addProperty("Value", record.getMaterialCode()); // 设置比较的值为物料编码 filterObject.addProperty("Value", record.getMaterialCode()); // 设置比较的值为物料编码
// 为第一个和最后一个元素设置括号 // 为第一个和最后一个元素设置括号
if (i == 0) { if (i == 0) {
@ -171,6 +175,7 @@ public class ImMaterialServiceImpl implements IImMaterialService {
public TableDataInfo<ImMaterialVo> queryPageList(ImMaterialBo bo, PageQuery pageQuery) { public TableDataInfo<ImMaterialVo> queryPageList(ImMaterialBo bo, PageQuery pageQuery) {
try { try {
System.out.println("查询开始"+System.currentTimeMillis());
LambdaQueryWrapper<ImMaterial> lqw = buildQueryWrapper(bo); LambdaQueryWrapper<ImMaterial> lqw = buildQueryWrapper(bo);
// 执行查询 // 执行查询
@ -179,8 +184,11 @@ public class ImMaterialServiceImpl implements IImMaterialService {
if (CollectionUtils.isEmpty(result.getRecords())) { if (CollectionUtils.isEmpty(result.getRecords())) {
return TableDataInfo.build(result); // 如果结果为空直接返回 return TableDataInfo.build(result); // 如果结果为空直接返回
} }
System.out.println("查询结束"+System.currentTimeMillis());
// 调用库存查询方法优化为批量查询而非逐个查询 // 调用库存查询方法优化为批量查询而非逐个查询
Map<String, JsonObject> jsonMap = queryAllKuCun(result.getRecords()); Map<String, JsonObject> jsonMap = queryAllKuCun(result.getRecords());
System.out.println("组装结束"+System.currentTimeMillis());
// 更新库存信息 // 更新库存信息
updateRecordsWithKuCunInfo(jsonMap, result.getRecords()); updateRecordsWithKuCunInfo(jsonMap, result.getRecords());
// 更新数量更新实体类 // 更新数量更新实体类
@ -268,9 +276,7 @@ public class ImMaterialServiceImpl implements IImMaterialService {
for (JsonElement jsonElement : jsonArray) { for (JsonElement jsonElement : jsonArray) {
JsonObject jsonObject = jsonElement.getAsJsonObject(); JsonObject jsonObject = jsonElement.getAsJsonObject();
String materialCode = jsonObject.get("FMaterialId.FNumber").getAsString(); String materialCode = jsonObject.get("FMaterialId.FNumber").getAsString();
BigDecimal lockQty = Optional.ofNullable(jsonObject.get("FLockQty")) BigDecimal lockQty = Optional.ofNullable(jsonObject.get("FLockQty")).map(JsonElement::getAsBigDecimal).orElse(BigDecimal.ZERO);
.map(JsonElement::getAsBigDecimal)
.orElse(BigDecimal.ZERO);
lockStockMap.merge(materialCode, lockQty, BigDecimal::add); lockStockMap.merge(materialCode, lockQty, BigDecimal::add);
} }
} }
@ -286,8 +292,6 @@ public class ImMaterialServiceImpl implements IImMaterialService {
* @return * @return
*/ */
private void updateRecordsWithKuCunInfo(Map<String, JsonObject> jsonMap, List<ImMaterialVo> records) { private void updateRecordsWithKuCunInfo(Map<String, JsonObject> jsonMap, List<ImMaterialVo> records) {
// 先查询锁库信息
Map<String, BigDecimal> lockStockMap = queryLockStock(records);
for (ImMaterialVo record : records) { for (ImMaterialVo record : records) {
String materialCode = record.getMaterialCode(); String materialCode = record.getMaterialCode();
JsonObject jsonObject = jsonMap.get(materialCode); JsonObject jsonObject = jsonMap.get(materialCode);
@ -299,7 +303,7 @@ public class ImMaterialServiceImpl implements IImMaterialService {
String unit = jsonObject.get("FStockUnitId.FName").getAsString(); String unit = jsonObject.get("FStockUnitId.FName").getAsString();
if (unit != null && !unit.isEmpty()) { if (unit != null && !unit.isEmpty()) {
record.setClassificationName(unit); record.setClassificationName(unit);
}else { } else {
record.setClassificationName(""); record.setClassificationName("");
} }
@ -312,18 +316,13 @@ public class ImMaterialServiceImpl implements IImMaterialService {
} else { } else {
record.setMaterialQuality(""); record.setMaterialQuality("");
} }
// 计算可用库存
BigDecimal totalLockQty = lockStockMap.getOrDefault(materialCode, BigDecimal.ZERO);
BigDecimal unit = Optional.ofNullable(record.getUnit()) // 使用keYong方法计算可用库存
.map(NumberUtils::createBigDecimal) ImMaterial material = BeanUtil.toBean(record, ImMaterial.class);
.orElse(BigDecimal.ZERO); /* double availableStock = keYong(material);
record.setSingleWeight(BigDecimal.valueOf(availableStock));*/
// 计算 subtract如果 totalLockQty 0 或者为空subtract 就是 unit // 更新记录
BigDecimal subtract = unit.subtract(totalLockQty);
record.setSingleWeight(subtract); // 可用数量
// 仅当记录确实需要更新时执行更新操作
ImMaterial bean = BeanUtil.toBean(record, ImMaterial.class); ImMaterial bean = BeanUtil.toBean(record, ImMaterial.class);
baseMapper.updateById(bean); baseMapper.updateById(bean);
} }
@ -336,6 +335,46 @@ public class ImMaterialServiceImpl implements IImMaterialService {
public ImMaterialVo queryById(Long id) { public ImMaterialVo queryById(Long id) {
return baseMapper.selectVoById(id); return baseMapper.selectVoById(id);
} }
/**
* 计算可用库存
*/
public double keYong(ImMaterial material) {
// 获取库存
System.out.println("查询可用库存开始=============>"+System.currentTimeMillis());
double inventoryQty = Optional.ofNullable(JdUtil.getKuCun(material.getMaterialCode()))
.map(list ->list.stream()
.mapToDouble(JDInventoryDTO::getFBaseQty)
.sum())
.orElse(0.0);
System.out.println("查询子项物料的未领料量=============>"+System.currentTimeMillis());
// 查询子项物料的未领料量
double fNoPickedQty = Optional.ofNullable(JdUtil.getWeiLingliao(material.getMaterialCode()))
.map(list ->list.stream()
.mapToDouble(JDProductionDTO::getFNoPickedQty)
.sum())
.orElse(0.0);
System.out.println("获取生产订单未入库数量数量=============>"+System.currentTimeMillis());
// 获取生产订单未入库数量数量
double productionQty = Optional.ofNullable(JdUtil.getProMoList(material.getMaterialCode()))
.map(list -> list.stream()
.mapToDouble(ProMoDTO::getFQty)
.sum())
.orElse(0.0);
System.out.println("获取采购订单未入库数量=============>"+System.currentTimeMillis());
// 获取采购订单未入库数量
double purchaseQty = Optional.ofNullable(JdUtil.getPurchaseOrderList(material.getMaterialCode()))
.map(list -> list.stream()
.mapToDouble(PurchaseOrderDTO::getFRemainStockINQty)
.sum())
.orElse(0.0);
// 计算预计可用库存
System.out.println("计算预计可用库存=============>"+System.currentTimeMillis());
return inventoryQty + productionQty + purchaseQty - fNoPickedQty;
}
/** /**

View File

@ -7,6 +7,7 @@ import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.utils.file.SmbUtil;
import com.ruoyi.system.domain.EleMaterials; import com.ruoyi.system.domain.EleMaterials;
import com.ruoyi.system.domain.ProcessRoute; import com.ruoyi.system.domain.ProcessRoute;
import com.ruoyi.system.mapper.ProcessRouteMapper; import com.ruoyi.system.mapper.ProcessRouteMapper;
@ -87,6 +88,10 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
*/ */
@Override @Override
public Boolean insertByBo(ProcessOrderProBo bo) { public Boolean insertByBo(ProcessOrderProBo bo) {
// 下载excel文件
log.info("下载excel文件.."+bo.getProductionOrderNo());
SmbUtil.downloadExcelFiles(bo.getProductionOrderNo());
ProcessOrderPro add = BeanUtil.toBean(bo, ProcessOrderPro.class); ProcessOrderPro add = BeanUtil.toBean(bo, ProcessOrderPro.class);
validEntityBeforeSave(add); validEntityBeforeSave(add);
@ -160,7 +165,6 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
LambdaQueryWrapper<ProcessRoute> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<ProcessRoute> wrapper = new LambdaQueryWrapper<>();
LambdaQueryWrapper<ProcessRoute> eq = wrapper.eq(ProcessRoute::getProcessDescription, bo.getProductionOrderNo()); LambdaQueryWrapper<ProcessRoute> eq = wrapper.eq(ProcessRoute::getProcessDescription, bo.getProductionOrderNo());
List<ProcessRoute> processRoutes = processRouteMapper.selectList(wrapper); List<ProcessRoute> processRoutes = processRouteMapper.selectList(wrapper);
System.out.println(processRoutes);
return processRouteMapper.selectList(wrapper); return processRouteMapper.selectList(wrapper);
} }
} }

View File

@ -2,6 +2,7 @@ package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@ -44,13 +45,16 @@ import org.aspectj.bridge.MessageUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.ruoyi.system.controller.BomDetailsController.*; import static com.ruoyi.system.controller.BomDetailsController.*;
@ -82,6 +86,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
@Autowired @Autowired
ProcessInfoMapper processInfoMapper; ProcessInfoMapper processInfoMapper;
private final ProductionRouteTwoMapper productionRouteTwoMapper; private final ProductionRouteTwoMapper productionRouteTwoMapper;
private final IBomDetailsService bomDetailsService; private final IBomDetailsService bomDetailsService;
@ -125,9 +130,9 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
} }
@Override @Override
public List<ProcessRouteVo> queryList(ProcessRouteBo bo) { public List<ProcessRoute> queryList(ProcessRouteBo bo) {
LambdaQueryWrapper<ProcessRoute> lqw = buildQueryWrapper(bo); LambdaQueryWrapper<ProcessRoute> lqw = buildQueryWrapper(bo);
List<ProcessRouteVo> sortedList = new ArrayList<>(); List<ProcessRoute> sortedList = new ArrayList<>();
// 获取工艺表中材质为总装部件的物料编码和名称 // 获取工艺表中材质为总装部件的物料编码和名称
LambdaQueryWrapper<ProcessRoute> lqwRoute = buildQueryWrapper(bo); LambdaQueryWrapper<ProcessRoute> lqwRoute = buildQueryWrapper(bo);
@ -138,16 +143,11 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
if (!processRoutes.isEmpty()) { if (!processRoutes.isEmpty()) {
// 装配工艺路线 // 装配工艺路线
for (ProcessRoute processRoute : processRoutes) { for (ProcessRoute processRoute : processRoutes) {
List<ProcessRoute> routes1 = getProcessRoutesByOrder(processRoute.getRouteDescription(), List<ProcessRoute> routes1 = getProcessRoutesByOrder(processRoute.getRouteDescription(), processRoute.getMaterialCode());
processRoute.getMaterialCode()); sortedList.addAll(routes1);
for (ProcessRoute route : routes1) {
ProcessRouteVo processRouteVo1 = BeanUtil.copyProperties(route, ProcessRouteVo.class);
sortedList.add(processRouteVo1);
}
// 查询 BOM 详情 // 查询 BOM 详情
List<BomDetails> bomDetails1 = bomDetailsService.selectByFNumberAndTotalWeight( List<BomDetails> bomDetails1 = bomDetailsService.selectByFNumberAndTotalWeight(processRoute.getMaterialCode(), processRoute.getRouteDescription());
processRoute.getMaterialCode(), processRoute.getRouteDescription());
List<BomDetails> filteredBomDetails = filterBomDetails(bomDetails1); List<BomDetails> filteredBomDetails = filterBomDetails(bomDetails1);
log.info("过滤后的 BOM 详情数量: {}", filteredBomDetails.size()); log.info("过滤后的 BOM 详情数量: {}", filteredBomDetails.size());
@ -158,8 +158,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
// 将组焊件写入工艺 // 将组焊件写入工艺
if ("组焊件".equals(bomDetail.getMaterial())) { if ("组焊件".equals(bomDetail.getMaterial())) {
List<BomDetails> bomDetails = bomDetailsService List<BomDetails> bomDetails = bomDetailsService.selectByFNumberAndTotalWeight(bomDetail.getPartNumber(), bomDetail.getTotalWeight());
.selectByFNumberAndTotalWeight(bomDetail.getPartNumber(), bomDetail.getTotalWeight());
for (BomDetails detail : bomDetails) { for (BomDetails detail : bomDetails) {
addProcessRoutesFromBomDetail(detail, sortedList); addProcessRoutesFromBomDetail(detail, sortedList);
} }
@ -176,7 +175,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
for (ProcessRoute processRoute : normalProcessRoutes) { for (ProcessRoute processRoute : normalProcessRoutes) {
// 创建一个新的 ProcessRouteVo 对象并复制 ProcessRoute 的基本信息 // 创建一个新的 ProcessRouteVo 对象并复制 ProcessRoute 的基本信息
ProcessRouteVo processRouteVo = BeanUtil.copyProperties(processRoute, ProcessRouteVo.class); ProcessRoute processRouteVo = BeanUtil.copyProperties(processRoute, ProcessRoute.class);
processRouteVo.setRawMaterialName(null); processRouteVo.setRawMaterialName(null);
processRouteVo.setRawMaterialCode(null); processRouteVo.setRawMaterialCode(null);
processRouteVo.setBomMaterial(null); processRouteVo.setBomMaterial(null);
@ -194,7 +193,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
String key = generateKey1(bomDetail,processRoute); // 生成唯一键 String key = generateKey1(bomDetail,processRoute); // 生成唯一键
if (!addedKeys.contains(key)) { if (!addedKeys.contains(key)) {
// 创建一个新的 ProcessRouteVo 对象来存储 BOM 详情的信息 // 创建一个新的 ProcessRouteVo 对象来存储 BOM 详情的信息
ProcessRouteVo bomDetailsVo = new ProcessRouteVo(); ProcessRoute bomDetailsVo = new ProcessRoute();
bomDetailsVo.setRouteDescription(bomDetail.getTotalWeight()); bomDetailsVo.setRouteDescription(bomDetail.getTotalWeight());
bomDetailsVo.setMaterialCode(bomDetail.getFNumber()); bomDetailsVo.setMaterialCode(bomDetail.getFNumber());
bomDetailsVo.setMaterialName(bomDetail.getFName()); bomDetailsVo.setMaterialName(bomDetail.getFName());
@ -204,9 +203,10 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
bomDetailsVo.setRawMaterialName(bomDetail.getName()); bomDetailsVo.setRawMaterialName(bomDetail.getName());
bomDetailsVo.setBomUnit(bomDetail.getWareHouse()); bomDetailsVo.setBomUnit(bomDetail.getWareHouse());
// 找到对应的 ProcessRouteVo 位置并插入 // 找到对应的 ProcessRouteVo 位置并插入
for (int i = 0; i < sortedList.size(); i++) { for (int i = 0; i < sortedList.size(); i++) {
ProcessRouteVo existingVo = sortedList.get(i); ProcessRoute existingVo = sortedList.get(i);
if (existingVo.getMaterialCode().equals(bomDetailsVo.getMaterialCode()) && if (existingVo.getMaterialCode().equals(bomDetailsVo.getMaterialCode()) &&
existingVo.getMaterialName().equals(bomDetailsVo.getMaterialName())) { existingVo.getMaterialName().equals(bomDetailsVo.getMaterialName())) {
sortedList.add(i, bomDetailsVo); // 插入到匹配的 ProcessRouteVo 之前 sortedList.add(i, bomDetailsVo); // 插入到匹配的 ProcessRouteVo 之前
@ -233,6 +233,50 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
return Collections.emptyList(); return Collections.emptyList();
} }
/**
* @param routeDescription
* @return
*/
@Override
public List<MaterialBom> getProcessMaterialListAll(String routeDescription) {
QueryWrapper<MaterialBom> wrapper = new QueryWrapper<>();
wrapper.eq("project_number", routeDescription);
return materialBomMapper.selectList(wrapper);
}
/**
* @param list
* @return
*/
@Override
public List<JDMaterialAndRoute> getProcessRouteGD(List<ProcessRouteVo> list) {
List<JDMaterialAndRoute> materialAndRouteList = new ArrayList<>();
for (ProcessRouteVo processRoute : list) {
//获取固定工艺路线和物料清单
List<ProcessRouteDTO> routeList = JdUtil.getRouteGuDing(processRoute.getRouteDescription());
List<MaterialUseDTO> materialUseX = JdUtil.getMaterialUseX(processRoute.getRouteDescription());
if (materialUseX == null || routeList == null) {
continue;
}
//表格错乱错行了
JDMaterialAndRoute jdMaterialAndRoute = new JDMaterialAndRoute();
jdMaterialAndRoute.setMaterialCode(processRoute.getRouteDescription());
jdMaterialAndRoute.setMaterialName(processRoute.getMaterialCode());
jdMaterialAndRoute.setCaizhi(processRoute.getMaterialName());
jdMaterialAndRoute.setDanzhong(processRoute.getMaterial());
jdMaterialAndRoute.setMaterialUseDTOS(materialUseX);
jdMaterialAndRoute.setPlannedProcessVos(routeList);
jdMaterialAndRoute.setBenpi(processRoute.getUnitQuantity());
jdMaterialAndRoute.setDantai(Long.valueOf(processRoute.getActivityUnit()));
materialAndRouteList.add(jdMaterialAndRoute);
}
return materialAndRouteList;
}
private String generateKey1(BomDetails bomDetail,ProcessRoute processRoute) { private String generateKey1(BomDetails bomDetail,ProcessRoute processRoute) {
return String.format("%s:%s:%s", processRoute.getMaterialCode(), processRoute.getMaterialName(), bomDetail.getName(),bomDetail.getPartNumber()); return String.format("%s:%s:%s", processRoute.getMaterialCode(), processRoute.getMaterialName(), bomDetail.getName(),bomDetail.getPartNumber());
} }
@ -246,12 +290,9 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
private void addProcessRoutesFromBomDetail(BomDetails bomDetail, List<ProcessRouteVo> sortedList) { private void addProcessRoutesFromBomDetail(BomDetails bomDetail, List<ProcessRoute> sortedList) {
List<ProcessRoute> routes = getProcessRoutesByOrder(bomDetail.getTotalWeight(), bomDetail.getPartNumber()); List<ProcessRoute> routes = getProcessRoutesByOrder(bomDetail.getTotalWeight(), bomDetail.getPartNumber());
for (ProcessRoute route : routes) { sortedList.addAll(routes);
ProcessRouteVo processRouteVo1 = BeanUtil.copyProperties(route, ProcessRouteVo.class);
sortedList.add(processRouteVo1);
}
} }
private LambdaQueryWrapper<ProcessRoute> buildQueryWrapper(ProcessRouteBo bo) { private LambdaQueryWrapper<ProcessRoute> buildQueryWrapper(ProcessRouteBo bo) {
@ -503,11 +544,15 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
public boolean saveData(List<ProcessRouteVo> routeVoList, List<ProductionOrderVo> productionOrderVos) { public boolean saveData(List<ProcessRouteVo> routeVoList, List<ProductionOrderVo> productionOrderVos) {
List<ProcessRoute> processRoutes = BeanUtil.copyToList(routeVoList, ProcessRoute.class); List<ProcessRoute> processRoutes = BeanUtil.copyToList(routeVoList, ProcessRoute.class);
processMaterialBom(processRoutes); processMaterialBom(processRoutes);
List<BomDetailsVo> bomDetailsVos = processBomDetails(routeVoList, productionOrderVos); List<BomDetailsVo> bomDetailsVos = processBomDetails(routeVoList, productionOrderVos);
saveBomDetails(bomDetailsVos); saveBomDetails(bomDetailsVos);
List<ProcessRoute> routeArrayList = new ArrayList<>(); List<ProcessRoute> routeArrayList = new ArrayList<>();
Map<String, Double> inventoryCache = new HashMap<>(); Map<String, Double> inventoryCache = new HashMap<>();
// 批量查询所有需要的库存信息 // 批量查询所有需要的库存信息
@ -635,6 +680,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
} }
} }
private void processMaterialBom(List<ProcessRoute> processRoutes) { private void processMaterialBom(List<ProcessRoute> processRoutes) {
for (ProcessRoute processRoute : processRoutes) { for (ProcessRoute processRoute : processRoutes) {
if (processRoute.getRawMaterialCode() != null && processRoute.getRawMaterialName() != null) { if (processRoute.getRawMaterialCode() != null && processRoute.getRawMaterialName() != null) {
@ -644,8 +690,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
String unit = processRoute.getBomUnit(); String unit = processRoute.getBomUnit();
String materialType = processRoute.getBomMaterial(); String materialType = processRoute.getBomMaterial();
Double quantity = processRoute.getDiscUsage() != null ? processRoute.getDiscUsage() : 0; Double quantity = processRoute.getDiscUsage() != null ? processRoute.getDiscUsage() : 0;
if (projectNumber == null || parentMaterialCode == null || parentMaterialName == null || unit == null if (projectNumber == null || parentMaterialCode == null || parentMaterialName == null || unit == null || materialType == null) {
|| materialType == null) {
// 处理空值情况例如记录日志或抛出异常 // 处理空值情况例如记录日志或抛出异常
log.error("必填字段为空: {}", processRoute); log.error("必填字段为空: {}", processRoute);
continue; continue;
@ -659,7 +704,8 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
materialBom.setMaterialName(processRoute.getRawMaterialName()); materialBom.setMaterialName(processRoute.getRawMaterialName());
materialBom.setUnit(unit); materialBom.setUnit(unit);
materialBom.setMaterialType(materialType); materialBom.setMaterialType(materialType);
materialBom.setQuantity(String.valueOf(quantity)); //保留4位小数
materialBom.setQuantity(new BigDecimal(quantity));
// 这里插入 materialBom 数据 // 这里插入 materialBom 数据
materialBomMapper.insert(materialBom); materialBomMapper.insert(materialBom);
} }
@ -671,9 +717,9 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
* *
* @routeVoList 工艺路线 * @routeVoList 工艺路线
*/ */
private List<BomDetailsVo> processBomDetails(List<ProcessRouteVo> routeVoList, private List<BomDetailsVo> processBomDetails(List<ProcessRouteVo> routeVoList, List<ProductionOrderVo> productionOrderVos) {
List<ProductionOrderVo> productionOrderVos) {
List<BomDetailsVo> bomDetailsVos = new ArrayList<>(); List<BomDetailsVo> bomDetailsVos = new ArrayList<>();
//总装BOM
if (productionOrderVos != null && !productionOrderVos.isEmpty()) { if (productionOrderVos != null && !productionOrderVos.isEmpty()) {
List<ProductionOrder> productionOrderList = productionOrderVos.stream().map(productionOrderVo -> { List<ProductionOrder> productionOrderList = productionOrderVos.stream().map(productionOrderVo -> {
ProductionOrder productionOrder = new ProductionOrder(); ProductionOrder productionOrder = new ProductionOrder();
@ -685,7 +731,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
boolean b = productionOrderMapper.insertBatch(productionOrderList); boolean b = productionOrderMapper.insertBatch(productionOrderList);
log.info("插入到装备BOM清单中: {}", b); log.info("插入到装备BOM清单中: {}", b);
// 获取主产品图号 // 处理总装BOM 将bom存表 bomdetail
for (ProductionOrderVo productionOrderVo : productionOrderVos) { for (ProductionOrderVo productionOrderVo : productionOrderVos) {
BomDetailsVo bomDetails = new BomDetailsVo(); BomDetailsVo bomDetails = new BomDetailsVo();
bomDetails.setTotalWeight(productionOrderVo.getProductionOrderNo()); bomDetails.setTotalWeight(productionOrderVo.getProductionOrderNo());
@ -704,7 +750,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
} else { } else {
bomDetails.setRemarks(productionOrderVo.getRemark()); bomDetails.setRemarks(productionOrderVo.getRemark());
} }
bomDetails.setDanzhong(productionOrderVo.getSingleWeight()); bomDetails.setDanZhong(productionOrderVo.getSingleWeight());
// 判断外购或自制 // 判断外购或自制
String drawingNo = productionOrderVo.getDrawingNo(); String drawingNo = productionOrderVo.getDrawingNo();
String remark = productionOrderVo.getRemark(); String remark = productionOrderVo.getRemark();
@ -720,6 +766,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
bomDetailsVos.add(bomDetails); bomDetailsVos.add(bomDetails);
} }
} }
//将带工艺的bom 存表 bomdetail
if (routeVoList != null && !routeVoList.isEmpty()) { if (routeVoList != null && !routeVoList.isEmpty()) {
for (ProcessRouteVo processRouteVo : routeVoList) { for (ProcessRouteVo processRouteVo : routeVoList) {
if (processRouteVo.getRawMaterialCode() != null && processRouteVo.getRawMaterialName() != null) { if (processRouteVo.getRawMaterialCode() != null && processRouteVo.getRawMaterialName() != null) {
@ -728,7 +775,6 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
} }
} }
} }
return bomDetailsVos; // 如果需要返回结果 return bomDetailsVos; // 如果需要返回结果
} }
@ -745,7 +791,13 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
bomDetails.setFName(processRoute.getMaterialName()); bomDetails.setFName(processRoute.getMaterialName());
bomDetails.setPartNumber(processRoute.getRawMaterialCode()); bomDetails.setPartNumber(processRoute.getRawMaterialCode());
bomDetails.setName(processRoute.getRawMaterialName()); bomDetails.setName(processRoute.getRawMaterialName());
bomDetails.setDanzhong(processRoute.getDiscWeight());
// 添加单重验证和日志
Double discWeight = processRoute.getDiscWeight();
bomDetails.setDanZhong(discWeight);
bomDetails.setSingleWeghit(processRoute.getBomDanZhong());
bomDetails.setMaterial(processRoute.getMaterial());
// 处理单位换算 // 处理单位换算
if ("mm".equals(processRoute.getBomUnit())) { if ("mm".equals(processRoute.getBomUnit())) {
bomDetails.setQuantity(processRoute.getDiscUsage() / 1000.0); // 转换为米 bomDetails.setQuantity(processRoute.getDiscUsage() / 1000.0); // 转换为米
@ -769,45 +821,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
return bomDetails; return bomDetails;
} }
private void createAssemblyBomDetails(String zFlinghao, String zFnumber, String zFname,
List<ProductionOrderVo> productionOrderVos) {
List<BomDetailsVo> bomDetailsVos = new ArrayList<>();
for (ProductionOrderVo productionOrderVo : productionOrderVos) {
if (productionOrderVo != null) {
BomDetailsVo bomDetails = new BomDetailsVo();
bomDetails.setTotalWeight(zFlinghao);
bomDetails.setFNumber(zFnumber);
bomDetails.setFName(zFname);
bomDetails.setPartdiagramCode(productionOrderVo.getParentDrawingNo());
bomDetails.setPartdiagramName(productionOrderVo.getParentPart());
bomDetails.setPartNumber(productionOrderVo.getDrawingNo());
bomDetails.setName(productionOrderVo.getDrawingName());
bomDetails.setQuantity(productionOrderVo.getQuantity());
bomDetails.setMaterial(productionOrderVo.getMaterial());
bomDetails.setRemarks(productionOrderVo.getRemark());
bomDetails.setDanzhong(productionOrderVo.getSingleWeight());
// 判断外购或自制
String drawingNo = productionOrderVo.getDrawingNo();
String remark = productionOrderVo.getRemark();
if (drawingNo != null) {
if ((isOutsourced(drawingNo)
|| (remark != null && (remark.contains("外购件") || remark.contains("伊特")))
|| drawingNo.startsWith(" ")) || drawingNo.startsWith("009")) {
bomDetails.setStats("外购");
} else {
bomDetails.setStats("自制");
}
}
// iBomDetailsService.insertByVo(bomDetails);
bomDetailsVos.add(bomDetails);
}
}
log.info("总装bom物料添加");
saveBomDetails(bomDetailsVos);
}
public int loadMaterialPreservation(BomDetails bomDetails1, String states) { public int loadMaterialPreservation(BomDetails bomDetails1, String states) {
K3CloudApi client = new K3CloudApi(); K3CloudApi client = new K3CloudApi();
@ -1025,32 +1039,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
iBomDetailsService.insertByVo(BeanUtil.toBean(bomDetails, BomDetailsVo.class)); iBomDetailsService.insertByVo(BeanUtil.toBean(bomDetails, BomDetailsVo.class));
} }
/*
* // 新增不存在的物料
* for (BomDetails material : materialsToAdd) {
* if (material != null && material.getPartNumber() != null &&
* material.getName() != null) {
* String state = determineState(material);
* log.info("开始新增不存在的物料 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " +
* material.getName());
*
* int result = loadMaterialPreservation(material, state);
* if (result == 1) {
* log.info("新增物料成功 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " +
* material.getName());
* material.setUnitWeight("新增成功");
* } else {
* log.error("新增物料失败 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " +
* material.getName());
* }
*
* // 更新物料状态
* iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class));
* } else {
* log.error("物料信息不完整,无法新增物料");
* }
* }
*/
} }
@Override @Override
@ -1117,6 +1106,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
LambdaQueryWrapper<ProcessRoute> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<ProcessRoute> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ProcessRoute::getRouteDescription, rooteProdet).ne(ProcessRoute::getMaterialName, "") wrapper.eq(ProcessRoute::getRouteDescription, rooteProdet).ne(ProcessRoute::getMaterialName, "")
.ne(ProcessRoute::getProcessName, "按图订制") .ne(ProcessRoute::getProcessName, "按图订制")
.ne(ProcessRoute::getProcessName, "按图定制")
.isNotNull(ProcessRoute::getMaterialName).ne(ProcessRoute::getMaterialCode, "") .isNotNull(ProcessRoute::getMaterialName).ne(ProcessRoute::getMaterialCode, "")
.isNotNull(ProcessRoute::getMaterialCode).ne(ProcessRoute::getProcessNo, "") .isNotNull(ProcessRoute::getMaterialCode).ne(ProcessRoute::getProcessNo, "")
.isNotNull(ProcessRoute::getProcessNo).ne(ProcessRoute::getProcessName, "") .isNotNull(ProcessRoute::getProcessNo).ne(ProcessRoute::getProcessName, "")
@ -1165,8 +1155,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
* 查询这个项目下的所有工艺路线材料bom ,原材料bom集合 * 查询这个项目下的所有工艺路线材料bom ,原材料bom集合
*/ */
public List<ProcessRoute> getRawBomList(String rooteProdet) { public List<ProcessRoute> getRawBomList(String rooteProdet) {
return baseMapper return baseMapper.selectList(new LambdaQueryWrapper<ProcessRoute>().eq(ProcessRoute::getRouteDescription, rooteProdet));
.selectList(new LambdaQueryWrapper<ProcessRoute>().eq(ProcessRoute::getRouteDescription, rooteProdet));
} }
@Override @Override
@ -1252,8 +1241,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
return resultDTO; return resultDTO;
} }
private boolean compareProcessRoutes(List<ProcessRouteDTO> processRouteDT, private boolean compareProcessRoutes(List<ProcessRouteDTO> processRouteDT, Map<String, List<ProcessRouteSelectDTO>> groupedByFNumber) {
Map<String, List<ProcessRouteSelectDTO>> groupedByFNumber) {
// 对当前物料的工艺路线进行排序 // 对当前物料的工艺路线进行排序
processRouteDT.sort(Comparator.comparing(ProcessRouteDTO::getProcessNo)); processRouteDT.sort(Comparator.comparing(ProcessRouteDTO::getProcessNo));
for (List<ProcessRouteSelectDTO> jdRoutes : groupedByFNumber.values()) { for (List<ProcessRouteSelectDTO> jdRoutes : groupedByFNumber.values()) {
@ -1336,12 +1324,10 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
// 调用接口 // 调用接口
String resultJson = String.valueOf(client.billQuery(jsonData)); String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
// 使用 ObjectMapper JsonArray 转换为 List<PlannedProcessVo> // 使用 ObjectMapper JsonArray 转换为 List<PlannedProcessVo>
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
List<PlannedProcessVo> plannedProcessList = objectMapper.readValue(jsonArray.toString(), List<PlannedProcessVo> plannedProcessList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<PlannedProcessVo>>() { new TypeReference<List<PlannedProcessVo>>() {
}); });
// 检查 plannedProcessList 是否为 null避免空指针异常 // 检查 plannedProcessList 是否为 null避免空指针异常
@ -1714,8 +1700,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
* 查询材料bom * 查询材料bom
*/ */
@Override @Override
public List<MaterialBom> getProcessMaterialList(String materialCode, String materialName, public List<MaterialBom> getProcessMaterialList(String materialCode, String materialName, String productionOrderNo) {
String productionOrderNo) {
if (materialCode == null) { if (materialCode == null) {
logger.error("做工艺的物料不存在"); logger.error("做工艺的物料不存在");
throw new IllegalArgumentException("做工艺的物料不能为空"); throw new IllegalArgumentException("做工艺的物料不能为空");
@ -2113,10 +2098,64 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
return null; return null;
} }
} }
public List<ProcessRouteSelectDTO> getSelectStandProcessRoute(String materialCode) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "ENG_Route");
json.addProperty("FieldKeys",
"FNumber,FMATERIALID.FNumber,FMATERIALNAME,FOperNumber,FProcessProperty,FWorkCenterId.FName,FOperDescription,FOptCtrlCodeId.FName,FActivity1Qty");
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMATERIALID.FNumber");
filterObject.addProperty("Compare", "67");
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
JsonObject filterObject1 = new JsonObject();
filterObject1.addProperty("FieldName", "FRouteGroupId.FName");
filterObject1.addProperty("Compare", "17");
filterObject1.addProperty("Value", "固定工艺");
filterObject1.addProperty("Left", "");
filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);
filterString.add(filterObject1);
JsonObject filterObject2 = new JsonObject();
filterObject2.addProperty("FieldName", "FForbidStatus");
filterObject2.addProperty("Compare", "105");
filterObject2.addProperty("Value", "A");
filterObject2.addProperty("Left", "");
filterObject2.addProperty("Right", "");
filterObject2.addProperty("Logic", 0);
filterString.add(filterObject2);
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
json.addProperty("StartRow", 0);
json.addProperty("Limit", 2000);
json.addProperty("SubSystemId", "");
String jsonData = json.toString();
String resultJson;
try {
// 调用API接口
resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
// 将JsonArray转为PlanOrder列表
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(jsonArray.toString(), new TypeReference<List<ProcessRouteSelectDTO>>() {
});
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/** /**
* 根据项目令号删除 材料bom 总装bom 工艺路线 * 根据项目令号删除 材料bom 总装bom 工艺路线
*
* @param productionOrderNo * @param productionOrderNo
* @return * @return
*/ */

View File

@ -23,10 +23,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Collection; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* 安全库存Service业务层处理 * 安全库存Service业务层处理
@ -89,6 +86,9 @@ public class SafetyStockServiceImpl implements ISafetyStockService {
lqw.like(StringUtils.isNotBlank(bo.getMaterialName()), SafetyStock::getMaterialName, bo.getMaterialName()); lqw.like(StringUtils.isNotBlank(bo.getMaterialName()), SafetyStock::getMaterialName, bo.getMaterialName());
lqw.eq(bo.getMinSafetyStock() != null, SafetyStock::getMinSafetyStock, bo.getMinSafetyStock()); lqw.eq(bo.getMinSafetyStock() != null, SafetyStock::getMinSafetyStock, bo.getMinSafetyStock());
lqw.eq(bo.getMaxSafetyStock() != null, SafetyStock::getMaxSafetyStock, bo.getMaxSafetyStock()); lqw.eq(bo.getMaxSafetyStock() != null, SafetyStock::getMaxSafetyStock, bo.getMaxSafetyStock());
lqw.eq(bo.getWlMaterial() != null, SafetyStock::getWlMaterial, bo.getWlMaterial());
lqw.eq(StringUtils.isNotBlank(bo.getType()), SafetyStock::getType, bo.getType());
lqw.eq(StringUtils.isNotBlank(bo.getWlMaterial()), SafetyStock::getWlMaterial, bo.getWlMaterial());
return lqw; return lqw;
} }
@ -133,6 +133,21 @@ public class SafetyStockServiceImpl implements ISafetyStockService {
} }
return baseMapper.deleteBatchIds(ids) > 0; return baseMapper.deleteBatchIds(ids) > 0;
} }
/**
* @param type1
* @return
*/
@Override
public List<SafetyStock> selectByType(String type1) {
if (type1 != null) {
LambdaQueryWrapper<SafetyStock> lqw = Wrappers.lambdaQuery();
lqw.eq(SafetyStock::getType, type1);
return baseMapper.selectList(lqw);
}
return Collections.emptyList();
}
/** /**
* 物料批量查询 * 物料批量查询
*/ */

View File

@ -17,14 +17,14 @@ import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SafetyStock; import com.ruoyi.system.domain.SafetyStock;
import com.ruoyi.system.domain.WlStockData; import com.ruoyi.system.domain.WlStockData;
import com.ruoyi.system.domain.bo.WlStockDataBo; import com.ruoyi.system.domain.bo.WlStockDataBo;
import com.ruoyi.system.domain.dto.InvReserveAnalyzeRptDTO; import com.ruoyi.system.domain.dto.*;
import com.ruoyi.system.domain.dto.ProMoDTO;
import com.ruoyi.system.domain.dto.PurchaseOrderDTO;
import com.ruoyi.system.domain.vo.WlStockDataVo; import com.ruoyi.system.domain.vo.WlStockDataVo;
import com.ruoyi.system.mapper.SafetyStockMapper; import com.ruoyi.system.mapper.SafetyStockMapper;
import com.ruoyi.system.mapper.WlStockDataMapper; import com.ruoyi.system.mapper.WlStockDataMapper;
import com.ruoyi.system.runner.JdUtil; import com.ruoyi.system.runner.JdUtil;
import com.ruoyi.system.service.ISafetyStockService;
import com.ruoyi.system.service.IWlStockDataService; import com.ruoyi.system.service.IWlStockDataService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -50,6 +50,7 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
private static final Logger logger = LoggerFactory.getLogger(WlStockDataServiceImpl.class); private static final Logger logger = LoggerFactory.getLogger(WlStockDataServiceImpl.class);
private final WlStockDataMapper baseMapper; private final WlStockDataMapper baseMapper;
private final SafetyStockMapper safetyStockMapper; private final SafetyStockMapper safetyStockMapper;
private final ISafetyStockService iSafetyStockService;
private static final int MAX_RETRIES = 3; private static final int MAX_RETRIES = 3;
private static final long RETRY_DELAY = 2000L; // 2秒 private static final long RETRY_DELAY = 2000L; // 2秒
@ -93,11 +94,13 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
lqw.eq(StringUtils.isNotBlank(bo.getDocumentType()), WlStockData::getDocumentType, bo.getDocumentType()); lqw.eq(StringUtils.isNotBlank(bo.getDocumentType()), WlStockData::getDocumentType, bo.getDocumentType());
lqw.eq(bo.getAvailableStock() != null, WlStockData::getAvailableStock, bo.getAvailableStock()); lqw.eq(bo.getAvailableStock() != null, WlStockData::getAvailableStock, bo.getAvailableStock());
lqw.eq(bo.getSecAvbqty() != null, WlStockData::getSecAvbqty, bo.getSecAvbqty()); lqw.eq(bo.getSecAvbqty() != null, WlStockData::getSecAvbqty, bo.getSecAvbqty());
lqw.eq( WlStockData::getSafeStatus, bo.getSafeStatus());
lqw.eq(bo.getProductionQty() != null, WlStockData::getProductionQty, bo.getProductionQty()); lqw.eq(bo.getProductionQty() != null, WlStockData::getProductionQty, bo.getProductionQty());
lqw.eq(bo.getPurchaseQty() != null, WlStockData::getPurchaseQty, bo.getPurchaseQty()); lqw.eq(bo.getPurchaseQty() != null, WlStockData::getPurchaseQty, bo.getPurchaseQty());
lqw.eq(bo.getSecQty() != null, WlStockData::getSecQty, bo.getSecQty()); lqw.eq(bo.getSecQty() != null, WlStockData::getSecQty, bo.getSecQty());
lqw.eq(bo.getMaxsafetyStock() != null, WlStockData::getMaxsafetyStock, bo.getMaxsafetyStock()); lqw.eq(bo.getMaxsafetyStock() != null, WlStockData::getMaxsafetyStock, bo.getMaxsafetyStock());
lqw.eq(bo.getMinsafetyStock() != null, WlStockData::getMinsafetyStock, bo.getMinsafetyStock()); lqw.eq(bo.getMinsafetyStock() != null, WlStockData::getMinsafetyStock, bo.getMinsafetyStock());
lqw.eq(StringUtils.isNotBlank(bo.getWlMaterial()), WlStockData::getWlMaterial, bo.getWlMaterial());
return lqw; return lqw;
} }
@ -230,6 +233,68 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
} }
} }
public List<WlStockData> generateDoc12() {
List<SafetyStock> safetyStocks = safetyStockMapper.selectList();
if (CollectionUtils.isEmpty(safetyStocks)) {
logger.warn("没有找到安全库存数据");
logMessages("没有找到安全库存数据");
return Collections.emptyList();
}
// 使用固定大小的线程池而不是CachedThreadPool避免创建过多线程
ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
List<WlStockData> wlStockDataList = Collections.synchronizedList(new ArrayList<>());
try {
// 创建所有任务的Future列表
List<CompletableFuture<Void>> futures = safetyStocks.stream()
.map(safetyStock -> CompletableFuture
.supplyAsync(() -> processWithRetry(safetyStock), executor)
.thenAccept(wlStockData -> {
if (wlStockData != null) {
wlStockDataList.add(wlStockData);
}
})
.exceptionally(e -> {
logger.error("处理安全库存数据失败: {}", safetyStock.getMaterialCode(), e);
logMessages("处理安全库存数据失败: " + safetyStock.getMaterialCode());
return null;
}))
.collect(Collectors.toList());
// 等待所有任务完成
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.get(5, TimeUnit.MINUTES); // 设置整体超时时间
// 批量保存数据
if (!wlStockDataList.isEmpty()) {
boolean success = baseMapper.insertBatch(wlStockDataList);
logger.info("批量插入{}条数据: {}", wlStockDataList.size(), success);
logMessages("批量插入" + wlStockDataList.size() + "条数据成功");
}
return wlStockDataList;
} catch (TimeoutException e) {
logger.error("生成文档操作超时", e);
logMessages("生成单据操作超时");
throw new ServiceException("操作超时,请稍后重试");
} catch (Exception e) {
logger.error("生成文档时发生错误", e);
logMessages("生成单据发生错误: " + e.getMessage());
throw new ServiceException("生成文档失败:" + e.getMessage());
} finally {
executor.shutdown();
try {
if (!executor.awaitTermination(30, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
private WlStockData processWithRetry(SafetyStock safetyStock) { private WlStockData processWithRetry(SafetyStock safetyStock) {
int retryCount = 0; int retryCount = 0;
while (retryCount < MAX_RETRIES) { while (retryCount < MAX_RETRIES) {
@ -261,293 +326,115 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
} }
String materialCode = safetyStock.getMaterialCode(); String materialCode = safetyStock.getMaterialCode();
boolean isMainMaterial5 = "ELS-MJ.00.5".equals(materialCode);
boolean isMainMaterial9 = "ELS-MJ.00.9".equals(materialCode);
boolean isMainMaterial3WH = "ELS-MJ.00.3-WH".equals(materialCode);
boolean isMainMaterial3GY = "ELS-MJ.00.3-GY".equals(materialCode);
boolean isAssociatedMaterial5 = "ELS-MJ.00.6".equals(materialCode) ||
"ELS-MJ.00.7".equals(materialCode) ||
"ELS-MJ.00.8".equals(materialCode);
boolean isAssociatedMaterial9 = "ELS-MJ.00.10".equals(materialCode) ||
"ELS-MJ.00.12".equals(materialCode) ||
"ELS-MJ.00.13".equals(materialCode) ||
"ELS-MJ.00.14".equals(materialCode);
boolean isAssociatedMaterial3WH = "ELS-MJ.00.4-WH".equals(materialCode);
boolean isAssociatedMaterial3GY = "ELS-MJ.00.4-GY".equals(materialCode);
try { try {
// 获取库存 // 获取库存
List<InvReserveAnalyzeRptDTO> analyzeRpt = JdUtil.getInvReserveAnalyzeRpt(materialCode); double inventoryQty = Optional.ofNullable(JdUtil.getKuCun(materialCode))
double fSecAVBQty = 0.0; .map(list ->list.stream()
double fSecQty = 0.0; .mapToDouble(JDInventoryDTO::getFBaseQty)
.sum())
.orElse(0.0);
// 查询子项物料的未领料量
double fNoPickedQty = Optional.ofNullable(JdUtil.getWeiLingliao(materialCode))
.map(list ->list.stream()
.mapToDouble(JDProductionDTO::getFNoPickedQty)
.sum())
.orElse(0.0);
if (!CollectionUtils.isEmpty(analyzeRpt)) { // 获取生产订单未入库数量数量
fSecAVBQty = analyzeRpt.get(0).getFSecAVBQty();
fSecQty = analyzeRpt.stream()
.mapToDouble(dto -> dto.getFSecQty() != null ? dto.getFSecQty() : 0.0)
.sum();
}
// 获取生产订单数量
double productionQty = Optional.ofNullable(JdUtil.getProMoList(materialCode)) double productionQty = Optional.ofNullable(JdUtil.getProMoList(materialCode))
.map(list -> list.stream() .map(list -> list.stream()
.mapToDouble(ProMoDTO::getFQty) .mapToDouble(ProMoDTO::getFQty)
.sum()) .sum())
.orElse(0.0); .orElse(0.0);
// 获取采购订单数量 // 获取采购订单未入库数量
double purchaseQty = Optional.ofNullable(JdUtil.getPurchaseOrderList(materialCode)) double purchaseQty = Optional.ofNullable(JdUtil.getPurchaseOrderList(materialCode))
.map(list -> list.stream() .map(list -> list.stream()
.mapToDouble(PurchaseOrderDTO::getFQty) .mapToDouble(PurchaseOrderDTO::getFRemainStockINQty)
.sum()) .sum())
.orElse(0.0); .orElse(0.0);
// 计算预计可用库存
// 计算可用库存 double availableStock = inventoryQty + productionQty + purchaseQty - fNoPickedQty;
double availableStock = fSecAVBQty + productionQty + purchaseQty - fSecQty;
double minSafetyStock = safetyStock.getMinSafetyStock(); double minSafetyStock = safetyStock.getMinSafetyStock();
double maxSafetyStock = safetyStock.getMaxSafetyStock(); double maxSafetyStock = safetyStock.getMaxSafetyStock();
logger.debug("物料编码:{},即时库存: {},用料清单未领料数量: {} 生产订单未入库数量: {}, 采购订单未入库数量: {}, 预计可用库存: {}", materialCode,inventoryQty, fNoPickedQty,productionQty, purchaseQty, availableStock);
logger.debug("物料编码:{}, 生产订单数量: {}, 采购订单数量: {}, 可用库存: {}", materialCode, productionQty, purchaseQty, availableStock);
logMessages("物料编码:" + materialCode + ", 生产订单数量: " + productionQty + ", 采购订单数量: " + purchaseQty + ", 可用库存: " + availableStock); logMessages("物料编码:" + materialCode + ", 生产订单数量: " + productionQty + ", 采购订单数量: " + purchaseQty + ", 可用库存: " + availableStock);
// 检查主物料是否满足条件
if ((isMainMaterial5 && (fSecAVBQty <= 0 || fSecQty <= 0)) ||
(isMainMaterial9 && (fSecAVBQty <= 0 || fSecQty <= 0)) ||
(isMainMaterial3WH && (fSecAVBQty <= 0 || fSecQty <= 0)) ||
(isMainMaterial3GY && (fSecAVBQty <= 0 || fSecQty <= 0))) {
logger.warn("物料 {} 不满足条件", materialCode);
return null; // 主物料不满足条件
}
// 如果主物料不满足条件关联物料也不满足条件
if ((isAssociatedMaterial5 || isAssociatedMaterial9 || isAssociatedMaterial3WH || isAssociatedMaterial3GY)) {
return null; // 关联物料不满足条件
}
// 如果可用库存低于最小安全库存创建库存数据记录 // 如果可用库存低于最小安全库存创建库存数据记录
if (availableStock < minSafetyStock) {
return createWlStockData(safetyStock, availableStock, fSecAVBQty, productionQty, purchaseQty, fSecQty, minSafetyStock, maxSafetyStock); //预计可用库存
} return createWlStockData(safetyStock, availableStock,inventoryQty, fNoPickedQty, productionQty, purchaseQty, minSafetyStock, maxSafetyStock);
} catch (Exception e) { } catch (Exception e) {
logger.error("处理物料编码时出错: {}", materialCode, e); logger.error("处理物料编码时出错: {}", materialCode, e);
logMessages("处理物料编码时出错: " + materialCode); logMessages("处理物料编码时出错: " + materialCode);
throw e; // 抛出异常以触发重试机制 throw e; // 抛出异常以触发重试机制
}
return null;
} }
private WlStockData createWlStockData(SafetyStock safetyStock, double availableStock, double fSecAVBQty, double productionQty, double purchaseQty, double fSecQty, double minSafetyStock, double maxSafetyStock) { }
private WlStockData createWlStockData(SafetyStock safetyStock, double availableStock, double inventoryQty, double fNoPickedQty, double productionQty, double purchaseQty, double minSafetyStock, double maxSafetyStock) {
if (availableStock < minSafetyStock) {
//创建安全库存单据 //创建安全库存单据
WlStockData wlStockData = new WlStockData(); WlStockData wlStockData = new WlStockData();
wlStockData.setMaterialCode(safetyStock.getMaterialCode()); wlStockData.setMaterialCode(safetyStock.getMaterialCode());
wlStockData.setWlMaterial(safetyStock.getType());
//将相同类型的物料也要生成WlStockData ,如果有就不生成了
wlStockData.setMaterialName(safetyStock.getMaterialName()); wlStockData.setMaterialName(safetyStock.getMaterialName());
wlStockData.setDocumentType(safetyStock.getWlMaterial());
wlStockData.setRequiredStock(maxSafetyStock); wlStockData.setRequiredStock(maxSafetyStock);
//预计可用量
wlStockData.setCurrentStock(availableStock); wlStockData.setCurrentStock(availableStock);
wlStockData.setTriggerTime(new Date()); wlStockData.setTriggerTime(new Date());
wlStockData.setAvailableStock(BigDecimal.valueOf(availableStock)); //用料清单未领料数量
wlStockData.setAvailableStock(BigDecimal.valueOf(fNoPickedQty));
//生产订单未入库数量
wlStockData.setProductionQty(BigDecimal.valueOf(productionQty)); wlStockData.setProductionQty(BigDecimal.valueOf(productionQty));
//采购订单未入库数量
wlStockData.setPurchaseQty(BigDecimal.valueOf(purchaseQty)); wlStockData.setPurchaseQty(BigDecimal.valueOf(purchaseQty));
wlStockData.setSecQty(BigDecimal.valueOf(fSecQty));
// wlStockData.setSecQty(BigDecimal.valueOf(purchaseQty));
wlStockData.setMinsafetyStock(BigDecimal.valueOf(minSafetyStock)); wlStockData.setMinsafetyStock(BigDecimal.valueOf(minSafetyStock));
wlStockData.setMaxsafetyStock(BigDecimal.valueOf(maxSafetyStock)); wlStockData.setMaxsafetyStock(BigDecimal.valueOf(maxSafetyStock));
wlStockData.setSecAvbqty(BigDecimal.valueOf(fSecAVBQty)); //即时库存
wlStockData.setSecAvbqty(BigDecimal.valueOf(inventoryQty));
wlStockData.setDocumentType(String.format("物料编码:%s||可用库存:%.2f||库存量:%.2f||生产订单:%.2f||" + wlStockData.setSafeStatus(1);
"采购订单:%.2f||预留量:%.2f||最大库存:%.2f||最低库存:%.2f", return wlStockData;
safetyStock.getMaterialCode(), availableStock, fSecAVBQty, productionQty, }else {
purchaseQty, fSecQty, maxSafetyStock, minSafetyStock)); //创建安全库存单据
WlStockData wlStockData = new WlStockData();
wlStockData.setMaterialCode(safetyStock.getMaterialCode());
wlStockData.setWlMaterial(safetyStock.getType());
//将相同类型的物料也要生成WlStockData ,如果有就不生成了
wlStockData.setMaterialName(safetyStock.getMaterialName());
wlStockData.setDocumentType(safetyStock.getWlMaterial());
wlStockData.setRequiredStock(maxSafetyStock);
//预计可用量
wlStockData.setCurrentStock(availableStock);
wlStockData.setTriggerTime(new Date());
//用料清单未领料数量
wlStockData.setAvailableStock(BigDecimal.valueOf(fNoPickedQty));
//生产订单未入库数量
wlStockData.setProductionQty(BigDecimal.valueOf(productionQty));
//采购订单未入库数量
wlStockData.setPurchaseQty(BigDecimal.valueOf(purchaseQty));
// wlStockData.setSecQty(BigDecimal.valueOf(purchaseQty));
wlStockData.setMinsafetyStock(BigDecimal.valueOf(minSafetyStock));
wlStockData.setMaxsafetyStock(BigDecimal.valueOf(maxSafetyStock));
//即时库存
wlStockData.setSecAvbqty(BigDecimal.valueOf(inventoryQty));
wlStockData.setSafeStatus(0);
return wlStockData; return wlStockData;
} }
public List<InvReserveAnalyzeRptDTO> getInvReserveAnalyzeRpt(String materialCode) {
List<InvReserveAnalyzeRptDTO> rptDTOS = new ArrayList<>();
K3CloudApi client = new K3CloudApi();
JsonObject jsonData = new JsonObject();
jsonData.addProperty("FieldKeys", "FMATERIALNUMBER,FMaterialName,FDemandTypeName,FSecQty,FSecAVBQty");
jsonData.addProperty("SchemeId", "");
jsonData.addProperty("StartRow", 0);
jsonData.addProperty("Limit", 2000);
jsonData.addProperty("IsVerifyBaseDataField", "true");
JsonArray filterArray = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("Left", "");
filterObject.addProperty("FieldName", "FMATERIALNUMBER");
filterObject.addProperty("Compare", "67");
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterArray.add(filterObject);
jsonData.add("FilterString", filterArray);
JsonObject model = new JsonObject();
model.addProperty("FStockOrgId", "1");
JsonObject beginMaterialId = new JsonObject();
beginMaterialId.addProperty("FNUMBER", materialCode);
model.add("FBeginMaterialId", beginMaterialId);
model.addProperty("FDemandType", "PLN_FORECAST,PLN_PLANORDER,PRD_PPBOM,SAL_SaleOrder");
model.addProperty("FNeedTransOnly", false);
jsonData.add("Model", model);
String jsonString = jsonData.toString();
String formId = "PLN_InvReserveAnalyzeRpt";
String resultJson = null;
try {
resultJson = client.getSysReportData(formId, jsonString);
} catch (Exception e) {
System.err.println("Error fetching data for materialCode: " + materialCode);
logMessages("Error fetching data for materialCode: " + materialCode);
e.printStackTrace();
return new ArrayList<>();
} }
if (resultJson == null) {
System.err.println("No data returned for materialCode: " + materialCode);
logMessages("No data returned for materialCode: " + materialCode);
return new ArrayList<>();
}
JsonObject resultObject = new Gson().fromJson(resultJson, JsonObject.class);
JsonArray rows = resultObject.getAsJsonObject("Result").getAsJsonArray("Rows");
if (rows == null) {
System.err.println("No data returned for materialCode: " + materialCode);
logMessages("No data returned for materialCode: " + materialCode);
return new ArrayList<>();
}
System.out.println("库存预留单===========>" + rows);
logMessages("库存预留单===========>" + rows);
for (JsonElement rowElement : rows) {
JsonArray row = rowElement.getAsJsonArray();
InvReserveAnalyzeRptDTO analyzeRptDTO = new InvReserveAnalyzeRptDTO();
analyzeRptDTO.setFMATERIALNUMBER(getStringFromJsonArray(row, 0));
analyzeRptDTO.setFMaterialName(getStringFromJsonArray(row, 1));
analyzeRptDTO.setFDemandTypeName(getStringFromJsonArray(row, 2));
analyzeRptDTO.setFSecQty(getDoubleFromJsonArray(row, 3));
analyzeRptDTO.setFSecAVBQty(getDoubleFromJsonArray(row, 4));
rptDTOS.add(analyzeRptDTO);
}
return rptDTOS;
}
private static String getStringFromJsonArray(JsonArray array, int index) {
return array.size() > index && !array.get(index).isJsonNull() ? array.get(index).getAsString() : "";
}
private static double getDoubleFromJsonArray(JsonArray array, int index) {
if (array.size() > index && !array.get(index).isJsonNull()) {
String value = array.get(index).getAsString();
if (!value.isEmpty()) {
try {
return Double.parseDouble(value);
} catch (NumberFormatException e) {
System.err.println("NumberFormatException for value: " + value);
}
}
}
return 0.0;
}
/**
* 物料批量查询
*/
public static JsonArray selectKuCun1(List<SafetyStock> safetyStocks) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "STK_Inventory");
json.addProperty("FieldKeys", "FMaterialId.FNumber,FMaterialName,FStockName,FStockUnitId.FName,FBaseQty");
JsonArray filterString = new JsonArray();
// 添加额外的过滤条件排除售后库
JsonObject excludeStockFilter = new JsonObject();
excludeStockFilter.addProperty("FieldName", "FStockId.FNumber"); // 设置字段名称为仓库编号
excludeStockFilter.addProperty("Compare", "!="); // 设置比较方式为"不等于"
excludeStockFilter.addProperty("Value", "CK012"); // 设置需要排除的仓库编号
excludeStockFilter.addProperty("Left", ""); // 保留字段不使用
excludeStockFilter.addProperty("Right", ""); // 保留字段不使用
excludeStockFilter.addProperty("Logic", 0); // 设置逻辑关系为 OR (假设 0 代表 OR)
filterString.add(excludeStockFilter); // 将排除条件添加到过滤条件数组中
JsonObject excludeStockFilter1 = new JsonObject();
excludeStockFilter1.addProperty("FieldName", "FStockId.FNumber"); // 设置字段名称为仓库编号
excludeStockFilter1.addProperty("Compare", "!="); // 设置比较方式为"不等于"
excludeStockFilter1.addProperty("Value", "CK018"); // 设置需要排除的仓库编号
excludeStockFilter1.addProperty("Left", ""); // 保留字段不使用
excludeStockFilter1.addProperty("Right", ""); // 保留字段不使用
excludeStockFilter1.addProperty("Logic", 0); // 设置逻辑关系为 OR (假设 0 代表 OR)
filterString.add(excludeStockFilter1);
for (int i = 0; i < safetyStocks.size(); i++) {
SafetyStock safetyStock = safetyStocks.get(i);
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMaterialId.FNumber");
filterObject.addProperty("Compare", "=");
filterObject.addProperty("Value", safetyStock.getMaterialCode());
// 为第一个和最后一个元素设置括号
if (i == 0) {
filterObject.addProperty("Left", "("); // 第一个物料左括号
} else {
filterObject.addProperty("Left", ""); // 其他物料不设置左括号
}
if (i == safetyStocks.size() - 1) {
filterObject.addProperty("Right", ")"); // 最后一个物料右括号
} else {
filterObject.addProperty("Right", ""); // 其他物料不设置右括号
}
filterObject.addProperty("Logic", 1);
filterString.add(filterObject);
}
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
json.addProperty("StartRow", 0);
json.addProperty("Limit", 2000);
json.addProperty("SubSystemId", "");
String jsonData = json.toString();
JsonArray jsonArray;
try {
// 调用接口
String resultJson = String.valueOf(client.billQuery(jsonData));
jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
logger.info("查询库存信息:{}", jsonArray);
} catch (Exception e) {
return null;
}
// 聚合库存数据
Map<String, Double> materialStockMap = new HashMap<>();
for (int i = 0; i < jsonArray.size(); i++) {
JsonObject stockData = jsonArray.get(i).getAsJsonObject();
String materialCode = stockData.has("FMaterialId.FNumber")
? stockData.get("FMaterialId.FNumber").getAsString()
: "";
double baseQty = stockData.has("FBaseQty") ? stockData.get("FBaseQty").getAsDouble() : 0;
// 聚合相同物料的库存数量
materialStockMap.put(materialCode, materialStockMap.getOrDefault(materialCode, 0.0) + baseQty);
}
// 构建返回的 JsonArray
JsonArray resultJsonArray = new JsonArray();
for (Map.Entry<String, Double> entry : materialStockMap.entrySet()) {
JsonObject aggregatedData = new JsonObject();
aggregatedData.addProperty("FMaterialId.FNumber", entry.getKey());
aggregatedData.addProperty("FBaseQty", entry.getValue()); // 物料总库存
resultJsonArray.add(aggregatedData);
}
return resultJsonArray;
}
} }

View File

@ -1,11 +1,17 @@
package com.ruoyi.system.service.impl; package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.JsonObject;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.ProductionPlan; import com.ruoyi.system.domain.ProductionPlan;
@ -22,6 +28,7 @@ import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
@ -130,6 +137,99 @@ public class WorkProcedureServiceImpl implements IWorkProcedureService {
return tasks; return tasks;
} }
public List<ProductctionPlanGatteDto> getAllTasks1() {
try {
K3CloudApi client = new K3CloudApi();
JsonObject parameter = new JsonObject();
parameter.addProperty("FWorkCenterName", "机一工段");
Object[] parameters = new Object[] { parameter.toString() };
String execute = client.execute(
"Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi",
parameters);
// 解析响应
JSONObject response = JSONObject.parseObject(execute);
if (!"true".equals(response.getString("IsSuccess"))) {
String errorMsg = response.getString("Message");
return null;
}
// 获取明天的日期字符串 (格式: yyyy-MM-dd)
String tomorrow = DateUtil.format(DateUtil.tomorrow().toLocalDateTime().plusDays(1), "yyyy-MM-dd");
// 获取数据数组
JSONArray dataArray = response.getJSONArray("data");
if (dataArray == null || dataArray.isEmpty()) {
return null;
}
List<ProductctionPlanGatteDto> tasks = new ArrayList<>();
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
for (int i = 0; i < dataArray.size(); i++) {
JSONArray queryList = dataArray.getJSONObject(i).getJSONArray("QueryList");
for (int j = 0; j < queryList.size(); j++) {
JSONObject item = queryList.getJSONObject(j);
// 获取计划结束时间并转换为日期格式进行比较
String planFinishTime = item.getString("FOperPlanFinishTime2");
if (org.springframework.util.StringUtils.hasText(planFinishTime)) {
// 提取日期部分进行比较 (去掉时间部分)
String finishDate = planFinishTime.split(" ")[0];
// 只处理明天结束的工单
if (tomorrow.equals(finishDate)) {
// 转换为 ProductctionPlanGatteDto 对象
ProductctionPlanGatteDto task = new ProductctionPlanGatteDto();
task.setId(item.getLong("Id")); // 假设有 Id 字段
task.setText(item.getString("MoOrderNo"));
task.setToolTipsTxt(item.getString("FProcessName"));
task.setType(1);
LocalDate startDate = item.getDate("FOperPlanStartTime2").toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate endDate = item.getDate("FOperPlanFinishTime2").toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
task.setStart_date(startDate.toString());
task.setEnd_date(endDate.toString());
long duration = ChronoUnit.DAYS.between(startDate, endDate);
task.setDuration(duration);
task.setOpen(true);
task.setProgress(1L);
task.setStatus("yellow");
task.setParent(null); // 父任务没有parent
tasks.add(task);
// 处理子任务
JSONArray subTasksArray = item.getJSONArray("SubTasks");
if (subTasksArray != null) {
for (int k = 0; k < subTasksArray.size(); k++) {
JSONObject subTaskItem = subTasksArray.getJSONObject(k);
ProductctionPlanGatteDto subTask = new ProductctionPlanGatteDto();
subTask.setId(subTaskItem.getLong("SubTaskId"));
subTask.setText(subTaskItem.getString("FProcessName"));
subTask.setToolTipsTxt(subTaskItem.getString("SubTaskProcessName"));
subTask.setStart_date(subTaskItem.getString("FOperPlanStartTime2"));
subTask.setEnd_date(subTaskItem.getString("FOperPlanFinishTime2"));
subTask.setDuration(subTaskItem.getLong("1"));
subTask.setOpen(true);
subTask.setProgress(1L);
subTask.setStatus("yellow");
subTask.setParent(task.getId()); // 设置父任务ID
tasks.add(subTask);
}
}
}
}
}
}
return tasks;
} catch (Exception e) {
return null;
}
}
/** /**
* 查询工序任务 * 查询工序任务

View File

@ -24,7 +24,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="fName" column="f_name"/> <result property="fName" column="f_name"/>
<result property="stats" column="stats"/> <result property="stats" column="stats"/>
<result property="wareHouse" column="ware_house"/> <result property="wareHouse" column="ware_house"/>
<result property="danzhong" column="danzhong"/> <result property="danZhong" column="dan_zhong"/>
<result property="singleWeghit" column="single_weghit"/>
</resultMap> </resultMap>

View File

@ -24,6 +24,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="maxsafetyStock" column="maxsafety_stock"/> <result property="maxsafetyStock" column="maxsafety_stock"/>
<result property="minsafetyStock" column="minsafety_stock"/> <result property="minsafetyStock" column="minsafety_stock"/>
<result property="doucCode" column="douc_code"/> <result property="doucCode" column="douc_code"/>
<result property="wlMaterial" column="wl_material"/>
<result property="safeStatus" column="safe_status"/>
</resultMap> </resultMap>