feat(system): 新增物料BOM相关功能
- 新增物料BOM校验逻辑 - 添加货主信息更新功能 - 实现安全库存更新 - 优化物料导入导出功能 - 新增双单位支持
This commit is contained in:
parent
969d31d9b7
commit
c57f04959c
@ -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
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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("更新成功");
|
||||
}
|
||||
}
|
||||
|
||||
@ -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("保存工段数据失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
/**
|
||||
* 需求时间
|
||||
*/
|
||||
|
||||
@ -97,7 +97,7 @@ public class ProcessRoute extends BaseEntity {
|
||||
/**
|
||||
* 单台数量
|
||||
*/
|
||||
private Long unitQuantity;
|
||||
private Double unitQuantity;
|
||||
/**
|
||||
* 本批数量
|
||||
*/
|
||||
|
||||
@ -75,5 +75,8 @@ public class BomDetailsBo extends BaseEntity {
|
||||
*/
|
||||
private String remarks;
|
||||
|
||||
|
||||
/**
|
||||
* 单重
|
||||
*/
|
||||
private Double danzhong;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
|
||||
@ -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; // 部件名称
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -31,4 +31,6 @@ public class PlanPrcessNumDTO {
|
||||
private Date FOperPlanStartTime;
|
||||
@JsonProperty("FOperPlanFinishTime")
|
||||
private Date FOperPlanFinishTime;
|
||||
@JsonProperty("FMONumber")
|
||||
private String FMONumber;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -96,6 +96,9 @@ public class BomDetailsVo {
|
||||
*/
|
||||
@ExcelProperty(value = "备注/仓库")
|
||||
private String remarks;
|
||||
|
||||
/**
|
||||
* 单重
|
||||
*/
|
||||
private Double danzhong;
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* 需求时间
|
||||
|
||||
@ -136,4 +136,7 @@ public class PlannedProcessVo {
|
||||
*/
|
||||
@JsonProperty("FDenominator")
|
||||
private Long fDenominator;
|
||||
|
||||
@JsonProperty("FActivity1Qty")
|
||||
private Long FActivity1Qty;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,4 +45,7 @@ public interface IMaterialTotalService {
|
||||
* 校验并批量删除物料汇总信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
|
||||
Boolean getVMIByCode(String code);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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());
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
|
||||
@ -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">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user