feat(system): 新增物料BOM相关功能

- 新增物料BOM校验逻辑
- 添加货主信息更新功能
- 实现安全库存更新
- 优化物料导入导出功能
- 新增双单位支持
This commit is contained in:
tzy 2025-03-07 17:42:50 +08:00
parent 969d31d9b7
commit c57f04959c
32 changed files with 1391 additions and 375 deletions

View File

@ -116,6 +116,62 @@ public class ExcelUtil {
throw new RuntimeException("导出Excel异常");
}
}
/**
* 导出excel
*
* @param list 导出数据集合
* @param sheetName 工作表的名称
* @param clazz 实体类
* @param response 响应体
*/
public static <T> void exportExceluseRoute(List<T> list, String sheetName, Class<T> clazz, HttpServletResponse response) {
try {
resetResponse(sheetName, response);
ServletOutputStream os = response.getOutputStream();
// 使用 EasyExcel Apache POI 自定义导出
ExcelWriter excelWriter = EasyExcel.write(os, clazz).build();
WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
// 在这里自定义标题和数据映射
excelWriter.write(list, writeSheet);
excelWriter.finish();
} catch (IOException e) {
throw new RuntimeException("导出Excel异常");
}
}
/**
* 导出excel
*
* @param list1 导出数据集合1
* @param sheetName1 工作表的名称1
* @param clazz1 实体类1
* @param list2 导出数据集合2
* @param sheetName2 工作表的名称2
* @param clazz2 实体类2
* @param response 响应体
*/
public static <T1, T2> void exportExcelWithMultipleSheets(List<T1> list1, String sheetName1, Class<T1> clazz1,
List<T2> list2, String sheetName2, Class<T2> clazz2,
HttpServletResponse response) {
try {
resetResponse(sheetName1, response);
ServletOutputStream os = response.getOutputStream();
// 使用 EasyExcel Apache POI 自定义导出
ExcelWriter excelWriter = EasyExcel.write(os, clazz1).build();
// 写入第一个 sheet
WriteSheet writeSheet1 = EasyExcel.writerSheet(sheetName1).build();
excelWriter.write(list1, writeSheet1);
// 写入第二个 sheet
WriteSheet writeSheet2 = EasyExcel.writerSheet(sheetName2).build();
excelWriter.write(list2, writeSheet2);
excelWriter.finish();
} catch (IOException e) {
throw new RuntimeException("导出Excel异常");
}
}
/**
* 导出excel

View File

@ -23,10 +23,12 @@ import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.BomDetails;
import com.ruoyi.system.domain.MaterialProperties;
import com.ruoyi.system.domain.bo.BomDetailsBo;
import com.ruoyi.system.domain.dto.JDBom;
import com.ruoyi.system.domain.vo.BomDetailsVo;
import com.ruoyi.system.runner.JdUtil;
import com.ruoyi.system.service.IBomDetailsService;
import com.ruoyi.system.service.IMaterialPropertiesService;
import com.ruoyi.system.service.IMaterialTotalService;
import com.ruoyi.system.service.IProcessRouteService;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.Cell;
@ -66,6 +68,8 @@ public class BomDetailsController extends BaseController {
private final IMaterialPropertiesService iMaterialPropertiesService;
private final IProcessRouteService iProcessRouteService;
private final IMaterialTotalService iMaterialTotalService;
private static final Logger log = LoggerFactory.getLogger(BomDetailsController.class);
/**
@ -422,6 +426,9 @@ public class BomDetailsController extends BaseController {
log.error("物料信息不完整,无法新增物料");
}
}
//保存物料之前进行BOM校验
List<JDBom> selectBomList = JdUtil.getSelectBomList(fnumber);
// 物料清单保存方法
FBloadBillOfMaterialsPreservation(bomDetails);
bomDetailsList.addAll(bomDetails);
@ -430,44 +437,8 @@ public class BomDetailsController extends BaseController {
return R.ok("成功", bomDetailsList);
}
/**
* 检查金蝶中是否存在该物料的BOM
*//*
*
*
* private JsonArray checkBomExists(String fnumber) {
* try {
* K3CloudApi client = new K3CloudApi();
* String formId = "ENG_BOM";
*
* JsonObject queryParam = new JsonObject();
* queryParam.addProperty("FormId", formId);
* queryParam.addProperty("FieldKeys",
* "FID,FMATERIALID.FNumber,FTreeEntity.FMATERIALIDCHILD.FNumber,FTreeEntity.FNUMERATOR"
* );
*
* JsonArray filterArray = new JsonArray();
* JsonObject filter = new JsonObject();
* filter.addProperty("Field", "FMATERIALID.FNumber");
* filter.addProperty("Value", fnumber);
* filterArray.add(filter);
* queryParam.add("FilterString", filterArray);
*
* String resultJson = client.executeBillQuery(queryParam.toString());
* Gson gson = new Gson();
* JsonArray result = gson.fromJson(resultJson, JsonArray.class);
*
* return result;
* } catch (Exception e) {
* log.error("查询BOM失败:", e);
* return null;
* }
* }
*
*/
/*
* s
* 物料清单保存方法
*/
public int loadBillOfMaterialsPreservation(List<BomDetails> bomlist) {
@ -648,7 +619,7 @@ public class BomDetailsController extends BaseController {
// 创建FTreeEntity数组并加入Model
JsonArray fTreeEntity = new JsonArray();
model.add("FTreeEntity", fTreeEntity);
ArrayList<JsonObject> fTreeEntityList = new ArrayList<>();
List<JsonObject> fTreeEntityList = new ArrayList<>();
for (BomDetails details : bomlist) {
if (bomlist.isEmpty()) {
return;
@ -699,11 +670,21 @@ public class BomDetailsController extends BaseController {
fTreeEntityItem.addProperty("FDOSAGETYPE", "2");
fTreeEntityItem.addProperty("FNUMERATOR", details.getQuantity());
fTreeEntityItem.addProperty("FDENOMINATOR", details.getDenominator());
//添加货主信息 查看这个bom中是否符合货主信息
String materialCode = details.getPartNumber();
Boolean vmiByCode = iMaterialTotalService.getVMIByCode(materialCode);
if (vmiByCode){
fTreeEntityItem.addProperty("FOWNERTYPEID", "BD_Supplier");
JsonObject FOWNERID = new JsonObject();
fTreeEntityItem.add("FOWNERID", FOWNERID);
FOWNERID.addProperty("FNumber", "GYS_070");
}
fTreeEntityList.add(fTreeEntityItem);
}
String jsonData = json.toString();
log.debug("打印json:" + jsonData);
System.out.println(jsonData);
try {
// 业务对象标识
String formId = "ENG_BOM";
@ -718,7 +699,6 @@ public class BomDetailsController extends BaseController {
System.out.printf("接口返回结果: %s%n", gson.toJson(repoRet.getResult()));
log.debug("物料清单bom 保存成功===================>" + "图号:" + bomDetails1.getFNumber());
} else {
log.error("接口返回结果: " + gson.toJson(repoRet.getResult().getResponseStatus()));
log.error("物料清单bom 保存失败===================>" + "图号:" + bomDetails1.getFNumber());
}
} catch (Exception e) {
@ -1338,6 +1318,9 @@ public class BomDetailsController extends BaseController {
// 添加Model字段
model.addProperty("FMATERIALID", 0);
if(!(bomDetails1.getDanzhong() ==null)){
model.addProperty("F_HBYT_DZ", bomDetails1.getDanzhong());
}
model.addProperty("FSpecification", bomDetails1.getRemarks());
model.addProperty("FNumber", bomDetails1.getPartNumber());
model.addProperty("FName", bomDetails1.getName());

View File

@ -9,13 +9,12 @@ import java.util.concurrent.TimeUnit;
import com.alibaba.fastjson.JSONObject;
import com.kingdee.bos.webapi.entity.SuccessEntity;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.excel.ExcelResult;
import com.ruoyi.common.utils.JdUtils;
import com.ruoyi.system.domain.EleMaterials;
import com.ruoyi.system.domain.dto.JdEntry;
import com.ruoyi.system.domain.dto.JdEntryVmi;
import com.ruoyi.system.domain.dto.JdVMIVo;
import com.ruoyi.system.domain.dto.JinYongDTO;
import com.ruoyi.system.domain.dto.*;
import com.ruoyi.system.domain.vo.ExcelVo;
import com.ruoyi.system.runner.JdUtil;
import lombok.RequiredArgsConstructor;
@ -30,8 +29,6 @@ import org.springframework.validation.annotation.Validated;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.enums.BusinessType;
@ -179,7 +176,7 @@ public class EleMaterialsController extends BaseController {
}
@Log(title = "禁用物料", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:importDataTime")
@SaCheckPermission("system:materials:importDataTime")
@PostMapping(value = "/importMA", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importMA(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
@ -196,7 +193,7 @@ public class EleMaterialsController extends BaseController {
return R.ok("更新成功");
}
@Log(title = "禁用子项中包含的物料", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:importDataTime")
@SaCheckPermission("system:materials:importDataTime")
@PostMapping(value = "/importMA1", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importMA1(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
@ -236,7 +233,7 @@ public class EleMaterialsController extends BaseController {
}
@Log(title = "更新工时", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:updaDateGongshi")
@SaCheckPermission("system:materials:updaDateGongshi")
@PostMapping(value = "/updaDateGongshi", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> updaDateGongshi(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
@ -275,10 +272,10 @@ public class EleMaterialsController extends BaseController {
return R.ok("更新成功");
}
@Log(title = "更新VMI仓位", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:updaDateGongshi")
@PostMapping(value = "/updaDateCangwei", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> updaDateCangwei(@RequestParam("file") MultipartFile file) throws Exception {
@Log(title = "更新货主信息", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:updateHuoZhu")
@PostMapping(value = "/updateHuoZhu", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> updateHuoZhu(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
log.info("读取文件名: " + originalFilename);
ExcelResult<JdVMIVo> result = ExcelUtil.importExcelSheet1(file.getInputStream(), JdVMIVo.class, true);
@ -289,26 +286,110 @@ public class EleMaterialsController extends BaseController {
for (JdVMIVo vmi : list) {
executor.submit(() -> {
List<JdEntryVmi> entryID = JdUtil.getEntryID2(vmi.getMaterialCode());
for (JdEntryVmi jdEntryVmi : entryID) {
int fmaterialid = jdEntryVmi.getFMATERIALID();
int fEntryId1 = jdEntryVmi.getFEntryId1();
int fEntryId3 = jdEntryVmi.getFEntryId3();
List<JdHuoZhu> entryID = JdUtil.getFID(vmi.getMaterialCode());
for (JdHuoZhu jdEntryVmi : entryID) {
int fmaterialid = jdEntryVmi.getFID();
int fEntryId1 = jdEntryVmi.getFTreeEntityFENTRYID();
log.info("物料"+vmi.getMaterialCode()+"的FId: " + fmaterialid);
log.info("物料"+vmi.getMaterialCode()+"fEntryId: " + fEntryId1);
try {
JdUtil.updateVMI(fmaterialid, fEntryId1, fEntryId3,vmi.getFStockId(),vmi.getFStockPlaceId());
JdUtil.updateHuozhu(fmaterialid, fEntryId1,vmi.getMaterialCode());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
});
}
// 关闭线程池
executor.shutdown();
while (!executor.isTerminated()) {
// 等待所有任务完成
}
return R.ok("更新成功");
}
@Log(title = "更新VMI仓位", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:updaDateCangwei")
@PostMapping(value = "/updaDateCangwei", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> updaDateCangwei(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
log.info("读取文件名: " + originalFilename);
ExcelResult<JdVMIVo> result = ExcelUtil.importExcelSheet1(file.getInputStream(), JdVMIVo.class, true);
List<JdVMIVo> list = result.getList();
// 创建固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数
list.forEach(vmi -> executor.submit(() -> {
log.info("===============>开始查询物料编码: " + vmi.getMaterialCode()+"的entryID");
List<JdEntryVmi> entryID = JdUtil.getEntryID2(vmi.getMaterialCode());
entryID.forEach(jdEntryVmi -> {
int fmaterialid = jdEntryVmi.getFMATERIALID();
int fEntryId1 = jdEntryVmi.getFEntryId1();
int fEntryId3 = jdEntryVmi.getFEntryId3();
try {
log.info("=====================>开始更新 " + vmi.getMaterialCode() + " 的VMI仓位");
JdUtil.updateVMI(fmaterialid, fEntryId1, fEntryId3, vmi.getFStockId(), vmi.getFStockPlaceId());
} 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("更新成功");
}
@Log(title = "更新安全库存", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:updaDateKuCun")
@PostMapping(value = "/updaDateKuCun", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> updaDateKuCun(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
log.info("读取文件名: " + originalFilename);
ExcelResult<JDSafeStockDTO> result = ExcelUtil.importExcelSheet1(file.getInputStream(), JDSafeStockDTO.class, true);
List<JDSafeStockDTO> list = result.getList();
// 创建固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数
list.forEach(vmi -> executor.submit(() -> {
log.info("===============>开始查询物料编码: " + vmi.getMaterialCode()+"的entryID");
List<SubHeadEntityDTO> entryID = JdUtil.getSubHeadEntity1Id(vmi.getMaterialCode());
entryID.forEach(jdEntryVmi -> {
int fmaterialid = jdEntryVmi.getFMATERIALID();
int fEntryId1 = jdEntryVmi.getFEntryId1();
int fMaxStock = vmi.getFMaxStock();
int FSafeStock = vmi.getFSafeStock();
try {
log.info("=====================>开始更新 " + vmi.getMaterialCode() + " 的安全库存");
JdUtil.updateKunCun(fmaterialid, fEntryId1, fMaxStock, FSafeStock);
} 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

@ -447,39 +447,40 @@ public class KingdeeWorkCenterDataController extends BaseController {
// 获取计划结束时间并转换为日期格式进行比较
String planFinishTime = item.getString("FOperPlanFinishTime2");
if (StringUtils.hasText(planFinishTime)) {
// 提取日期部分进行比较 (去掉时间部分)
String finishDate = planFinishTime.split(" ")[0];
// 只处理明天结束的工单
if (yesterday.equals(finishDate)) {
// 计算延期条件转出数减转入数大于0
//转出
long transOutQty = item.getLong("FTransOutQty");
//转入
long transInQty = item.getLong("FTransInQty");
if (transInQty - transOutQty > 0) {
// 转换为实体对象
KingdeeWorkCenterDataBo data = new KingdeeWorkCenterDataBo();
data.setWorkCenter(workCenter);
data.setMoBillNo(item.getString("MoBillNo"));
data.setMoOrderNo(item.getString("MoOrderNo"));
data.setMaterialNumber(item.getString("FMaterialNumber"));
data.setMaterialName(item.getString("FMaterialName"));
data.setOperQty(item.getLong("FOperQty"));
data.setTransInQty(transInQty);
data.setTransOutQty(transOutQty);
data.setOperNumber(item.getString("FOperNumber"));
data.setProcessName(item.getString("FProcessName"));
data.setOperPlanStartTime(item.getString("FOperPlanStartTime2"));
data.setOperPlanFinishTime(planFinishTime);
data.setDelayDays(item.getString("FDelayDays"));
kingdeeWorkCenterDataVos.add(data);
String delayDaysStr = item.getString("FDelayDays");
Long delayDays = null;
if (delayDaysStr != null && !delayDaysStr.isEmpty()) {
try {
delayDays = Long.parseLong(delayDaysStr);
} catch (NumberFormatException e) {
log.warn("无法解析延期天数: {}", delayDaysStr);
}
}
if (delayDays != null && delayDays > 0) {
// 只处理延期天数大于0的工单
long transOutQty = item.getLong("FTransOutQty");
// 转入
long transInQty = item.getLong("FTransInQty");
// 转换为实体对象
KingdeeWorkCenterDataBo data = new KingdeeWorkCenterDataBo();
data.setWorkCenter(workCenter);
data.setMoBillNo(item.getString("MoBillNo"));
data.setMoOrderNo(item.getString("MoOrderNo"));
data.setMaterialNumber(item.getString("FMaterialNumber"));
data.setMaterialName(item.getString("FMaterialName"));
data.setOperQty(item.getLong("FOperQty"));
data.setTransInQty(transInQty);
data.setTransOutQty(transOutQty);
data.setOperNumber(item.getString("FOperNumber"));
data.setProcessName(item.getString("FProcessName"));
data.setOperPlanStartTime(item.getString("FOperPlanStartTime2"));
data.setOperPlanFinishTime(planFinishTime);
data.setDelayDays(item.getString("FDelayDays"));
kingdeeWorkCenterDataVos.add(data);
Boolean b = iKingdeeWorkCenterDataService.insertByBo(data);
if (!b) {
return R.fail("保存工段数据失败");
}
}
Boolean b = iKingdeeWorkCenterDataService.insertByBo(data);
if (!b) {
return R.fail("保存工段数据失败");
}
}
}

View File

@ -294,8 +294,8 @@ public class MaterialListForwardController extends BaseController {
materialTotal.setProductionOrderNumber(listForward.getProductionOrderNumber());
materialTotal.setMaterialCode(listForward.getMaterialCode());
materialTotal.setMaterialName(listForward.getName());
materialTotal.setQuantity(total);
materialTotal.setInventory(inventory);
materialTotal.setQuantity(String.valueOf(total));
materialTotal.setInventory(String.valueOf(inventory));
materialTotal.setDemandTime(new Date());
totalsSet.add(materialTotal);
materialCodesSet.add(materialCode);

View File

@ -1,11 +1,13 @@
package com.ruoyi.system.controller;
import java.io.*;
import java.util.List;
import java.util.Arrays;
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 lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
@ -114,4 +116,6 @@ public class ProcessOrderProController extends BaseController {
return iProcessOrderProService.deleteWithValidByIds(Arrays.asList(ids), true);
}
}

View File

@ -1,9 +1,6 @@
package com.ruoyi.system.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.controller.BaseController;
@ -17,20 +14,25 @@ import com.ruoyi.common.excel.ExcelResult;
import com.ruoyi.common.utils.HttpRequestUtil;
import com.ruoyi.common.utils.WxRobotUtil;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.MaterialBom;
import com.ruoyi.system.domain.ProcessRoute;
import com.ruoyi.system.domain.ProductionRouteTwo;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.bo.ProcessRouteBo;
import com.ruoyi.system.domain.dto.*;
import com.ruoyi.system.domain.vo.PlannedProcessVo;
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.ImMaterialMapper;
import com.ruoyi.system.mapper.MaterialBomMapper;
import com.ruoyi.system.mapper.ProcessRouteMapper;
import com.ruoyi.system.service.IProcessRouteService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
@ -56,13 +58,20 @@ import java.util.*;
@RestController
@RequestMapping("/system/route")
public class ProcessRouteController extends BaseController {
private final ProcessRouteMapper baseMapper;
@Autowired
BomDetailsMapper bomDetailsMapper;
private final IProcessRouteService iProcessRouteService;
private static final Logger log = LoggerFactory.getLogger(ProcessRouteController.class);
@Autowired
MaterialBomMapper materialBomMapper;
@Resource
private final ImMaterialMapper imMaterialMapper;
private Long generateUniqueParentId(Long originalId) {
return originalId + 1000;
}
/**
* 主动更新可用库存
*/
@ -121,6 +130,7 @@ public class ProcessRouteController extends BaseController {
return new TableDataInfo<>();
}
}
/**
* 查询工艺路线列表
*/
@ -207,6 +217,7 @@ public class ProcessRouteController extends BaseController {
child.setXuEndTime(processRouteVo.getXuEndTime());
return child;
}
/**
* 导出工艺路线列表
*/
@ -215,7 +226,9 @@ public class ProcessRouteController extends BaseController {
@PostMapping("/export")
public void export(ProcessRouteBo bo, HttpServletResponse response) {
List<ProcessRouteVo> list = iProcessRouteService.queryList(bo);
ExcelUtil.exportExcel(list, "工艺路线", ProcessRouteVo.class, response);
List<ProcessRouteVo> list2 = iProcessRouteService.queryList2(bo);
ExcelUtil.exportExceluseRoute(list, "工艺路线", ProcessRouteVo.class, response);
}
/**
@ -269,10 +282,10 @@ public class ProcessRouteController extends BaseController {
public R<Void> importData(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
log.info("读取文件名: " + originalFilename);
//读取工艺部分sheet
// 读取工艺部分sheet
ExcelResult<ProcessRouteVo> result = ExcelUtil.importExcelSheet6(file.getInputStream(), ProcessRouteVo.class,
true);
//读取总装部分sheet
// 读取总装部分sheet
ExcelResult<ProductionOrderVo> result1 = ExcelUtil.importExcelSheet1(file.getInputStream(),
ProductionOrderVo.class, true);
List<ProductionOrderVo> list = result1.getList();
@ -307,7 +320,7 @@ public class ProcessRouteController extends BaseController {
* 查询工艺表中所有的需要做工艺的物料
*
* @return
* RequestBody List<ProcessRouteVo> routeVoList
* RequestBody List<ProcessRouteVo> routeVoList
*/
public List<ProcessRoute> getProcessRouteList(@RequestParam String rooteProdet) {
List<ProcessRoute> list = iProcessRouteService.pushRawMater(rooteProdet);
@ -382,9 +395,18 @@ public class ProcessRouteController extends BaseController {
@Log(title = "更新计划时间")
@SaCheckPermission("system:route:updateProcessPlan")
@PostMapping("/updateProcessPlan")
public List<Model> updateProcessPlan(@RequestParam String rooteProdet) {
public List<Model> updateProcessPlan(@RequestParam String rooteProdet) throws Exception {
return iProcessRouteService.updateProcessPlan(rooteProdet);
}
/**
* 更新生产订单的时间
*/
@Log(title = "更新生产订单时间")
@SaCheckPermission("system:route:updateProcesTime")
@PostMapping("/updateProcesTime")
public List<Model> updateProcesTime(@RequestParam String rooteProdet) throws Exception {
return iProcessRouteService.updateProcesTime(rooteProdet);
}
/**
* 保存工艺路线
@ -409,24 +431,27 @@ public class ProcessRouteController extends BaseController {
@Log(title = "获取材料bom列表")
@SaCheckPermission("system:route:getRawBom")
@PostMapping("/getBomInfo")
public ResponseEntity<List<MaterialBom>> getProcessMaterialList(@RequestParam(value = "materialCode") String materialCode,
@RequestParam(value = "materialName") String materialName,
@RequestParam(value = "productionOrderNo") String productionOrderNo) {
public ResponseEntity<List<MaterialBom>> getProcessMaterialList(
@RequestParam(value = "materialCode") String materialCode,
@RequestParam(value = "materialName") String materialName,
@RequestParam(value = "productionOrderNo") String productionOrderNo) {
return ResponseEntity.ok(iProcessRouteService.getProcessMaterialList(materialCode, materialName, productionOrderNo));
return ResponseEntity
.ok(iProcessRouteService.getProcessMaterialList(materialCode, materialName, productionOrderNo));
}
@Log(title = "获取金蝶列表")
@SaCheckPermission("system:route:getProcessRouteList")
@GetMapping("/getProcessRouteList")
public ResponseEntity<List<ProcessRouteJdDTO> >getProcessRouteList(@RequestParam(value = "materialCode") String materialCode,
@RequestParam(value = "materialName") String materialName,
@RequestParam(value = "productionOrderNo") String productionOrderNo) {
public ResponseEntity<List<ProcessRouteJdDTO>> getProcessRouteList(
@RequestParam(value = "materialCode") String materialCode,
@RequestParam(value = "materialName") String materialName,
@RequestParam(value = "productionOrderNo") String productionOrderNo) {
return ResponseEntity.ok(iProcessRouteService.getProcessRouteList(materialCode, materialName, productionOrderNo));
return ResponseEntity
.ok(iProcessRouteService.getProcessRouteList(materialCode, materialName, productionOrderNo));
}
@Log(title = "导入时间", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:importDataTime")
@PostMapping(value = "/importDataTime", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ -442,9 +467,146 @@ public class ProcessRouteController extends BaseController {
@Log(title = "获取金蝶工艺路线")
@SaCheckPermission("system:route:getSelectProcessRoute")
@PostMapping("/getSelectProcessRoute")
public List<ProcessRouteSelectDTO> getSelectProcessRoute(@RequestParam String materilCode) {
@PostMapping("/getSelectProcessRout1e")
public List<ProcessRouteSelectDTO> getSelectProcessRoute1(@RequestParam String materilCode) {
return iProcessRouteService.getSelectProcessRoute(materilCode);
}
private void processCombinedDTO(CombinedDTO combinedDTO, List<BomDetails> bomDetailsList,
List<ProcessRoute> routeList, List<MaterialBom> materialBoms, String productionOrderNo) {
// 处理工序列表
combinedDTO.getProcesses().forEach(process -> {
ProcessRoute processRoute = createProcessRoute(process, combinedDTO, productionOrderNo);
routeList.add(processRoute);
});
// 处理物料清单
combinedDTO.getMaterialUsageDTOList().forEach(materialUsageDTO -> {
BomDetails bomDetails = createBomDetails(materialUsageDTO, combinedDTO, productionOrderNo);
bomDetailsList.add(bomDetails);
});
// 处理材料BOM
combinedDTO.getMaterialUsageDTOList().forEach(materialUsageDTO -> {
MaterialBom materialBom = creatBomMaterial(materialUsageDTO, combinedDTO, productionOrderNo);
materialBoms.add(materialBom);
});
}
@Log(title = "生成金蝶标准工艺")
@SaCheckPermission("system:route:getKindeeExcel")
@GetMapping("/getKindeeExcel")
public ResponseEntity<String> getKindeeExcel(String rooteProdet) throws IOException {
List<CombinedDTO> planRouteList = iProcessRouteService.getSelecPlanRouteList(rooteProdet);
List<BomDetails> bomDetailsList = new ArrayList<>();
List<ProcessRoute> routeList = new ArrayList<>();
List<MaterialBom> materialBoms = new ArrayList<>();
// 将数据写入excel
for (CombinedDTO combinedDTO : planRouteList) {
processCombinedDTO(combinedDTO, bomDetailsList, routeList, materialBoms, rooteProdet);
}
// 批量插入数据库
try {
bomDetailsMapper.insertBatch(bomDetailsList);
baseMapper.insertBatch(routeList);
materialBomMapper.insertBatch(materialBoms);
return ResponseEntity.ok("保存成功");
} catch (Exception e) {
// 处理异常并返回失败信息
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("保存失败: " + e.getMessage());
}
}
private ProcessRoute createProcessRoute(PlannedProcessVo process, CombinedDTO combinedDTO,
String productionOrderNo) {
ProcessRoute processRoute = new ProcessRoute();
// 设置路线描述为生产订单号
processRoute.setRouteDescription(productionOrderNo);
// 设置工序号
processRoute.setProcessNo(process.getFOperNumber());
// 设置工序名称
processRoute.setProcessName(process.getFProcessName());
String materialCode = combinedDTO.getMaterialCode();
try {
List<ProcessRoute> singleWeightList = iProcessRouteService.getSingleWeght(materialCode);
if (singleWeightList != null && !singleWeightList.isEmpty()) {
processRoute.setDiscWeight(singleWeightList.get(0).getDiscWeight());
}
} catch (Exception e) {
// 记录日志或采取其他措施
log.error("Error fetching single weight for material code: " + materialCode, e);
}
// 设置物料代码
processRoute.setMaterialCode(combinedDTO.getMaterialCode());
processRoute.setMaterialName(combinedDTO.getMaterialName());
Double fOperQty = process.getFOperQty();
long l = fOperQty.longValue();
processRoute.setWorkCenter(process.getFWorkCenterName());
// 基本时长
processRoute.setActivityDuration(process.getFActivity1BaseQty());
processRoute.setProcessDescription(process.getFOperDescription());
processRoute.setProcessControl(process.getFOptCtrlCodeIFName());
processRoute.setXuStartTime(process.getFSeqPlanStartTime());
processRoute.setXuEndTime(process.getFSeqPlanFinishTime());
processRoute.setActivityUnit("");
// 本批数量对应
processRoute.setBatchQuantity(process.getFMOQty());
List<MaterialUsageDTO> materialUsageDTOList = combinedDTO.getMaterialUsageDTOList();
for (MaterialUsageDTO materialUsageDTO : materialUsageDTOList) {
processRoute.setUnitQuantity(materialUsageDTO.getFNumerator());
processRoute.setRawMaterialCode(materialUsageDTO.getMaterialCode());
processRoute.setRawMaterialName(materialUsageDTO.getMaterialName());
processRoute.setBomUnit(materialUsageDTO.getUnit());
if (materialUsageDTO.getUnit().equals("")) {
processRoute.setDiscUsage(materialUsageDTO.getFDenominator());
} else {
processRoute.setDiscUsage(materialUsageDTO.getFNumerator() / materialUsageDTO.getFDenominator());
}
processRoute.setMaterial(materialUsageDTO.getChildMaterial());
}
return processRoute;
}
private BomDetails createBomDetails(MaterialUsageDTO materialUsageDTO, CombinedDTO combinedDTO,
String productionOrderNo) {
BomDetails bomDetails = new BomDetails();
bomDetails.setTotalWeight(productionOrderNo);
bomDetails.setFNumber(combinedDTO.getMaterialCode());
bomDetails.setFName(combinedDTO.getMaterialName());
bomDetails.setPartNumber(materialUsageDTO.getMaterialCode());
bomDetails.setUnitWeight("");
//子项分子
bomDetails.setQuantity(materialUsageDTO.getFNumerator());
//子项分母
bomDetails.setDenominator(materialUsageDTO.getFDenominator());
bomDetails.setName(materialUsageDTO.getMaterialName());
if (materialUsageDTO.getItemType().equals("1")){
bomDetails.setStats("外购");
}else{
bomDetails.setStats("自制");
}
bomDetails.setMaterial(materialUsageDTO.getChildMaterial());
return bomDetails;
}
private MaterialBom creatBomMaterial(MaterialUsageDTO materialUsageDTO, CombinedDTO combinedDTO,
String productionOrderNo) {
MaterialBom materialBom = new MaterialBom();
materialBom.setProjectNumber(productionOrderNo);
materialBom.setParentMaterialCode(combinedDTO.getMaterialCode());
materialBom.setParentMaterialName(combinedDTO.getMaterialName());
materialBom.setMaterialCode(materialUsageDTO.getMaterialCode());
materialBom.setMaterialName(materialUsageDTO.getMaterialName());
materialBom.setUnit(materialUsageDTO.getUnit());
materialBom.setMaterialType(materialUsageDTO.getItemType());
materialBom.setQuantity(String.valueOf(materialUsageDTO.getRequiredQty()));
return materialBom;
}
}

View File

@ -3,6 +3,7 @@ package com.ruoyi.system.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -20,52 +21,68 @@ public class BomDetails extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
*
*/
private String partNumber;
/**
* 部件图号
*/
@JsonProperty("F_HBYT_BJBM")
private String partdiagramCode;
/**
* 部件名称
*/
@JsonProperty("F_HBYT_BJMC")
private String partdiagramName;
/*父级物料编码*/
private String fNumber;
/*父级物料名称*/
private String fName;
private String wareHouse;
/**
*
* 父级物料编码
*/
@JsonProperty("FMATERIALID.FNumber")
private String fNumber;
/**
* 父级物料名称
*/
@JsonProperty("FITEMNAME")
private String fName;
/**
* 子项物料单位
*/
@JsonProperty("FUNITID.FName")
private String wareHouse;
/**
*子项物料编码
*/
@JsonProperty("FMATERIALIDCHILD.FNumber")
private String partNumber;
/**
*子项物料名称
*/
@JsonProperty("FCHILDITEMNAME")
private String name;
/**
*
*属性
*/
@JsonProperty("FCHILDITEMPROPERTY")
private String stats;
/**
* fenzi
* 子项分子
*/
@JsonProperty("FNUMERATOR")
private Double quantity;
/**
* 分母
* 子项分母
*/
@JsonProperty("FDENOMINATOR")
private Double denominator;
/**
*
*材质
*/
private String material;
/**
*
*是否存在
*/
private String unitWeight;
/**
@ -73,8 +90,11 @@ public class BomDetails extends BaseEntity {
*/
private String totalWeight;
/**
*
*备注
*/
private String remarks;
/**
* 单重
*/
private Double danzhong;
}

View File

@ -1,20 +1,18 @@
package com.ruoyi.system.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 物料汇总对象 material_total
*
* @author ruoyi
* @date 2024-06-03
* @date 2025-02-26
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ -26,7 +24,7 @@ public class MaterialTotal extends BaseEntity {
/**
*
*/
@TableId(value = "ID",type = IdType.AUTO)
@TableId(value = "id")
private Long id;
/**
* 生产令号
@ -41,13 +39,13 @@ public class MaterialTotal extends BaseEntity {
*/
private String materialName;
/**
* 数量
* 仓库编码
*/
private BigDecimal quantity;
private String quantity;
/**
* 库存
* 仓位编码
*/
private BigDecimal inventory;
private String inventory;
/**
* 需求时间
*/

View File

@ -97,7 +97,7 @@ public class ProcessRoute extends BaseEntity {
/**
* 单台数量
*/
private Long unitQuantity;
private Double unitQuantity;
/**
* 本批数量
*/

View File

@ -75,5 +75,8 @@ public class BomDetailsBo extends BaseEntity {
*/
private String remarks;
/**
* 单重
*/
private Double danzhong;
}

View File

@ -5,17 +5,16 @@ import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 物料汇总业务对象 material_total
*
* @author ruoyi
* @date 2024-06-03
* @date 2025-02-26
*/
@Data
@ -31,7 +30,6 @@ public class MaterialTotalBo extends BaseEntity {
/**
* 生产令号
*/
@NotBlank(message = "生产令号不能为空", groups = { AddGroup.class, EditGroup.class })
private String productionOrderNumber;
/**
@ -47,16 +45,16 @@ public class MaterialTotalBo extends BaseEntity {
private String materialName;
/**
* 数量
* 仓库编码
*/
@NotNull(message = "数量不能为空", groups = { AddGroup.class, EditGroup.class })
private BigDecimal quantity;
@NotBlank(message = "仓库编码不能为空", groups = { AddGroup.class, EditGroup.class })
private String quantity;
/**
* 库存
* 仓位编码
*/
@NotNull(message = "库存不能为空", groups = { AddGroup.class, EditGroup.class })
private BigDecimal inventory;
@NotBlank(message = "仓位编码不能为空", groups = { AddGroup.class, EditGroup.class })
private String inventory;
/**
* 需求时间
@ -67,7 +65,6 @@ public class MaterialTotalBo extends BaseEntity {
/**
* 备注
*/
@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
private String remarks;

View File

@ -0,0 +1,52 @@
package com.ruoyi.system.domain.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class JDBom {
@JsonProperty("FNumberbOM")
private String fNumberBom; // BOM编号
@JsonProperty("FGroup")
private String fGroup; // 分组名称
@JsonProperty("FName")
private String fName; // 物料名称
@JsonProperty("FMATERIALID")
private String fMaterialId; // 父项物料编码
@JsonProperty("FNumber")
private String fNumber; // 物料编码
@JsonProperty("FITEMNAME")
private String fItemName; // 物料名称
@JsonProperty("FUNITID")
private String fUnitId; // 物料单位
@JsonProperty("FMATERIALIDCHILD")
private String fMaterialIdChild; // 子项物料编码
@JsonProperty("FCHILDITEMNAME")
private String fChildItemName; // 子项物料名称
@JsonProperty("FCHILDITEMPROPERTY")
private String fChildItemProperty; // 子项物料属性
@JsonProperty("FCHILDUNITID.FName")
private String fChildUnitId; // 子项单位
@JsonProperty("FNUMERATOR")
private String fNumerator; // 子项用量分子
@JsonProperty("FDENOMINATOR")
private String fDenominator; // 子项用量分母
@JsonProperty("F_HBYT_BJBM")
private String fHbytBjbm; // 部件编码
@JsonProperty("F_HBYT_BJMC")
private String fHbytBjmc; // 部件名称
}

View File

@ -0,0 +1,29 @@
package com.ruoyi.system.domain.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
@Data
public class JDSafeStockDTO {
/**
* 编码
*/
@ExcelProperty(value = "物料编码")
private String materialCode;
/**
* 名称
*/
@ExcelProperty(value = "物料名称")
private String materialName;
/**
* 安全库存
*/
@ExcelProperty(value = "安全库存")
private int FSafeStock;
/**
* 最高库存
*/
@ExcelProperty(value = "最高库存")
private int FMaxStock;
}

View File

@ -0,0 +1,15 @@
package com.ruoyi.system.domain.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class JdHuoZhu {
@JsonProperty("FID")
private int FID;
@JsonProperty("FTreeEntity_FENTRYID")
private int FTreeEntityFENTRYID;
@JsonProperty("FNumber")
private int Fnumber;
}

View File

@ -29,9 +29,9 @@ public class MaterialUsageDTO {
@JsonProperty("FMEMO1")
private String remarks; // 备注
@JsonProperty("FNumerator")
private Long FNumerator; // 备注
private double FNumerator; // 分子
@JsonProperty("FDenominator")
private Long FDenominator; // 备注
private double FDenominator; // 分母
//需求日期
@JsonProperty("FNeedDate2")
private Date needDate;

View File

@ -31,4 +31,6 @@ public class PlanPrcessNumDTO {
private Date FOperPlanStartTime;
@JsonProperty("FOperPlanFinishTime")
private Date FOperPlanFinishTime;
@JsonProperty("FMONumber")
private String FMONumber;
}

View File

@ -0,0 +1,13 @@
package com.ruoyi.system.domain.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class SubHeadEntityDTO {
@JsonProperty("FMATERIALID")
private int FMATERIALID;
@JsonProperty("SubHeadEntity1_FEntryId")
private int FEntryId1;
}

View File

@ -96,6 +96,9 @@ public class BomDetailsVo {
*/
@ExcelProperty(value = "备注/仓库")
private String remarks;
/**
* 单重
*/
private Double danzhong;
}

View File

@ -1,19 +1,16 @@
package com.ruoyi.system.domain.vo;
import java.util.Date;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 物料汇总视图对象 material_total
*
* @author ruoyi
* @date 2024-06-03
* @date 2025-02-26
*/
@Data
@ExcelIgnoreUnannotated
@ -46,16 +43,16 @@ public class MaterialTotalVo {
private String materialName;
/**
* 数量
* 仓库编码
*/
@ExcelProperty(value = "数量")
private BigDecimal quantity;
@ExcelProperty(value = "仓库编码")
private String quantity;
/**
* 库存
* 仓位编码
*/
@ExcelProperty(value = "库存")
private BigDecimal inventory;
@ExcelProperty(value = "仓位编码")
private String inventory;
/**
* 需求时间

View File

@ -136,4 +136,7 @@ public class PlannedProcessVo {
*/
@JsonProperty("FDenominator")
private Long fDenominator;
@JsonProperty("FActivity1Qty")
private Long FActivity1Qty;
}

View File

@ -16,6 +16,8 @@ public class Model {
private Date FPlanStartTime;
@JsonProperty("FProcessId_number") // 添加 FProcessId_number 字段
private String FProcessId_number;
@JsonProperty("FMONumber")
private String FMONumber;
@JsonProperty("FPlanFinishTime")
private Date FPlanFinishTime;

View File

@ -9,41 +9,27 @@ import com.google.gson.JsonObject;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ruoyi.common.utils.JdUtils;
import com.ruoyi.system.controller.EleMaterialsController;
import com.ruoyi.system.domain.BomDetails;
import com.ruoyi.system.domain.MaterialProperties;
import com.ruoyi.system.domain.dto.*;
import com.ruoyi.system.domain.vo.ImMaterialVo;
import com.ruoyi.system.domain.vo.PlanOrderVo;
import com.ruoyi.system.domain.vo.PlannedProcessVo;
import com.ruoyi.system.domain.vo.ProductionRouteTwoVo;
import com.ruoyi.system.jdmain.rouplan.Model;
import com.ruoyi.system.mapper.ImProductionPlanProMapper;
import com.ruoyi.system.service.IImProductionPlanProService;
import com.ruoyi.system.service.IProcessRouteService;
import org.aspectj.bridge.MessageUtil;
import org.checkerframework.checker.units.qual.A;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.text.SimpleDateFormat;
import java.util.*;
import static com.ruoyi.common.core.domain.R.fail;
public class JdUtil {
@Resource
private ImProductionPlanProMapper imProductionPlanProMapper;
@Resource
private IImProductionPlanProService imProductionPlanProService;
private static final Logger log = LoggerFactory.getLogger(JdUtil.class);
static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 入库状态
public static JsonArray storageProduce(String number, String FMaterialIdCode) {
@ -920,6 +906,9 @@ public class JdUtil {
// 添加Model字段
model.addProperty("FMATERIALID", 0);
if(!(bomDetail.getDanzhong() ==null)){
model.addProperty("F_HBYT_DZ", bomDetail.getDanzhong());
}
model.addProperty("FNumber", bomDetail.getFNumber());
model.addProperty("FName", bomDetail.getFName());
@ -1093,7 +1082,6 @@ public class JdUtil {
log.info("查询物料是否启用VMI的接口参数: {}", jsonData);
try {
String resultJson = String.valueOf(client.billQuery(jsonData));
log.info("查询物料是否启用VMI的接口返回结果: {}", resultJson);
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
if (jsonArray != null && jsonArray.size() > 0) {
@ -1162,7 +1150,7 @@ public class JdUtil {
json.add("Model", model);
String data = json.toString();
String result = api.save("BD_Material", data);
log.info("物料保存接口参数: {}", data);
Gson gson = new Gson();
RepoRet sRet = gson.fromJson(result, RepoRet.class);
if (sRet.isSuccessfully()) {
@ -1175,5 +1163,336 @@ public class JdUtil {
return errorMessage;
}
}
//查询物料清单 行iD
public static List<JdHuoZhu> getFID(String materialCode) {
List<JdHuoZhu> jinYongDTOS = new ArrayList<>();
K3CloudApi client = new K3CloudApi();
JsonObject json = new JsonObject();
json.addProperty("FormId", "ENG_BOM");
json.addProperty("FieldKeys", "FTreeEntity_FENTRYID,FID");
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<JdHuoZhu> JinYongDTOList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<JdHuoZhu>>() {});
if (JinYongDTOList != null && !JinYongDTOList.isEmpty()) {
jinYongDTOS.addAll(JinYongDTOList);
}
} else {
log.warn("未找到与bom版本号 " + materialCode + " 相关的记录");
}
} catch (Exception e) {
log.error("调用接口时发生异常: " + e.getMessage(), e);
}
return jinYongDTOS;
}
//更新物料清单 行ID
public static String updateHuozhu(int FID, int FENTRYID,String code) throws Exception {
K3CloudApi api = new K3CloudApi(false);
JsonObject json = new JsonObject();
// 构建 NeedUpDateFields 数组
JsonArray needUpDateFields = new JsonArray();
needUpDateFields.add("FID");
needUpDateFields.add("FOWNERTYPEID");
needUpDateFields.add("FOWNERID");
needUpDateFields.add("FTreeEntity");
needUpDateFields.add("FTreeEntity_FENTRYID");
json.add("NeedUpDateFields", needUpDateFields);
// 添加 IsDeleteEntry 字段
json.addProperty("IsDeleteEntry", "false");
// 构建 Model 对象
JsonObject model = new JsonObject();
model.addProperty("FID", FID);
// 构建 FTreeEntity 数组
JsonArray fTreeEntity = new JsonArray();
JsonObject fTreeEntityItem = new JsonObject();
fTreeEntityItem.addProperty("FENTRYID", FENTRYID);
fTreeEntityItem.addProperty("FOWNERTYPEID", "BD_Supplier");
// 构建 FOWNERID 对象
JsonObject fOwnerId = new JsonObject();
fOwnerId.addProperty("FNumber", "GYS_070");
fTreeEntityItem.add("FOWNERID", fOwnerId);
fTreeEntity.add(fTreeEntityItem);
model.add("FTreeEntity", fTreeEntity);
json.add("Model", model);
String data = json.toString();
String result = api.save("ENG_BOM", data);
Gson gson = new Gson();
RepoRet sRet = gson.fromJson(result, RepoRet.class);
if (sRet.isSuccessfully()) {
String successMessage = String.format("物料清单 %s 保存成功", sRet.getResult().getResponseStatus());
log.info("物料编码"+code+"保存成功");
return successMessage;
} else {
String errorMessage = String.format("物料 %s 保存失败: %s", FENTRYID, gson.toJson(sRet.getResult()));
log.info("物料编码"+code+"保存失败"+"原因:"+gson.toJson(sRet.getResult()));
return errorMessage;
}
}
//查询物料清单 行iD
public static JdHuoZhu getFIDToProductionOrder(PlanOrderVo planOrder) {
K3CloudApi client = new K3CloudApi();
JsonObject json = new JsonObject();
json.addProperty("FormId", "PRD_MO");
json.addProperty("FieldKeys", "FTreeEntity_FENTRYID,FID");
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FBillNo");
filterObject.addProperty("Compare", "=");
filterObject.addProperty("Value", planOrder.getFBillNo());
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<JdHuoZhu> jinYongDTOList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<JdHuoZhu>>() {});
if (jinYongDTOList != null && !jinYongDTOList.isEmpty()) {
return jinYongDTOList.get(0); // 返回第一个对象
}
} else {
log.warn("未找到与次生产订单的FID " + planOrder.getFBillNo() + " 相关的记录");
}
} catch (Exception e) {
log.error("调用接口时发生异常: " + e.getMessage(), e);
}
return null; // 如果没有找到返回 null
}
//保存更新生产订单的开工时间
public static String updateOrder(JdHuoZhu jdHuoZhu, Model numDTO, Date xuStartTime, Date xuEndTime) throws Exception {
String planStartDate = dateFormat.format(xuStartTime);
String planFinishDate = dateFormat.format(xuEndTime);
K3CloudApi api = new K3CloudApi(false);
JsonObject json = new JsonObject();
// 构建 NeedUpDateFields 数组
JsonArray needUpDateFields = new JsonArray();
needUpDateFields.add("FID");
needUpDateFields.add("FPlanStartDate");
needUpDateFields.add("FTreeEntity_FENTRYID");
needUpDateFields.add("FPlanFinishDate");
json.add("NeedUpDateFields", needUpDateFields);
// 添加 IsDeleteEntry 字段
json.addProperty("IsDeleteEntry", "false");
// 构建 Model 对象
JsonObject model = new JsonObject();
model.addProperty("FID", jdHuoZhu.getFID());
// 构建 FTreeEntity 数组
JsonArray fTreeEntity = new JsonArray();
JsonObject fTreeEntityItem = new JsonObject();
fTreeEntityItem.addProperty("FPlanStartDate", planStartDate);
fTreeEntityItem.addProperty("FPlanFinishDate", planFinishDate);
fTreeEntityItem.addProperty("FENTRYID", jdHuoZhu.getFTreeEntityFENTRYID());
fTreeEntity.add(fTreeEntityItem);
model.add("FTreeEntity", fTreeEntity);
json.add("Model", model);
String data = json.toString();
String result = api.save("PRD_MO", data);
System.out.println("========================================>>>>"+data);
Gson gson = new Gson();
RepoRet sRet = gson.fromJson(result, RepoRet.class);
if (sRet.isSuccessfully()) {
String successMessage = String.format("生产订单 %s 保存成功", sRet.getResult().getResponseStatus());
log.info("物料编码"+numDTO.getFID()+"保存成功");
return successMessage;
} else {
String errorMessage = String.format("物料 %s 保存失败: %s", +numDTO.getFID(), gson.toJson(sRet.getResult()));
log.info("物料编码"+numDTO.getFID()+"保存失败"+"原因:"+gson.toJson(sRet.getResult()));
return errorMessage;
}
}
public static List<SubHeadEntityDTO> getSubHeadEntity1Id(String materialCode) {
List<SubHeadEntityDTO>subHeadEntityDTOS = new ArrayList<>();
K3CloudApi client = new K3CloudApi();
JsonObject json = new JsonObject();
json.addProperty("FormId", "BD_MATERIAL");
json.addProperty("FieldKeys", "FMATERIALID,SubHeadEntity1_FEntryId");
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "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();
log.info("查询物料是否启用VMI的接口参数: {}", jsonData);
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<SubHeadEntityDTO> JinYongDTOList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<SubHeadEntityDTO>>() {});
if (JinYongDTOList != null && !JinYongDTOList.isEmpty()) {
subHeadEntityDTOS.addAll(JinYongDTOList);
}
} else {
log.warn("未找到与bom版本号 " + materialCode + " 相关的记录");
}
} catch (Exception e) {
log.error("调用接口时发生异常: " + e.getMessage(), e);
}
return subHeadEntityDTOS;
}
public static String updateKunCun(int FMATERIALID, int fEntryId1, int FMaxStock, int FSafeStock) throws Exception {
K3CloudApi api = new K3CloudApi(false);
JsonObject json = new JsonObject();
// 创建 NeedUpDateFields 数组
JsonArray needUpDateFields = new JsonArray();
needUpDateFields.add("SubHeadEntity1");
needUpDateFields.add("FMATERIALID");
needUpDateFields.add("SubHeadEntity3");
needUpDateFields.add("FIsEnableMaxStock");
needUpDateFields.add("FIsEnableSafeStock");
needUpDateFields.add("FMaxStock");
needUpDateFields.add("FSafeStock");
json.add("NeedUpDateFields", needUpDateFields);
// 添加 IsDeleteEntry 属性
json.addProperty("IsDeleteEntry", "false");
// 创建 Model 对象
JsonObject model = new JsonObject();
model.addProperty("FMATERIALID", FMATERIALID);
// 创建 SubHeadEntity1 对象
JsonObject subHeadEntity1 = new JsonObject();
model.add("SubHeadEntity1", subHeadEntity1);
subHeadEntity1.addProperty("FEntryId", fEntryId1);
// 创建 FStockId 对象
JsonObject fStockId = new JsonObject();
subHeadEntity1.addProperty("FIsEnableMaxStock", true);
subHeadEntity1.addProperty("FIsEnableSafeStock", true);
subHeadEntity1.addProperty(" FMaxStock", FMaxStock);
subHeadEntity1.addProperty(" FSafeStock", FSafeStock);
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);
return successMessage;
} else {
String errorMessage = String.format("物料 %s 保存失败: %s", FMATERIALID, gson.toJson(sRet.getResult()));
System.out.println(errorMessage);
return errorMessage;
}
}
//获取用料清单 根据父级物料编码,作为bom校验使用
public static List<JDBom> getSelectBomList(String FMaterialCode) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "PRD_PPBOM");
json.addProperty("FieldKeys",
"FNumber,FMATERIALID.FNumber,FITEMNAME,FUNITID.FName,F_HBYT_CZ,FCHILDITEMNAME,FCHILDITEMPROPERTY,FCHILDUNITID.FName,FNUMERATOR,FDENOMINATOR,F_HBYT_BJBM,F_HBYT_BJMC");
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);
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<JDBom>>() {
});
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -45,4 +45,7 @@ public interface IMaterialTotalService {
* 校验并批量删除物料汇总信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
Boolean getVMIByCode(String code);
}

View File

@ -100,7 +100,7 @@ public interface IProcessRouteService {
* 更新计划时间
*/
List<Model> updateProcessPlan(String rooteProdet);
List<Model> updateProcessPlan(String rooteProdet) throws Exception;
/**
* 获取所有项目
*/
@ -129,4 +129,9 @@ public interface IProcessRouteService {
Double getFaWorkTime(BomDetails material);
//根据令号和物料编码 查询工艺路线
List<ProcessRoute> getProcessRoutesByOrder(String productionOrderNo, String materialCode);
List<ProcessRoute> getSingleWeght( String materialCode);
List<Model> updateProcesTime(String rooteProdet) throws Exception;
List<ProcessRouteVo> queryList2(ProcessRouteBo bo);
}

View File

@ -259,7 +259,7 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
public boolean saveData(List<EleMaterialsVo> list, HttpServletResponse response) {
Collection<EleMaterials> eleMaterialsList = new ArrayList<>();
List<EleMaterialsVo> allMaterialsList = new ArrayList<>(); // 用于导出所有物料
// 获取表中的已有的数据
log.info("开始获取表中的已有的数据");
for (EleMaterialsVo newMaterialsVo : list) {
@ -269,7 +269,7 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
.eq(EleMaterials::getModel, newMaterialsVo.getModel())
.eq(EleMaterials::getMaterialType, newMaterialsVo.getMaterialType())
.eq(EleMaterials::getBrand, newMaterialsVo.getBrand());
// 查询是否存在相同的物料
EleMaterials existingMaterial = baseMapper.selectOne(queryWrapper);
EleMaterialsVo eleMaterialsVo = BeanUtil.copyProperties(existingMaterial, EleMaterialsVo.class);
@ -283,24 +283,30 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
} else {
// 如果不存在生成新的物料编码
String lastCode = baseMapper.getLastMaterialCode(newMaterialsVo.getMaterialType()); // 查询数据库中最后的编码
String newCode = generateNextMaterialCode(lastCode, newMaterialsVo.getMaterialType());
String newCode;
if (lastCode != null) {
newCode = generateNextMaterialCode(lastCode, newMaterialsVo.getMaterialType());
} else {
// 如果没有找到旧的物料编码设置为默认编码
newCode = newMaterialsVo.getMaterialType() + "0000000001"; // 例如使用类型加上一个默认的序号
}
newMaterialsVo.setMaterialCode(newCode);
EleMaterials eleMaterials = BeanUtil.copyProperties(newMaterialsVo, EleMaterials.class);
eleMaterials.setMaterialValue("0");
//立刻插入数据
// 立刻插入数据
int insert = baseMapper.insert(eleMaterials);
// 仅在有编码的情况下添加到插入列表和导出列表
eleMaterialsList.add(eleMaterials); // 添加到插入列表
allMaterialsList.add(newMaterialsVo); // 添加到导出列表
}
}
// 导出数据为 Excel 文件
log.info("开始导出数据为 Excel 文件");
ExcelUtil.exportExcel(allMaterialsList, "电气物料BOM", EleMaterialsVo.class, response);
log.info("开始导出数据为 Excel 文件");
ExcelUtil.exportExcel(allMaterialsList, "电气物料BOM", EleMaterialsVo.class, response);
return true;
}
@ -387,6 +393,9 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
case "":
fBaseUnitId.addProperty("FNumber", "002");
break;
case "":
fBaseUnitId.addProperty("FNumber", "034");
break;
case "":
fBaseUnitId.addProperty("FNumber", "012");
break;
@ -446,6 +455,9 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
case "":
fBaseUnitId.addProperty("FNumber", "012");
break;
case "":
fBaseUnitId.addProperty("FNumber", "034");
break;
case "":
fBaseUnitId.addProperty("FNumber", "001");
break;
@ -504,6 +516,9 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
case "":
fBaseUnitId.addProperty("FNumber", "012");
break;
case "":
fBaseUnitId.addProperty("FNumber", "034");
break;
case "":
fBaseUnitId.addProperty("FNumber", "001");
break;
@ -550,6 +565,9 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
case "":
fBaseUnitId.addProperty("FNumber", "012");
break;
case "":
fBaseUnitId.addProperty("FNumber", "034");
break;
case "":
fBaseUnitId.addProperty("FNumber", "001");
break;
@ -620,6 +638,9 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
case "":
fBaseUnitId.addProperty("FNumber", "012");
break;
case "":
fBaseUnitId.addProperty("FNumber", "034");
break;
case "":
fBaseUnitId.addProperty("FNumber", "001");
break;
@ -676,6 +697,9 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
case "":
fBaseUnitId.addProperty("FNumber", "005");
break;
case "":
fBaseUnitId.addProperty("FNumber", "034");
break;
case "":
fBaseUnitId.addProperty("FNumber", "020");
break;

View File

@ -64,8 +64,8 @@ public class MaterialTotalServiceImpl implements IMaterialTotalService {
lqw.eq(StringUtils.isNotBlank(bo.getProductionOrderNumber()), MaterialTotal::getProductionOrderNumber, bo.getProductionOrderNumber());
lqw.eq(StringUtils.isNotBlank(bo.getMaterialCode()), MaterialTotal::getMaterialCode, bo.getMaterialCode());
lqw.like(StringUtils.isNotBlank(bo.getMaterialName()), MaterialTotal::getMaterialName, bo.getMaterialName());
lqw.eq(bo.getQuantity() != null, MaterialTotal::getQuantity, bo.getQuantity());
lqw.eq(bo.getInventory() != null, MaterialTotal::getInventory, bo.getInventory());
lqw.eq(StringUtils.isNotBlank(bo.getQuantity()), MaterialTotal::getQuantity, bo.getQuantity());
lqw.eq(StringUtils.isNotBlank(bo.getInventory()), MaterialTotal::getInventory, bo.getInventory());
lqw.eq(bo.getDemandTime() != null, MaterialTotal::getDemandTime, bo.getDemandTime());
lqw.eq(StringUtils.isNotBlank(bo.getRemarks()), MaterialTotal::getRemarks, bo.getRemarks());
return lqw;
@ -112,4 +112,15 @@ public class MaterialTotalServiceImpl implements IMaterialTotalService {
}
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* @param code
* @return
*/
@Override
public Boolean getVMIByCode(String code) {
LambdaQueryWrapper<MaterialTotal> materialTotalLambdaQueryWrapper = new LambdaQueryWrapper<>();
materialTotalLambdaQueryWrapper.eq(MaterialTotal::getMaterialCode, code);
return !baseMapper.selectList(materialTotalLambdaQueryWrapper).isEmpty();
}
}

View File

@ -36,6 +36,7 @@ import com.ruoyi.system.runner.JdUtil;
import com.ruoyi.system.runner.PDFGenerator;
import com.ruoyi.system.service.IBomDetailsService;
import com.ruoyi.system.service.IMaterialPropertiesService;
import com.ruoyi.system.service.IMaterialTotalService;
import com.ruoyi.system.service.IProcessRouteService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.ListUtils;
@ -66,9 +67,10 @@ import static com.ruoyi.system.runner.updatePcessPlanConver.updatePcessPlan1;
@Service
public class ProcessRouteServiceImpl implements IProcessRouteService {
private final ProcessRouteMapper baseMapper;
private final IMaterialTotalService iMaterialTotalService;
@Autowired
IBomDetailsService iBomDetailsService;
private final ProcessRouteMapper baseMapper;
@Autowired
BomDetailsMapper bomDetailsMapper;
@Autowired
@ -126,55 +128,124 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
public List<ProcessRouteVo> queryList(ProcessRouteBo bo) {
LambdaQueryWrapper<ProcessRoute> lqw = buildQueryWrapper(bo);
List<ProcessRouteVo> sortedList = new ArrayList<>();
// 获取工艺表中材质为总装部件的物料编码和名称
LambdaQueryWrapper<ProcessRoute> lqwRoute = buildQueryWrapper(bo);
lqwRoute.eq(ProcessRoute::getMaterial, "总装部件")
.eq(ProcessRoute::getRouteDescription, bo.getRouteDescription());
List<ProcessRoute> processRoutes = baseMapper.selectList(lqwRoute);
// 装配工艺路线
for (ProcessRoute processRoute : processRoutes) {
List<ProcessRoute> routes1 = getProcessRoutesByOrder(processRoute.getRouteDescription(), processRoute.getMaterialCode());
for (ProcessRoute route : routes1) {
ProcessRouteVo processRouteVo1 = BeanUtil.copyProperties(route, ProcessRouteVo.class);
sortedList.add(processRouteVo1);
if (!processRoutes.isEmpty()) {
// 装配工艺路线
for (ProcessRoute processRoute : processRoutes) {
List<ProcessRoute> routes1 = getProcessRoutesByOrder(processRoute.getRouteDescription(),
processRoute.getMaterialCode());
for (ProcessRoute route : routes1) {
ProcessRouteVo processRouteVo1 = BeanUtil.copyProperties(route, ProcessRouteVo.class);
sortedList.add(processRouteVo1);
}
// 查询 BOM 详情
List<BomDetails> bomDetails1 = bomDetailsService.selectByFNumberAndTotalWeight(
processRoute.getMaterialCode(), processRoute.getRouteDescription());
List<BomDetails> filteredBomDetails = filterBomDetails(bomDetails1);
log.info("过滤后的 BOM 详情数量: {}", filteredBomDetails.size());
// 将对应的工艺路线加入到 sortedList
for (BomDetails bomDetail : filteredBomDetails) {
addProcessRoutesFromBomDetail(bomDetail, sortedList);
// 将组焊件写入工艺
if ("组焊件".equals(bomDetail.getMaterial())) {
List<BomDetails> bomDetails = bomDetailsService
.selectByFNumberAndTotalWeight(bomDetail.getPartNumber(), bomDetail.getTotalWeight());
for (BomDetails detail : bomDetails) {
addProcessRoutesFromBomDetail(detail, sortedList);
}
}
}
return sortedList;
}
// 查询 BOM 详情
List<BomDetails> bomDetails1 = bomDetailsService.selectByFNumberAndTotalWeight(processRoute.getMaterialCode(), processRoute.getRouteDescription());
List<BomDetails> filteredBomDetails = filterBomDetails(bomDetails1);
log.info("过滤后的 BOM 详情数量: {}", filteredBomDetails.size());
// 将对应的工艺路线加入到 sortedList
for (BomDetails bomDetail : filteredBomDetails) {
addProcessRoutesFromBomDetail(bomDetail, sortedList);
// 将组焊件写入工艺
if ("组焊件".equals(bomDetail.getMaterial())) {
List<BomDetails> bomDetails = bomDetailsService.selectByFNumberAndTotalWeight(bomDetail.getPartNumber(), bomDetail.getTotalWeight());
for (BomDetails detail : bomDetails) {
addProcessRoutesFromBomDetail(detail, sortedList);
} else {
log.info("工艺路线为空,按正常顺序导出");
List<ProcessRoute> normalProcessRoutes = baseMapper.selectList(lqw);
Set<String> addedKeys = new HashSet<>(); // 记录已添加的 BOM 详情键
for (ProcessRoute processRoute : normalProcessRoutes) {
// 创建一个新的 ProcessRouteVo 对象并复制 ProcessRoute 的基本信息
ProcessRouteVo processRouteVo = BeanUtil.copyProperties(processRoute, ProcessRouteVo.class);
processRouteVo.setRawMaterialName(null);
processRouteVo.setRawMaterialCode(null);
processRouteVo.setBomMaterial(null);
processRouteVo.setDiscUsage(null);
processRouteVo.setBomUnit(null);
sortedList.add(processRouteVo);
// 获取到工艺路线对应的BOM 数量
List<BomDetails> bomDetails = bomDetailsService.selectByFNumberAndTotalWeight(
processRoute.getMaterialCode(), processRoute.getRouteDescription());
// 如果 BOM 详情不为空为每个 BOM 详情创建一个新的对象
if (bomDetails != null && !bomDetails.isEmpty()) {
for (BomDetails bomDetail : bomDetails) {
String key = generateKey1(bomDetail,processRoute); // 生成唯一键
if (!addedKeys.contains(key)) {
// 创建一个新的 ProcessRouteVo 对象来存储 BOM 详情的信息
ProcessRouteVo bomDetailsVo = new ProcessRouteVo();
bomDetailsVo.setRouteDescription(bomDetail.getTotalWeight());
bomDetailsVo.setMaterialCode(bomDetail.getFNumber());
bomDetailsVo.setMaterialName(bomDetail.getFName());
bomDetailsVo.setMaterial(bomDetail.getMaterial());
bomDetailsVo.setDiscUsage(bomDetail.getQuantity());
bomDetailsVo.setRawMaterialCode(bomDetail.getPartNumber());
bomDetailsVo.setRawMaterialName(bomDetail.getName());
bomDetailsVo.setBomUnit(bomDetail.getWareHouse());
// 找到对应的 ProcessRouteVo 位置并插入
for (int i = 0; i < sortedList.size(); i++) {
ProcessRouteVo existingVo = sortedList.get(i);
if (existingVo.getMaterialCode().equals(bomDetailsVo.getMaterialCode()) &&
existingVo.getMaterialName().equals(bomDetailsVo.getMaterialName())) {
sortedList.add(i, bomDetailsVo); // 插入到匹配的 ProcessRouteVo 之前
addedKeys.add(key); // 记录已添加的键
break;
}
}
}
}
}
}
}
return sortedList;
}
/**
* @param bo
* @return
*/
@Override
public List<ProcessRouteVo> queryList2(ProcessRouteBo bo) {
LambdaQueryWrapper<ProcessRoute> lqw = buildQueryWrapper(bo);
List<ProcessRouteVo> sortedList = new ArrayList<>();
List<ProcessRoute> processRoutes = baseMapper.selectList(lqw);
return Collections.emptyList();
}
private String generateKey1(BomDetails bomDetail,ProcessRoute processRoute) {
return String.format("%s:%s:%s", processRoute.getMaterialCode(), processRoute.getMaterialName(), bomDetail.getName(),bomDetail.getPartNumber());
}
private List<BomDetails> filterBomDetails(List<BomDetails> bomDetails) {
return bomDetails.stream()
.filter(bom -> bom != null &&
bom.getPartNumber() != null &&
!bom.getPartNumber().startsWith("009") &&
!bom.getPartNumber().startsWith(" ") &&
(bom.getRemarks() == null || !bom.getRemarks().contains("伊特")))
.filter(bom -> bom != null &&
bom.getPartNumber() != null &&
!bom.getPartNumber().startsWith("009") &&
!bom.getPartNumber().startsWith(" ") &&
(bom.getRemarks() == null || !bom.getRemarks().contains("伊特")))
.collect(Collectors.toList());
}
private void addProcessRoutesFromBomDetail(BomDetails bomDetail, List<ProcessRouteVo> sortedList) {
List<ProcessRoute> routes = getProcessRoutesByOrder(bomDetail.getTotalWeight(), bomDetail.getPartNumber());
for (ProcessRoute route : routes) {
@ -431,24 +502,32 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
}
public boolean saveData(List<ProcessRouteVo> routeVoList, List<ProductionOrderVo> productionOrderVos) {
// ProcessRouteVo 转换为 ProcessRoute 工艺集合 材料bom 集合
List<ProcessRoute> processRoutes = BeanUtil.copyToList(routeVoList, ProcessRoute.class);
// 1. 处理材料 BOM 存入材料bom
processMaterialBom(processRoutes);
// 2. 处理 BOM 详情 工艺 总装的
List<BomDetailsVo> bomDetailsVos = processBomDetails(routeVoList, productionOrderVos);
// 3. 保存 BOM 详情
Map<String, Double> inventoryCache = new HashMap<>(); // 缓存可用库存
saveBomDetails(bomDetailsVos);
List<ProcessRoute> routeArrayList = new ArrayList<>();
Map<String, Double> inventoryCache = new HashMap<>();
// 批量查询所有需要的库存信息
for (ProcessRoute processRoute : processRoutes) {
String materialCode = processRoute.getMaterialCode();
if (!inventoryCache.containsKey(materialCode)) {
try {
Double kucun = JdUtil.getKeyong(materialCode);
inventoryCache.put(materialCode, kucun != null ? kucun : 0.0);
} catch (Exception e) {
log.error("查询库存失败: {}", materialCode, e);
inventoryCache.put(materialCode, 0.0);
}
}
}
boolean allEmpty = processRoutes.stream()
.allMatch(route -> route.getProcessNo() == null && route.getProcessName() == null);
if (allEmpty && !processRoutes.isEmpty()) {
// 1. 找出Excel中重复出现的组焊件物料编码
List<String> duplicateWeldingMaterials = processRoutes.stream()
.filter(route -> "组焊件".equals(route.getMaterial()))
.map(ProcessRoute::getMaterialCode)
@ -458,30 +537,19 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
.map(Map.Entry::getKey)
.collect(Collectors.toList());
// 2. 用于记录已处理的重复组焊件
Set<String> processedWeldingMaterials = new HashSet<>();
for (ProcessRoute processRoute : processRoutes) {
// 判断是否是重复的组焊件
String materialCode = processRoute.getMaterialCode();
Double kucun = inventoryCache.get(materialCode); // 从缓存中获取库存
if (kucun == null) { // 如果缓存中没有则查询
log.info("开始查询可用库存:" + materialCode);
kucun = JdUtil.getKeyong(materialCode);
if (kucun == null) {
kucun = 0.0;
}
inventoryCache.put(materialCode, kucun); // 将查询结果存入缓存
}
Double kucun = inventoryCache.get(materialCode);
boolean isDuplicateWelding = "组焊件".equals(processRoute.getMaterial())
&& duplicateWeldingMaterials.contains(processRoute.getMaterialCode());
&& duplicateWeldingMaterials.contains(materialCode);
// 如果是重复的组焊件且已处理过则跳过
if (isDuplicateWelding && processedWeldingMaterials.contains(processRoute.getMaterialCode())) {
if (isDuplicateWelding && processedWeldingMaterials.contains(materialCode)) {
continue;
}
List<ProcessRouteSelectDTO> selectProcessRoute = getSelectProcessRoute(processRoute.getMaterialCode());
List<ProcessRouteSelectDTO> selectProcessRoute = getSelectProcessRoute(materialCode);
if (!selectProcessRoute.isEmpty()) {
List<ProductionRouteTwo> productionRouteTwos = new ArrayList<>();
@ -500,38 +568,14 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
productionRouteTwo.setFmaterialidFnumber(processRouteSelectDTO.getFNumber());
productionRouteTwos.add(productionRouteTwo);
}
// 1. 保存金蝶工艺路线
productionRouteTwoMapper.insertOrUpdateBatch(productionRouteTwos);
try {
productionRouteTwoMapper.insertOrUpdateBatch(productionRouteTwos);
} catch (Exception e) {
log.error("保存金蝶工艺路线失败: {}", materialCode, e);
}
// 2. 同时创建默认工序
ProcessRoute defaultRoute = new ProcessRoute();
BeanUtil.copyProperties(processRoute, defaultRoute);
// 设置默认工序信息
defaultRoute.setProcessNo(10L); // 默认工序号为10
defaultRoute.setWorkCenter(null);
defaultRoute.setProcessName(null);
defaultRoute.setProcessDescription(null);
defaultRoute.setProcessControl(null);
defaultRoute.setActivityDuration(null);
defaultRoute.setActivityUnit("");
// 设置库存信息
kucun = inventoryCache.getOrDefault(processRoute.getMaterialCode(), 0.0);
defaultRoute.setFirstBatchQuantity(kucun);
// 设置时间戳
defaultRoute.setCreateTime(new Date());
defaultRoute.setUpdateTime(new Date());
routeArrayList.add(defaultRoute);
log.info("为物料 {} 同时生成了金蝶工艺路线和默认工序", processRoute.getMaterialCode());
} else {
// 如果没有金蝶工艺路线只生成默认工序
ProcessRoute defaultRoute = new ProcessRoute();
BeanUtil.copyProperties(processRoute, defaultRoute);
defaultRoute.setProcessNo(10L);
defaultRoute.setWorkCenter(null);
defaultRoute.setProcessName(null);
@ -539,41 +583,56 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
defaultRoute.setProcessControl(null);
defaultRoute.setActivityDuration(null);
defaultRoute.setActivityUnit("");
kucun = inventoryCache.getOrDefault(processRoute.getMaterialCode(), 0.0);
defaultRoute.setFirstBatchQuantity(kucun);
defaultRoute.setCreateTime(new Date());
defaultRoute.setUpdateTime(new Date());
routeArrayList.add(defaultRoute);
log.info("为物料 {} 仅生成默认工序,因为在金蝶中未找到对应工艺路线", processRoute.getMaterialCode());
log.info("为物料 {} 同时生成了金蝶工艺路线和默认工序", materialCode);
} else {
ProcessRoute defaultRoute = new ProcessRoute();
BeanUtil.copyProperties(processRoute, defaultRoute);
defaultRoute.setProcessNo(10L);
defaultRoute.setWorkCenter(null);
defaultRoute.setProcessName(null);
defaultRoute.setProcessDescription(null);
defaultRoute.setProcessControl(null);
defaultRoute.setActivityDuration(null);
defaultRoute.setActivityUnit("");
defaultRoute.setFirstBatchQuantity(kucun);
defaultRoute.setCreateTime(new Date());
defaultRoute.setUpdateTime(new Date());
routeArrayList.add(defaultRoute);
log.info("为物料 {} 仅生成默认工序,因为在金蝶中未找到对应工艺路线", materialCode);
}
// 如果是重复的组焊件标记为已处理
if (isDuplicateWelding) {
processedWeldingMaterials.add(processRoute.getMaterialCode());
log.info("为重复出现的组焊件物料 {} 生成了默认工序", processRoute.getMaterialCode());
processedWeldingMaterials.add(materialCode);
log.info("为重复出现的组焊件物料 {} 生成了默认工序", materialCode);
} else {
log.info("为物料 {} 生成了默认工序", processRoute.getMaterialCode());
log.info("为物料 {} 生成了默认工序", materialCode);
}
}
} else {
// 处理非空工序的情况
for (ProcessRoute processRoute : processRoutes) {
if (processRoute.getProcessNo() != null || processRoute.getProcessName() != null) {
processRoute.setActivityUnit("");
processRoute.setCreateTime(new Date());
processRoute.setUpdateTime(new Date());
Double kucun = JdUtil.getKeyong(processRoute.getMaterialCode());
Double kucun = inventoryCache.get(processRoute.getMaterialCode());
processRoute.setFirstBatchQuantity(kucun);
routeArrayList.add(processRoute);
}
}
}
return baseMapper.insertBatch(routeArrayList);
try {
return baseMapper.insertBatch(routeArrayList);
} catch (Exception e) {
log.error("批量插入工艺路线失败", e);
return false;
}
}
private void processMaterialBom(List<ProcessRoute> processRoutes) {
@ -639,8 +698,13 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
Double quantity = productionOrderVo.getQuantity();
bomDetails.setQuantity(quantity != null ? quantity : 0.0);
bomDetails.setMaterial(productionOrderVo.getMaterial());
bomDetails.setRemarks(productionOrderVo.getRemark());
String materialCode = productionOrderVo.getDrawingNo();
if (iMaterialTotalService.getVMIByCode(materialCode)) {
bomDetails.setRemarks("VMI");
} else {
bomDetails.setRemarks(productionOrderVo.getRemark());
}
bomDetails.setDanzhong(productionOrderVo.getSingleWeight());
// 判断外购或自制
String drawingNo = productionOrderVo.getDrawingNo();
String remark = productionOrderVo.getRemark();
@ -681,7 +745,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
bomDetails.setFName(processRoute.getMaterialName());
bomDetails.setPartNumber(processRoute.getRawMaterialCode());
bomDetails.setName(processRoute.getRawMaterialName());
bomDetails.setDanzhong(processRoute.getDiscWeight());
// 处理单位换算
if ("mm".equals(processRoute.getBomUnit())) {
bomDetails.setQuantity(processRoute.getDiscUsage() / 1000.0); // 转换为米
@ -721,6 +785,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
bomDetails.setQuantity(productionOrderVo.getQuantity());
bomDetails.setMaterial(productionOrderVo.getMaterial());
bomDetails.setRemarks(productionOrderVo.getRemark());
bomDetails.setDanzhong(productionOrderVo.getSingleWeight());
// 判断外购或自制
String drawingNo = productionOrderVo.getDrawingNo();
String remark = productionOrderVo.getRemark();
@ -1211,6 +1276,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
ProcessRouteSelectDTO jdRoute = jdRoutes.get(i);
if (!Objects.equals(localRoute.getProcessNo(), jdRoute.getProcessNo()) ||
!Objects.equals(localRoute.getProcessName(), jdRoute.getProcessName()) ||
!Objects.equals(localRoute.getProcessDescription(), jdRoute.getProcessDescription()) ||
!Objects.equals(localRoute.getWorkCenter(), jdRoute.getWorkCenter()) ||
!Objects.equals(localRoute.getProcessControl(), jdRoute.getProcessControl()) ||
!Objects.equals(localRoute.getActivityDuration(), jdRoute.getActivityDuration())) {
@ -1494,7 +1560,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
* 更新计划订单
*/
@Override
public List<Model> updateProcessPlan(String rooteProdet) {
public List<Model> updateProcessPlan(String rooteProdet) throws Exception {
// 获取工序计划单据内码
List<Model> numDTOS = getSelecPlan(rooteProdet);
// 获取原材料工艺路线列表
@ -1538,6 +1604,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
} finally {
executorService.shutdown();
}
RepoRet repoRet = updatePcessPlan1(numDTOS);
log.info(repoRet.isSuccessfully() ? "更新成功" : "更新失败");
if (repoRet.isSuccessfully()) {
@ -1869,7 +1936,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
json.addProperty("FieldKeys",
"FID,FSubEntity_FDetailID,FProductId.FNumber,FOperNumber,FEntity_FEntryID,FProcessId.FName,FSeqNumber,FSeqName,FPlanStartTime,FPlanFinishTime,"
+
"FOperPlanStartTime,FOperPlanFinishTime");
"FOperPlanStartTime,FOperPlanFinishTime,FMONumber");
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
@ -1923,10 +1990,11 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
// 使用 Map 结构暂存 Model 对象
Map<Integer, Model> modelMap = new HashMap<>();
for (PlanPrcessNumDTO dto : plannedProcesses) {
// <EFBFBD><EFBFBD>取或创建 Model 对象
// 创建 Model 对象
Model model = modelMap.computeIfAbsent(dto.getFID(), fid -> {
Model newModel = new Model();
newModel.setFID(fid);
newModel.setFMONumber(dto.getFMONumber());
newModel.setFPlanStartTime(dto.getFPlanStartTime());
newModel.setFPlanFinishTime(dto.getFPlanFinishTime());
newModel.setFProcessId_number(dto.getFProcessId_number()); // 设置 FProcessId_number
@ -1969,20 +2037,20 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
wrapper.eq(ProcessRoute::getMaterialCode, materialCode);
List<ProcessRoute> processRoutes = baseMapper.selectList(wrapper);
ProcessTimeInfo timeInfo = new ProcessTimeInfo(); // 创建返回对象
if (processRoutes.isEmpty()) {
System.out.println("没有找到任何工序");
return timeInfo; // 返回空信息
}
Date tenthProcessStartTime = null;
Date lastProcessEndTime = null;
int maxSequenceNumber = -1; // 初始化最大序号
Map<Integer, Date> sequenceEndTimeMap = new HashMap<>();
for (ProcessRoute route : processRoutes) {
Long sequenceNumber = route.getProcessNo();
// 确保 sequenceNumber 和时间不为 null
if (sequenceNumber != null && route.getXuEndTime() != null) {
sequenceEndTimeMap.put(sequenceNumber.intValue(), route.getXuEndTime());
@ -1997,13 +2065,14 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
}
}
}
// 获取最大序号对应的结束时间
lastProcessEndTime = sequenceEndTimeMap.get(maxSequenceNumber);
timeInfo.setTenthProcessStartTime(tenthProcessStartTime);
timeInfo.setLastProcessEndTime(lastProcessEndTime);
return timeInfo;
}
// 获取存在工艺
public List<ProcessRouteSelectDTO> getSelectProcessRoute(String materialCode) {
K3CloudApi client = new K3CloudApi();
@ -2196,7 +2265,8 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
}
return 0.0;
}
//获取父级的物料的公式
// 获取父级的物料的公式
public Double getFaWorkTime(BomDetails material) {
if (material == null) {
log.error("传入的物料对象为 null");
@ -2219,6 +2289,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
}
return 0.0;
}
/**
* @param productionOrderNo
* @param materialCode
@ -2235,4 +2306,140 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
return Collections.emptyList();
}
/**
* @param materialCode
* @return
*/
@Override
public List<ProcessRoute> getSingleWeght(String materialCode) {
LambdaQueryWrapper<ProcessRoute> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ProcessRoute::getMaterialCode, materialCode)
.ne(ProcessRoute::getWorkCenter, null);
if (baseMapper.selectList(wrapper) != null) {
return baseMapper.selectList(wrapper);
}
return Collections.emptyList();
}
/**
* 更新生产订单的计划开始时间和计划结束时间
*
* @param rooteProdet
* @return
*/
@Override
public List<Model> updateProcesTime(String rooteProdet) throws Exception {
List<PlanOrderVo> planOrderList = getSelectProceOrder1(rooteProdet);
List<Model> numDTOS = getSelecPlan(rooteProdet);
LambdaQueryWrapper<ProcessRoute> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ProcessRoute::getRouteDescription, rooteProdet);
List<ProcessRoute> routeList = baseMapper.selectList(wrapper);
Map<String, List<ProcessRoute>> groupedByMaterialCode = routeList.stream()
.collect(Collectors.groupingBy(ProcessRoute::getMaterialCode));
Set<String> processedMaterialCodes = new HashSet<>(); // 用于去重
if (planOrderList == null || planOrderList.isEmpty()) {
log.warn("没有找到生产订单");
return Collections.emptyList();
}
for (PlanOrderVo planOrder : planOrderList) {
for (Model numDTO : numDTOS) {
if (planOrder.getFBillNo().equals(numDTO.getFMONumber())) {
JdHuoZhu fidToProductionOrder = JdUtil.getFIDToProductionOrder(planOrder);
if (fidToProductionOrder != null) {
String materialCode = String.valueOf(fidToProductionOrder.getFID());
if (!processedMaterialCodes.contains(materialCode)) {
try {
List<ProcessRoute> routeList1 = groupedByMaterialCode
.get(planOrder.getFmaterialidFnumber());
Date xuStartTime = null;
Date xuEndTime = null;
if (routeList1 != null && !routeList1.isEmpty()) {
xuStartTime = getStartTime(routeList1);
xuEndTime = getEndTime(routeList1);
}
JdUtil.updateOrder(fidToProductionOrder, numDTO, xuStartTime, xuEndTime);
processedMaterialCodes.add(materialCode); // 标记为已处理
} catch (Exception e) {
log.error("更新生产订单 {} 时发生错误: {}", planOrder.getFBillNo(), e.getMessage());
}
} else {
log.info("更新生产订单 {} 已处理,跳过保存", materialCode);
}
} else {
log.warn("未找到与生产订单 {} 相关的 FID", planOrder.getFBillNo());
}
}
}
}
return Collections.emptyList();
}
// 获取工序是开始时间且是最小工序
private Date getStartTime(List<ProcessRoute> routeList) {
return routeList.stream()
.min(Comparator.comparing(ProcessRoute::getProcessNo))
.map(ProcessRoute::getXuStartTime)
.orElse(null);
}
private Date getEndTime(List<ProcessRoute> routeList) {
return routeList.stream()
.max(Comparator.comparing(ProcessRoute::getProcessNo))
.map(ProcessRoute::getXuEndTime)
.orElse(null);
}
public static JdHuoZhu getFIDToProductionOrder(PlanOrderVo planOrder) {
K3CloudApi client = new K3CloudApi();
JsonObject json = new JsonObject();
json.addProperty("FormId", "PRD_MO");
json.addProperty("FieldKeys", "FTreeEntity_FENTRYID,FID");
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FBillNo");
filterObject.addProperty("Compare", "=");
filterObject.addProperty("Value", planOrder.getFBillNo());
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<JdHuoZhu> jinYongDTOList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<JdHuoZhu>>() {
});
if (jinYongDTOList != null && !jinYongDTOList.isEmpty()) {
return jinYongDTOList.get(0); // 返回第一个对象
}
} else {
log.warn("未找到与次生产订单的FID " + planOrder.getFBillNo() + " 相关的记录");
}
} catch (Exception e) {
log.error("调用接口时发生异常: " + e.getMessage(), e);
}
return null; // 如果没有找到返回 null
}
}

View File

@ -186,8 +186,8 @@ public class ProductionRouteTwoServiceImpl implements IProductionRouteTwoService
// 填充物料相关数据
productionRouteTwo.setFMaterialid2ChildFnumber(materialUsageDTO.getMaterialCode()); // 物料编码
productionRouteTwo.setFMaterialName1(materialUsageDTO.getMaterialName()); // 物料名称
productionRouteTwo.setFNumerator(materialUsageDTO.getFNumerator()); // 分子fMaterialName1
productionRouteTwo.setFDenominator(materialUsageDTO.getFDenominator()); // 分母
productionRouteTwo.setFNumerator((long) materialUsageDTO.getFNumerator()); // 分子fMaterialName1
productionRouteTwo.setFDenominator((long) materialUsageDTO.getFDenominator()); // 分母
productionRouteTwo.setFunitid2ChildFname(materialUsageDTO.getUnit());
productionRouteTwo.setChildMaterial(materialUsageDTO.getChildMaterial());

View File

@ -47,17 +47,14 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
private final Queue<String> logMessages = new ConcurrentLinkedQueue<>(); // 使用线程安全的队列存储日志
private static final Logger logger = LoggerFactory.getLogger(WlStockDataServiceImpl.class);
private final WlStockDataMapper baseMapper;
private final SafetyStockMapper safetyStockMapper;
private static final int MAX_RETRIES = 3;
private static final long RETRY_DELAY = 2000L; // 2秒
private static final int THREAD_POOL_SIZE = 10;
/**
* 查询安全库存单据
*/
@ -103,6 +100,7 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
lqw.eq(bo.getMinsafetyStock() != null, WlStockData::getMinsafetyStock, bo.getMinsafetyStock());
return lqw;
}
/**
* 新增安全库存单据
*/
@ -145,8 +143,6 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
return baseMapper.deleteBatchIds(ids) > 0;
}
private void logMessages(String message) {
logMessages.add(message); // 存储日志信息
}
@ -163,6 +159,7 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
}
return logs;
}
/**
* 生成安全库存单据
*
@ -181,27 +178,27 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
// 使用固定大小的线程池而不是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());
.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); // 设置整体超时时间
.get(5, TimeUnit.MINUTES); // 设置整体超时时间
// 批量保存数据
if (!wlStockDataList.isEmpty()) {
@ -233,8 +230,6 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
}
}
private WlStockData processWithRetry(SafetyStock safetyStock) {
int retryCount = 0;
while (retryCount < MAX_RETRIES) {
@ -266,8 +261,25 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
}
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 {
// 获取库存分析报告
// 获取库存
List<InvReserveAnalyzeRptDTO> analyzeRpt = JdUtil.getInvReserveAnalyzeRpt(materialCode);
double fSecAVBQty = 0.0;
double fSecQty = 0.0;
@ -275,36 +287,49 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
if (!CollectionUtils.isEmpty(analyzeRpt)) {
fSecAVBQty = analyzeRpt.get(0).getFSecAVBQty();
fSecQty = analyzeRpt.stream()
.mapToDouble(dto -> dto.getFSecQty() != null ? dto.getFSecQty() : 0.0)
.sum();
.mapToDouble(dto -> dto.getFSecQty() != null ? dto.getFSecQty() : 0.0)
.sum();
}
// 获取生产订单数量
double productionQty = Optional.ofNullable(JdUtil.getProMoList(materialCode))
.map(list -> list.stream()
.mapToDouble(ProMoDTO::getFQty)
.sum())
.orElse(0.0);
.map(list -> list.stream()
.mapToDouble(ProMoDTO::getFQty)
.sum())
.orElse(0.0);
// 获取采购订单数量
double purchaseQty = Optional.ofNullable(JdUtil.getPurchaseOrderList(materialCode))
.map(list -> list.stream()
.mapToDouble(PurchaseOrderDTO::getFQty)
.sum())
.orElse(0.0);
.map(list -> list.stream()
.mapToDouble(PurchaseOrderDTO::getFQty)
.sum())
.orElse(0.0);
// 计算可用库存
double availableStock = fSecAVBQty + productionQty + purchaseQty - fSecQty;
double minSafetyStock = safetyStock.getMinSafetyStock();
double maxSafetyStock = safetyStock.getMaxSafetyStock();
logger.debug("物料编码:{},生产订单数量: {}, 采购订单数量: {}, 可用库存: {}",materialCode,productionQty, purchaseQty, availableStock);
logMessages("物料编码:" + materialCode + ",生产订单数量: " + productionQty + ", 采购订单数量: " + purchaseQty + ", 可用库存: " + availableStock);
logger.debug("物料编码:{}, 生产订单数量: {}, 采购订单数量: {}, 可用库存: {}", 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, fSecAVBQty, productionQty, purchaseQty, fSecQty, minSafetyStock, maxSafetyStock);
}
} catch (Exception e) {
@ -315,10 +340,8 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
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 fSecAVBQty, double productionQty, double purchaseQty, double fSecQty, double minSafetyStock, double maxSafetyStock) {
//创建安全库存单据
WlStockData wlStockData = new WlStockData();
wlStockData.setMaterialCode(safetyStock.getMaterialCode());
wlStockData.setMaterialName(safetyStock.getMaterialName());
@ -335,12 +358,13 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
wlStockData.setDocumentType(String.format("物料编码:%s||可用库存:%.2f||库存量:%.2f||生产订单:%.2f||" +
"采购订单:%.2f||预留量:%.2f||最大库存:%.2f||最低库存:%.2f",
safetyStock.getMaterialCode(), availableStock, fSecAVBQty, productionQty,
purchaseQty, fSecQty, maxSafetyStock, minSafetyStock));
safetyStock.getMaterialCode(), availableStock, fSecAVBQty, productionQty,
purchaseQty, fSecQty, maxSafetyStock, minSafetyStock));
return wlStockData;
}
public List<InvReserveAnalyzeRptDTO> getInvReserveAnalyzeRpt(String materialCode) {
public List<InvReserveAnalyzeRptDTO> getInvReserveAnalyzeRpt(String materialCode) {
List<InvReserveAnalyzeRptDTO> rptDTOS = new ArrayList<>();
K3CloudApi client = new K3CloudApi();
JsonObject jsonData = new JsonObject();
@ -393,7 +417,7 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
JsonObject resultObject = new Gson().fromJson(resultJson, JsonObject.class);
JsonArray rows = resultObject.getAsJsonObject("Result").getAsJsonArray("Rows");
if (rows == null){
if (rows == null) {
System.err.println("No data returned for materialCode: " + materialCode);
logMessages("No data returned for materialCode: " + materialCode);
return new ArrayList<>();
@ -415,6 +439,7 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
return rptDTOS;
}
private static String getStringFromJsonArray(JsonArray array, int index) {
return array.size() > index && !array.get(index).isJsonNull() ? array.get(index).getAsString() : "";
}
@ -432,6 +457,7 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
}
return 0.0;
}
/**
* 物料批量查询
*/
@ -445,7 +471,7 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
// 添加额外的过滤条件排除售后库
JsonObject excludeStockFilter = new JsonObject();
excludeStockFilter.addProperty("FieldName", "FStockId.FNumber"); // 设置字段名称为仓库编号
excludeStockFilter.addProperty("Compare", "!="); // 设置比较方式为不等于
excludeStockFilter.addProperty("Compare", "!="); // 设置比较方式为"不等于"
excludeStockFilter.addProperty("Value", "CK012"); // 设置需要排除的仓库编号
excludeStockFilter.addProperty("Left", ""); // 保留字段不使用
excludeStockFilter.addProperty("Right", ""); // 保留字段不使用
@ -454,7 +480,7 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
JsonObject excludeStockFilter1 = new JsonObject();
excludeStockFilter1.addProperty("FieldName", "FStockId.FNumber"); // 设置字段名称为仓库编号
excludeStockFilter1.addProperty("Compare", "!="); // 设置比较方式为不等于
excludeStockFilter1.addProperty("Compare", "!="); // 设置比较方式为"不等于"
excludeStockFilter1.addProperty("Value", "CK018"); // 设置需要排除的仓库编号
excludeStockFilter1.addProperty("Left", ""); // 保留字段不使用
excludeStockFilter1.addProperty("Right", ""); // 保留字段不使用
@ -524,5 +550,4 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
return resultJsonArray;
}
}

View File

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

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.MaterialTotalMapper">
<resultMap type="com.ruoyi.system.domain.MaterialTotal" id="MaterialTotalResult">