diff --git a/src/main/java/com/spring/modules/part/controller/PartInformationController.java b/src/main/java/com/spring/modules/part/controller/PartInformationController.java index c175768c..f0e360f7 100644 --- a/src/main/java/com/spring/modules/part/controller/PartInformationController.java +++ b/src/main/java/com/spring/modules/part/controller/PartInformationController.java @@ -704,6 +704,17 @@ public class PartInformationController { return R.ok(); } + /** + * RoHS 创建IFS料号(无From Part) + * @param data + * @return + */ + @PostMapping("createOfficialPartForRohs") + public R createOfficialPartForRohs(@RequestBody PartInformationVo data) { + partInformationService.createOfficialPartForRohs(data); + return R.ok(); + } + /** * 获取下一个物料编码 * @param data diff --git a/src/main/java/com/spring/modules/part/service/PartInformationService.java b/src/main/java/com/spring/modules/part/service/PartInformationService.java index ebfed3c8..1767ddc5 100644 --- a/src/main/java/com/spring/modules/part/service/PartInformationService.java +++ b/src/main/java/com/spring/modules/part/service/PartInformationService.java @@ -176,6 +176,11 @@ public interface PartInformationService { void copyPart2(PartInformationVo data); + /** + * RoHS 创建IFS料号(无From Part,直接新增正式物料并同步IFS) + */ + void createOfficialPartForRohs(PartInformationVo data); + /** * 查询物料关键字段变更日志(std_order_qty / estimated_material_cost) * @param site 工厂 diff --git a/src/main/java/com/spring/modules/part/service/impl/PartInformationServiceImpl.java b/src/main/java/com/spring/modules/part/service/impl/PartInformationServiceImpl.java index b058fc91..6cb707f6 100644 --- a/src/main/java/com/spring/modules/part/service/impl/PartInformationServiceImpl.java +++ b/src/main/java/com/spring/modules/part/service/impl/PartInformationServiceImpl.java @@ -3826,6 +3826,345 @@ public class PartInformationServiceImpl extends ServiceImpl() + .eq("site", data.getSite()) + .eq("part_no", data.getPartNo())); + if (existsPart != null) { + throw new RuntimeException("物料编码已存在,不允许重复创建!"); + } + + if (!StringUtils.hasText(data.getCreateBy()) && StringUtils.hasText(data.getUpdateBy())) { + data.setCreateBy(data.getUpdateBy()); + } + if (!StringUtils.hasText(data.getUpdateBy()) && StringUtils.hasText(data.getCreateBy())) { + data.setUpdateBy(data.getCreateBy()); + } + if (!StringUtils.hasText(data.getCreateBy())) { + data.setCreateBy("system"); + } + if (!StringUtils.hasText(data.getUpdateBy())) { + data.setUpdateBy(data.getCreateBy()); + } + if (data.getCreateDate() == null) { + data.setCreateDate(new Date()); + } + if (data.getEstimatedMaterialCost() == null) { + data.setEstimatedMaterialCost(BigDecimal.ZERO); + } + if (!StringUtils.hasText(data.getPartStatus())) { + data.setPartStatus("A"); + } + if (!StringUtils.hasText(data.getActive())) { + data.setActive("Y"); + } + if (!StringUtils.hasText(data.getLotTrackingCode())) { + data.setLotTrackingCode("Order Based"); + } + if (!StringUtils.hasText(data.getSupplyCode())) { + data.setSupplyCode("Inventory Order"); + } + if (!StringUtils.hasText(data.getConfigurationId())) { + data.setConfigurationId("*"); + } + if (!StringUtils.hasText(data.getInventoryValuationMethod())) { + data.setInventoryValuationMethod("Standard Cost"); + } + if (!StringUtils.hasText(data.getInventoryPartCostLevel())) { + data.setInventoryPartCostLevel("Cost Per Part"); + } + if (!StringUtils.hasText(data.getInvoiceConsideration())) { + data.setInvoiceConsideration("Ignore Invoice Price"); + } + if (!StringUtils.hasText(data.getZeroCostFlag())) { + data.setZeroCostFlag("Zero Cost Forbidden"); + } + if (!StringUtils.hasText(data.getPlanningMethod())) { + data.setPlanningMethod("A"); + } + if (!StringUtils.hasText(data.getBackFlushPart())) { + data.setBackFlushPart("All Locations"); + } + if (!StringUtils.hasText(data.getIssueType())) { + data.setIssueType("Reserve And Backflush"); + } + if (!StringUtils.hasText(data.getMrpControlFlagDb())) { + data.setMrpControlFlagDb("Y"); + } + + // RoHS创建IFS料号:直接创建正式物料 + data.setStatus("Y"); + data.setTemporaryPartFlag("N"); + data.setShowInQueryFlag("Y"); + data.setPlmPartNo(data.getPartNo()); + data.setIfsPartNo(data.getPartNo()); + if (data.getPartItemList() == null) { + data.setPartItemList(new ArrayList<>()); + } + + // 根据单位校验密度 + UmInformationEntity um = umInformationMapper.selectOne(new QueryWrapper().eq("um_id", data.getUmId())); + if (data.getDensity() != null && um != null && !("Weight".equals(um.getUmType()) || "Volume".equals(um.getUmType()))) { + throw new RuntimeException("单位类型为 Weight 或者 Volume 时才可设置密度!"); + } + + // master part:仅在不存在时新增,已存在则不修改 + MasterPartInformationEntity masterSyncData = new MasterPartInformationEntity(); + masterSyncData.setPartNo(data.getPartNo()); + masterSyncData.setPartDesc(data.getPartDesc()); + masterSyncData.setUmId(data.getUmId()); + masterSyncData.setPlmPartNo(data.getPartNo()); + masterSyncData.setOfficialFlag("Y"); + masterSyncData.setLotTrackingCode("Order Based"); + masterSyncData.setLotQuantityRule("Many Lots Per Production Order"); + masterSyncData.setSubLotRule("No Sub Lots Allowed"); + masterSyncData.setComponentLotRule("Many Lots Allowed"); + + boolean masterPartCreated = false; + MasterPartInformationEntity existsMasterPart = masterPartInformationMapper.selectOne(new QueryWrapper() + .eq("part_no", data.getPartNo())); + if (existsMasterPart == null) { + masterSyncData.setCreateBy(data.getCreateBy()); + masterPartInformationMapper.insert(masterSyncData); + masterPartCreated = true; + } + + // 新增part主数据 + partInformationMapper.insert(data); + + // 物料属性(无From Part场景默认可为空) + if (!data.getPartItemList().isEmpty()) { + savePartItemInfo(data); + } + + // 创建默认revision + PartRevisionEntity partRevision = new PartRevisionEntity(); + partRevision.setSite(data.getSite()); + partRevision.setPartNo(data.getPartNo()); + partRevision.setEngChgLevel(1); + partRevision.setEffPhaseInDate(data.getCreateDate()); + partRevision.setProductStatus("Not In Effect"); + partRevision.setRepairStatus("Not In Effect"); + partRevision.setCreateBy(data.getUpdateBy()); + partRevision.setEngRevision("1"); + partInformationMapper.saveRevision(partRevision); + + // 创建默认BOM/Routing(与copyPart2一致) + BomHeaderEntity bomHeader = new BomHeaderEntity(); + bomHeader.setSite(data.getSite()); + bomHeader.setPartNo(data.getPartNo()); + if (data.getPartType().contains("Manufactured")) { + bomHeader.setBomType("Manufacturing"); + } else if ("Purchased".equals(data.getPartType())) { + bomHeader.setBomType("Purchase"); + } + bomHeader.setEffPhaseInDate(data.getCreateDate()); + bomHeader.setEngRevision(partRevision.getEngRevision()); + bomHeader.setEngChgLevel(1); + bomHeader.setOfficialFlag("Y"); + if (!"Purchased (raw)".equals(data.getPartType())) { + if ("Manufactured Recipe".equals(data.getPartType())) { + savePartRecipeInfo(bomHeader, "copy2"); + } else { + savePartBomInfo(bomHeader, "copy2"); + } + if (data.getPartType().contains("Manufactured")) { + savePartRoutingInfo(data, "copy2"); + } + } + + // 同步物料件(Master Part):仅新增场景执行 + if (masterPartCreated) { + syncOfficialMasterPartForRohs(masterSyncData, data.getSite(), data.getUpdateBy()); + } + + // 同步库存件(Inventory Part) + Server srv = getIfsServer(data.getUpdateBy()); + PartIfsInventory partIfsInventory = getPartIfsInventory(data); + try { + if (dataUrl) { + PartIfsInventoryConfig partIfsInventoryConfig = getPartIfsInventoryConfig(data); + PartIfsInventoryManufacture partIfsInventoryManufacture = getPartIfsInventoryManufacture(data); + PartIfsInventoryPlan partIfsInventoryPlan = getPartIfsInventoryPlan(data); + List propertyList = partInformationMapper.getPartPropertyList(data.getSite(), data.getPartNo(), data.getCodeNo(), "IP"); + + Map getInventoryPartResponse = inventoryServiceBean.getInventoryPart(srv, partIfsInventory); + if (!"200".equals(getInventoryPartResponse.get("resultCode"))) { + Map addInventoryPartResponse = inventoryServiceBean.syncInventoryPart(srv, partIfsInventory); + if (!"200".equals(addInventoryPartResponse.get("resultCode"))) { + throw new RuntimeException("IFS库存件新增异常:" + addInventoryPartResponse.get("resultMsg")); + } + } else { + Map updateInventoryPartResponse = inventoryServiceBean.modifyInventoryPart(srv, partIfsInventory); + if (!"200".equals(updateInventoryPartResponse.get("resultCode"))) { + throw new RuntimeException("IFS库存件修改异常:" + updateInventoryPartResponse.get("resultMsg")); + } + } + + Map addInventoryPartCostsResponse = inventoryServiceBean.modifyInventoryPartCost(srv, partIfsInventoryConfig); + if (!"200".equals(addInventoryPartCostsResponse.get("resultCode"))) { + throw new RuntimeException("IFS库存件Costs修改异常:" + addInventoryPartCostsResponse.get("resultMsg")); + } + + Map addInventoryPartManufacturingResponse = inventoryServiceBean.modifyInventoryPartManufacture(srv, partIfsInventoryManufacture); + if (!"200".equals(addInventoryPartManufacturingResponse.get("resultCode"))) { + throw new RuntimeException("IFS库存件Manufacturing修改异常:" + addInventoryPartManufacturingResponse.get("resultMsg")); + } + + Map addInventoryPartPlanningResponse = inventoryServiceBean.modifyInventoryPartPlan(srv, partIfsInventoryPlan); + if (!"200".equals(addInventoryPartPlanningResponse.get("resultCode"))) { + throw new RuntimeException("IFS库存件Planning修改异常:" + addInventoryPartPlanningResponse.get("resultMsg")); + } + + if (!propertyList.isEmpty()) { + Map addInventoryPartPropertyResponse = inventoryServiceBean.syncInventoryPartCharacteristics(srv, propertyList); + if (!"200".equals(addInventoryPartPropertyResponse.get("resultCode"))) { + throw new RuntimeException("IFS库存件属性新增异常:" + addInventoryPartPropertyResponse.get("resultMsg")); + } + } + + if (!"Purchased (raw)".equals(data.getPartType())) { + BomIfsHeader bomIfsHeader = new BomIfsHeader(); + bomIfsHeader.setContract(data.getSite()); + bomIfsHeader.setPartNo(data.getPartNo()); + bomIfsHeader.setEngChgLevel("1"); + bomIfsHeader.setBomType(bomHeader.getBomType()); + bomIfsHeader.setEffPhaseInDate(DateUtils.format(bomHeader.getEffPhaseInDate())); + bomIfsHeader.setEffPhaseOutDate(bomHeader.getEffPhaseOutDate() == null ? "" : DateUtils.format(bomHeader.getEffPhaseOutDate())); + if ("Manufactured Recipe".equals(data.getPartType())) { + RecipeIfsHeader recipeIfsHeader = new RecipeIfsHeader(); + BeanUtils.copyProperties(bomIfsHeader, recipeIfsHeader); + Map getRecipeHeaderResponse = recipeServiceBean.getRecipeHeader(srv, recipeIfsHeader); + if (!"200".equals(getRecipeHeaderResponse.get("resultCode"))) { + Map addRecipeHeaderResponse = recipeServiceBean.syncRecipeHeader(srv, recipeIfsHeader); + if (!"200".equals(addRecipeHeaderResponse.get("resultCode"))) { + throw new RuntimeException("IFS RecipeHeader新增异常:" + addRecipeHeaderResponse.get("resultMsg")); + } + } else { + Map updateRecipeHeaderResponse = recipeServiceBean.modifyRecipeHeader(srv, recipeIfsHeader); + if (!"200".equals(updateRecipeHeaderResponse.get("resultCode"))) { + throw new RuntimeException("IFS RecipeHeader修改异常:" + updateRecipeHeaderResponse.get("resultMsg")); + } + } + } else { + Map getBomHeaderResponse = bomServiceBean.getBomHeader(srv, bomIfsHeader); + if (!"200".equals(getBomHeaderResponse.get("resultCode"))) { + Map addBomHeaderResponse = bomServiceBean.syncBomHeader(srv, bomIfsHeader); + if (!"200".equals(addBomHeaderResponse.get("resultCode"))) { + throw new RuntimeException("IFS BOMHeader新增异常:" + addBomHeaderResponse.get("resultMsg")); + } + } else { + Map updateBomHeaderResponse = bomServiceBean.modifyBomHeader(srv, bomIfsHeader); + if (!"200".equals(updateBomHeaderResponse.get("resultCode"))) { + throw new RuntimeException("IFS BOMHeader修改异常:" + updateBomHeaderResponse.get("resultMsg")); + } + } + } + + if (data.getPartType().contains("Manufactured")) { + RoutingIfsHeader routingIfsHeader = new RoutingIfsHeader(); + routingIfsHeader.setContract(data.getSite()); + routingIfsHeader.setPartNo(data.getPartNo()); + routingIfsHeader.setRoutingRevision("1"); + routingIfsHeader.setRoutingType("Manufacturing"); + routingIfsHeader.setPhaseInDate(DateUtils.format(data.getCreateDate())); + Map getRoutingHeaderResponse = routingServiceBean.getRoutingHeader(srv, routingIfsHeader); + if (!"200".equals(getRoutingHeaderResponse.get("resultCode"))) { + Map addRoutingHeaderResponse = routingServiceBean.syncRoutingHeader(srv, routingIfsHeader); + if (!"200".equals(addRoutingHeaderResponse.get("resultCode"))) { + throw new RuntimeException("IFS RoutingHeader新增异常:" + addRoutingHeaderResponse.get("resultMsg")); + } + } else { + Map updateRoutingHeaderResponse = routingServiceBean.modifyRoutingHeader(srv, routingIfsHeader); + if (!"200".equals(updateRoutingHeaderResponse.get("resultCode"))) { + throw new RuntimeException("IFS RoutingHeader修改异常:" + updateRoutingHeaderResponse.get("resultMsg")); + } + } + } + } + + Map modifyCommGroup3Response = inventoryServiceBean.modifyInventoryPartCommGroup3(srv, partIfsInventory); + if (!"200".equals(modifyCommGroup3Response.get("resultCode"))) { + throw new RuntimeException("IFS库存件CommGroup3修改异常:" + modifyCommGroup3Response.get("resultMsg")); + } + } + } catch (Exception e) { + Map deleteInventoryPartResponse = inventoryServiceBean.removeInventoryPartRelationInfo(srv, partIfsInventory); + if (!"200".equals(deleteInventoryPartResponse.get("resultCode"))) { + throw new RuntimeException(e.getMessage() + "; IFS删除库存件关联信息异常:" + deleteInventoryPartResponse.get("resultMsg")); + } + throw new RuntimeException(e.getMessage()); + } + } + + private void syncOfficialMasterPartForRohs(MasterPartInformationEntity masterPart, String site, String updateBy) { + if (!dataUrl) { + return; + } + SysUserEntity ifsUser = sysUserDao.selectOne(new QueryWrapper().eq("username", updateBy)); + if (ifsUser == null || !org.apache.commons.lang3.StringUtils.isNotBlank(ifsUser.getIfsUsername()) || !org.apache.commons.lang3.StringUtils.isNotBlank(ifsUser.getIfsPassword())) { + throw new RuntimeException("请维护IFS账号和密码!"); + } + Server srv = ifsServer.getIfsServer(ifsUser.getIfsUsername(), ifsUser.getIfsPassword()); + PartIfsCatalog partIfsCatalog = getPartIfsCatalog(masterPart); + + Map queryResponse = masterServiceBean.getMasterPart(srv, partIfsCatalog); + if ("200".equals(queryResponse.get("resultCode"))) { + return; + } + + Map addResponse = masterServiceBean.syncPartCatalog(srv, partIfsCatalog); + if (!"200".equals(addResponse.get("resultCode"))) { + throw new RuntimeException("IFS物料件新增异常:" + addResponse.get("resultMsg")); + } + if (org.apache.commons.lang3.StringUtils.isNotBlank(masterPart.getCodeNo())) { + PartIfsCatalogModel partIfsCatalogModel = new PartIfsCatalogModel(); + partIfsCatalogModel.setLuName(luName); + partIfsCatalogModel.setKeyRef("PART_NO=" + masterPart.getPartNo() + "^"); + partIfsCatalogModel.setTechnicalSpecNo(technicalSpecNo); + partIfsCatalogModel.setTechnicalClass(masterPart.getCodeNo()); + partIfsCatalogModel.setOkYesNo(okYesNo); + partIfsCatalogModel.setOkSign(ifsUser.getIfsUsername()); + partIfsCatalogModel.setDtOk(DateUtils.getStringNow2()); + Map addMasterPartModelResponse = technicalClassBean.syncTechnicalClass(srv, partIfsCatalogModel); + if (!"200".equals(addMasterPartModelResponse.get("resultCode"))) { + throw new RuntimeException("IFS 物料件模板新增异常:" + addMasterPartModelResponse.get("resultMsg")); + } + } + + if (org.apache.commons.lang3.StringUtils.isNotBlank(masterPart.getCodeNo())) { + List propertyList = partInformationMapper.getMasterPartPropertyList(site, masterPart.getPartNo(), masterPart.getCodeNo(), "MP"); + if (!propertyList.isEmpty()) { + Map addMasterPartPropertyResponse = technicalClassBean.modifyTechnicalClassAttributes(srv, propertyList); + if (!"200".equals(addMasterPartPropertyResponse.get("resultCode"))) { + throw new RuntimeException("IFS 物料件属性编辑异常:" + addMasterPartPropertyResponse.get("resultMsg")); + } + } + } + } + /** * 下一个物料编码 * @param data diff --git a/src/main/resources/mapper/rohs/RohsMapper.xml b/src/main/resources/mapper/rohs/RohsMapper.xml index 174cede4..ece2e675 100644 --- a/src/main/resources/mapper/rohs/RohsMapper.xml +++ b/src/main/resources/mapper/rohs/RohsMapper.xml @@ -113,7 +113,7 @@ dbo.plm_get_project_name(a.site, a.project_id) as projectName, dbo.get_product_group_name(a.site, a.comm_group1, '1') as commGroup1Desc, dbo.get_product_group_name(a.site, a.comm_group2, '2') as commGroup2Desc, - dbo.get_product_group_name(a.site, a.comm_group3, '3') as commGroup3Desc + dbo.get_product_group_name(a.site, a.comm_group3, '5') as commGroup3Desc from plm_rohs a left join plm_request_header prh on a.site = prh.site and prh.menu_id = #{params.menuId} and prh.status = 'Y' left join plm_request_node d on a.site = d.site and prh.classification_no = d.classification_no and prh.workflow_id = d.workflow_id and a.step_id = d.step_id @@ -157,7 +157,7 @@ dbo.plm_get_project_name(a.site, a.project_id) as projectName, dbo.get_product_group_name(a.site, a.comm_group1, '1') as commGroup1Desc, dbo.get_product_group_name(a.site, a.comm_group2, '2') as commGroup2Desc, - dbo.get_product_group_name(a.site, a.comm_group3, '3') as commGroup3Desc + dbo.get_product_group_name(a.site, a.comm_group3, '5') as commGroup3Desc from plm_rohs a left join plm_request_header prh on a.site = prh.site and prh.menu_id = #{params.menuId} and prh.status = 'Y' left join plm_request_node d on a.site = d.site and prh.classification_no = d.classification_no and prh.workflow_id = d.workflow_id and a.step_id = d.step_id @@ -184,7 +184,7 @@ dbo.plm_get_project_name(a.site, a.project_id) as projectName, dbo.get_product_group_name(a.site, a.comm_group1, '1') as commGroup1Desc, dbo.get_product_group_name(a.site, a.comm_group2, '2') as commGroup2Desc, - dbo.get_product_group_name(a.site, a.comm_group3, '3') as commGroup3Desc + dbo.get_product_group_name(a.site, a.comm_group3, '5') as commGroup3Desc from plm_rohs a where a.site = #{site} and a.reference_no = #{referenceNo}