diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/api/user/PBomApi.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/api/user/PBomApi.java index 78260c37..d9067d89 100644 --- a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/api/user/PBomApi.java +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/api/user/PBomApi.java @@ -14,6 +14,7 @@ import com.nflg.product.bomnew.pojo.dto.sap.impart2.ImportSapParamDTO; import com.nflg.product.bomnew.pojo.entity.BomNewPbomParentEntity; import com.nflg.product.bomnew.pojo.entity.BomNewTechnologyPackageTypeEntity; import com.nflg.product.bomnew.pojo.query.BomNewPbomParentQuery; +import com.nflg.product.bomnew.pojo.query.PbomImportToSAPQuery; import com.nflg.product.bomnew.pojo.vo.*; import com.nflg.product.bomnew.service.*; import com.nflg.product.bomnew.util.EecExcelUtil; @@ -26,7 +27,7 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; -import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -335,8 +336,7 @@ public class PBomApi extends BaseApi { */ @PostMapping("importToSAP") @ApiOperation("导入到SAP") - public ResultVO> importToSAP(@Valid @RequestBody @NotEmpty List rootBomRowIds) { - VUtils.isTure(rootBomRowIds.size() > 1).throwMessage("每次只能导入1条"); - return bomNewPbomParentService.importToSAP(rootBomRowIds.get(0)); + public ResultVO> importToSAP(@Valid @RequestBody @NotNull PbomImportToSAPQuery query) { + return ResultVO.success(bomNewPbomParentService.importToSAP2(query)); } } diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/query/PbomImportToSAPQuery.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/query/PbomImportToSAPQuery.java new file mode 100644 index 00000000..fedfb038 --- /dev/null +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/query/PbomImportToSAPQuery.java @@ -0,0 +1,32 @@ +package com.nflg.product.bomnew.pojo.query; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * @author 曹鹏飞 + * @date 2024/5/14 09:25:14 + */ +@Data +@Accessors(chain = true) +@ApiModel(value = "com-nflg-product-bomnew-pojo-new-query-PbomImportToSAPQuery") +public class PbomImportToSAPQuery implements Serializable { + + /** + * 根节点bom行id + */ + @ApiModelProperty(value = "根节点bom行id", required = true) + @NotNull + private Long rootBomRowId; + + /** + * 是否是 一次性订单/配件销售订单。仅对21码生效 + */ + @ApiModelProperty(value = "是否是 一次性订单/配件销售订单") + private Boolean isForSale = false; +} diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/BomNewPbomExportToSAPImpl.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/BomNewPbomExportToSAPImpl.java new file mode 100644 index 00000000..6c30fb30 --- /dev/null +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/BomNewPbomExportToSAPImpl.java @@ -0,0 +1,210 @@ +package com.nflg.product.bomnew.service; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.spring.SpringUtil; +import com.nflg.product.bomnew.constant.BomConstant; +import com.nflg.product.bomnew.constant.PBomStatusEnum; +import com.nflg.product.bomnew.constant.SapStatusEnum; +import com.nflg.product.bomnew.constant.VirtualPackageTypeEnum; +import com.nflg.product.bomnew.pojo.dto.sap.impart2.ImportSapParamDTO; +import com.nflg.product.bomnew.pojo.dto.sap.impart2.T1DTO; +import com.nflg.product.bomnew.pojo.entity.BomNewPbomChildEntity; +import com.nflg.product.bomnew.pojo.entity.BomNewPbomParentEntity; +import com.nflg.product.bomnew.pojo.vo.OperationErrorMsgVO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author 曹鹏飞 + * @date 2024/5/14 09:20:15 + */ +public class BomNewPbomExportToSAPImpl implements IBomNewPbomExportToSAP { + + private final static String TAG = "导入31物料到SAP"; + + //是否是 一次性订单/配件销售订单 + private boolean isForSale = false; + private boolean is21 = false; + + private final String dateYMD = DateUtil.format(new Date(), "yyyyMMdd"); + private final Map> cmap = new HashMap<>(); + private final List children = new ArrayList<>(); + + private final static Logger LOGGER = LoggerFactory.getLogger(BomNewPbomExportToSAPImpl.class); + + private final BomNewPbomParentService bomNewPbomParentService = SpringUtil.getBean(BomNewPbomParentService.class); + private final BomNewPbomChildService bomNewPbomChildService = SpringUtil.getBean(BomNewPbomChildService.class); + + public BomNewPbomExportToSAPImpl(boolean isForSale) { + this.isForSale = isForSale; + } + + @Override + public List export(Long rootBomRowId) { + BomNewPbomParentEntity root = bomNewPbomParentService.getById(rootBomRowId); + is21 = root.getMaterialNo().startsWith("21"); + List rcs = bomNewPbomChildService.lambdaQuery() + .eq(BomNewPbomChildEntity::getParentRowId, rootBomRowId) + .list(); + List unVirtualParts = rcs.stream() + .filter(c -> Objects.equals(c.getVirtualPartType(), VirtualPackageTypeEnum.UN_VIRTUAL_PACKAGE.getValue())) + .collect(Collectors.toList()); + if (CollUtil.isNotEmpty(unVirtualParts)) { + return unVirtualParts.stream().map(c -> OperationErrorMsgVO.create(c.getMaterialNo(), "未生成发货包")).collect(Collectors.toList()); + } + children.addAll(convert(rcs, root.getMaterialNo())); + rcs.forEach(it -> { + List cps = getParents(it); + cps.forEach(pt -> { + List cpsc = getChildren(pt); + children.addAll(convert(cpsc, pt.getMaterialNo())); + cpsc.forEach(cptt -> { + if (Objects.equals(cptt.getVirtualPartType(), VirtualPackageTypeEnum.DELIVERY_PACKAGE.getValue())) { + //选出发货包 + cmap.put(cptt.getRowId(), new ArrayList<>()); + LOGGER.debug("{} 发货包 rowId:{},编号:{},描述:{}", TAG, cptt.getRowId(), cptt.getMaterialNo(), cptt.getMaterialDesc()); + } + List cpsfp = getParents(cptt); + cpsfp.forEach(ewfce -> { + buildChildrenForSap(Objects.equals(cptt.getVirtualPartType(), VirtualPackageTypeEnum.DELIVERY_PACKAGE.getValue()) ? cptt.getRowId() : null, ewfce, it); + }); + }); + }); + }); + ImportSapParamDTO sapDto = new ImportSapParamDTO(); + sapDto.setZID(RandomUtil.randomNumbers(5)); + sapDto.setI_WERKS("1"); + sapDto.setI_STLAN("1"); + sapDto.setI_EMPNO(root.getCreatedBy()); + sapDto.setT1(children); + SapStatusEnum state = SapStatusEnum.PUB_ERROR_ALL; + List liErrMsg = null; + try { + updateSapState(rootBomRowId, SapStatusEnum.PUB_RUNNING); + liErrMsg = SpringUtil.getBean(SapOpUtilService.class).importToSapV2(sapDto, null); + LOGGER.debug("本次导入到sap数量共{}个,其中{}个有错误", sapDto.getT1().size(), liErrMsg.size()); + if (CollUtil.isEmpty(liErrMsg)) { + state = SapStatusEnum.PUB_SAP; + } else if (sapDto.getT1().size() != liErrMsg.size()) { + state = SapStatusEnum.PUB_ERROR; + } + } finally { + updateSapState(rootBomRowId, state); + } + return liErrMsg; + } + + private void updateSapState(Long rootBomRowId, SapStatusEnum sapState) { + bomNewPbomParentService.lambdaUpdate() + .in(BomNewPbomParentEntity::getRowId, rootBomRowId) + .set(BomNewPbomParentEntity::getSapTime, LocalDateTime.now()) + .set(BomNewPbomParentEntity::getSapState, sapState.getValue()) + .update(); + } + + private T1DTO convert(BomNewPbomChildEntity child, String parentMaterialNo) { + T1DTO t = new T1DTO(); + t.setID(RandomUtil.randomNumbers(5)); + t.setMATNR(parentMaterialNo); + t.setMENGE(child.getNum().toString()); + t.setPOSTP(child.getProjectType()); + t.setDATUM(dateYMD); + t.setMEINS(child.getMaterialUnit()); + if (BomConstant.PROJECT_TYPE_TEMPORARY.equals(child.getProjectType())) { + t.setIDNRK(""); + t.setPOTX1(child.getMaterialDesc()); + } else { + t.setIDNRK(child.getMaterialNo()); + // BaseMaterialVO bm = materialBaseInfos.stream().filter(m -> m.getMaterialNo().equals(d.getMaterialNo())).findFirst().orElse(null); + // if (!Objects.isNull(bm)) { + // t1.setMEINS(bm.getMaterialUnit()); + // } + } + return t; + } + + private List convert(List children, String parentMaterialNo) { + return children.stream().map(c -> convert(c, parentMaterialNo)).collect(Collectors.toList()); + } + + /** + * 构建child数据 + * @param cRowId 当前的发货包rowId + * @param p parent + * @param c 父级节点的child + * @return + */ + private void buildChildrenForSap(Long cRowId, BomNewPbomParentEntity p, BomNewPbomChildEntity c) { + List cc = getChildren(p); + for (BomNewPbomChildEntity it : cc) { + if (is21 && !isForSale && !Objects.equals(it.getVirtualPartType(), VirtualPackageTypeEnum.UN_VIRTUAL_PACKAGE.getValue())) { + return; + } + if (Objects.equals(it.getVirtualPartType(), VirtualPackageTypeEnum.UN_VIRTUAL_PACKAGE.getValue())) { + if (Objects.equals(c.getVirtualPartType(), VirtualPackageTypeEnum.DELIVERY_PACKAGE.getValue())) { + if (Objects.isNull(cRowId)) { + LOGGER.debug("{} 添加物料 编号:{},父级编号:{},数量:{},描述:{}", TAG, it.getMaterialNo(), c.getMaterialNo(), it.getNum().toString(), it.getMaterialDesc()); + children.add(convert(it, c.getMaterialNo())); + } else { + T1DTO cct = cmap.get(cRowId).stream() + .filter(ct -> (StrUtil.equals(ct.getPOSTP(), BomConstant.PROJECT_TYPE_TEMPORARY, true) && StrUtil.equals(ct.getPOTX1(), it.getMaterialDesc())) + || (!StrUtil.equals(ct.getPOSTP(), BomConstant.PROJECT_TYPE_TEMPORARY, true) && StrUtil.equals(ct.getIDNRK(), it.getMaterialNo()))) + .findFirst() + .orElse(null); + if (Objects.isNull(cct)) { + LOGGER.debug("{} 物料提层到顶级发货包 编号:{},父级编号:{},数量:{},描述:{}", TAG, it.getMaterialNo(), c.getMaterialNo(), it.getNum().toString(), it.getMaterialDesc()); + cct = convert(it, c.getMaterialNo()); + cmap.get(cRowId).add(cct); + children.add(cct); + } else { + //合并计算数量 + cct.setMENGE(new BigDecimal(cct.getMENGE()).add(it.getNum()).toString()); + LOGGER.debug("{} 物料提层到顶级发货包且合并 编号:{},父级编号:{},数量:{},合并后总数:{},描述:{}", TAG, it.getMaterialNo(), c.getMaterialNo(), it.getNum().toString(), cct.getMENGE(), it.getMaterialDesc()); + } + } + } else { + LOGGER.debug("{} 添加物料 编号:{},父级编号:{},数量:{},描述:{}", TAG, it.getMaterialNo(), c.getMaterialNo(), it.getNum().toString(), it.getMaterialDesc()); + children.add(convert(it, c.getMaterialNo())); + } + } + List cp = getParents(it); + cp.forEach(cpt -> { + buildChildrenForSap(cRowId, cpt, it); + }); + } + } + + private List getChildren(BomNewPbomParentEntity parent) { + return bomNewPbomChildService.lambdaQuery() + .eq(BomNewPbomChildEntity::getParentRowId, parent.getRowId()) + .list(); + } + + private List getParents(BomNewPbomChildEntity child) { + return bomNewPbomParentService.lambdaQuery() + .eq(BomNewPbomParentEntity::getMaterialNo, child.getMaterialNo()) + .eq(BomNewPbomParentEntity::getStatus, PBomStatusEnum.PUBLISH.getValue()) + .list(); + } + + // private List getChildren(List parents) { + // return bomNewPbomChildService.lambdaQuery() + // .in(BomNewPbomChildEntity::getParentRowId, parents.stream().map(BomNewPbomParentEntity::getRowId).collect(Collectors.toSet())) + // .list(); + // } + + // private List getParents(List children) { + // return bomNewPbomParentService.lambdaQuery() + // .in(BomNewPbomParentEntity::getMaterialNo, children.stream().map(BomNewPbomChildEntity::getMaterialNo).collect(Collectors.toSet())) + // .eq(BomNewPbomParentEntity::getStatus, PBomStatusEnum.PUBLISH.getValue()) + // .list(); + // } +} diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/BomNewPbomParentService.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/BomNewPbomParentService.java index c0735865..1b5b2ea1 100644 --- a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/BomNewPbomParentService.java +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/BomNewPbomParentService.java @@ -25,6 +25,7 @@ import com.nflg.product.bomnew.pojo.dto.sap.impart2.ImportSapParamDTO; import com.nflg.product.bomnew.pojo.dto.sap.impart2.T1DTO; import com.nflg.product.bomnew.pojo.entity.*; import com.nflg.product.bomnew.pojo.query.BomNewPbomParentQuery; +import com.nflg.product.bomnew.pojo.query.PbomImportToSAPQuery; import com.nflg.product.bomnew.pojo.vo.*; import com.nflg.product.bomnew.service.domain.PBom.*; import com.nflg.product.bomnew.service.domain.Sap; @@ -1115,7 +1116,7 @@ public class BomNewPbomParentService extends ServiceImpl liErrMsg = null; + List liErrMsg; try { updateSapState(rootRowId, SapStatusEnum.PUB_RUNNING); liErrMsg = SpringUtil.getBean(SapOpUtilService.class).importToSapV2(sapDto, null); @@ -1167,4 +1168,21 @@ public class BomNewPbomParentService extends ServiceImpl importToSAP2(PbomImportToSAPQuery query) { + BomNewPbomParentEntity root = getById(query.getRootBomRowId()); + VUtils.isTure(Objects.isNull(root)).throwMessage("数据不存在"); + VUtils.isTure(root.getRootIs() != 1).throwMessage("请选择根节点"); + + // IBomNewPbomExportToSAP service; + // if (root.getMaterialNo().startsWith("31")) { + // service = new BomNewPbomExportToSAP31(); + // } else if (root.getMaterialNo().startsWith("21")) { + // service = new BomNewPbomExportToSAP21(query.getIsForSale()); + // } else { + // throw new NflgBusinessException(STATE.BusinessError, "不复核要求的物料:" + root.getMaterialNo()); + // } + IBomNewPbomExportToSAP service = new BomNewPbomExportToSAPImpl(query.getIsForSale()); + return service.export(root.getRowId()); + } } diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/IBomNewPbomExportToSAP.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/IBomNewPbomExportToSAP.java new file mode 100644 index 00000000..8d2ad928 --- /dev/null +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/IBomNewPbomExportToSAP.java @@ -0,0 +1,25 @@ +package com.nflg.product.bomnew.service; + +import com.nflg.product.bomnew.pojo.vo.OperationErrorMsgVO; + +import java.util.List; + +/** + * @author 曹鹏飞 + * @date 2024/5/14 09:18:57 + */ +public interface IBomNewPbomExportToSAP { + + // //顶层发货包和其子级 + // Map> cmap = new HashMap<>(); + // + // BomNewPbomParentService bomNewPbomParentService = SpringUtil.getBean(BomNewPbomParentService.class); + // + // BomNewPbomChildService bomNewPbomChildService = SpringUtil.getBean(BomNewPbomChildService.class); + // + // List children = new ArrayList<>(); + // + // String dateYMD = DateUtil.format(new Date(), "yyyyMMdd"); + + List export(Long rootBomRowId); +}