diff --git a/nflg_project_dev/material/src/main/java/com/nflg/product/material/service/MaterialUpdateBillService.java b/nflg_project_dev/material/src/main/java/com/nflg/product/material/service/MaterialUpdateBillService.java index d8b1b9ca..edb51f67 100644 --- a/nflg_project_dev/material/src/main/java/com/nflg/product/material/service/MaterialUpdateBillService.java +++ b/nflg_project_dev/material/src/main/java/com/nflg/product/material/service/MaterialUpdateBillService.java @@ -700,9 +700,9 @@ public class MaterialUpdateBillService extends ServiceImpl drawingNoList = excelContext.stream().map(TwentyMaterialTemplateExcelDTO::getDrawingNo).collect(Collectors.toList()); List entityList = this.materialMainService.lambdaQuery().in(MaterialMainEntity::getDrawingNo, drawingNoList).list(); if (entityList != null && entityList.size() > 0) { - List drawingNos = entityList.stream().map(MaterialMainEntity::getDrawingNo).collect(Collectors.toList()); List others = entityList.stream().filter(item -> !upMaterialNos.contains(item.getMaterialNo())).collect(Collectors.toList()); if (others.size() > 0) { + List drawingNos = others.stream().map(MaterialMainEntity::getDrawingNo).collect(Collectors.toList()); throw new NflgBusinessException(STATE.ParamErr, StrUtil.join(",", drawingNos).concat("的图号在正式物料中已存在")); } } diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/api/user/BatchBomApi.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/api/user/BatchBomApi.java new file mode 100644 index 00000000..dbfca896 --- /dev/null +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/api/user/BatchBomApi.java @@ -0,0 +1,101 @@ +package com.nflg.product.bomnew.api.user; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.nflg.product.base.core.api.BaseApi; +import com.nflg.product.bomnew.pojo.query.BatchBomQuery; +import com.nflg.product.bomnew.pojo.query.PbomImportToSAPQuery; +import com.nflg.product.bomnew.pojo.vo.*; +import com.nflg.product.bomnew.service.BatchBomService; +import com.nflg.product.bomnew.service.BomNewEbomExportToSAP; +import com.nflg.product.bomnew.service.BomNewPbomParentService; +import com.nflg.product.bomnew.service.MaterialMainService; +import com.nflg.product.bomnew.util.EecExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import nflg.product.common.vo.ResultVO; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.io.IOException; +import java.util.*; + +/** + * 批量替代BOM + * + * @author makejava + */ +@Api(tags = "批量替代BOM接口") +@RestController +@RequestMapping("bom/new/batchBom") +public class BatchBomApi extends BaseApi { + + @Resource + private MaterialMainService materialMainService; + @Resource + private BatchBomService batchBomService; + @Resource + private BomNewPbomParentService bomNewPbomParentService; + + @GetMapping("getMaterialInfo") + @ApiOperation("查询物料信息") + public ResultVO getMaterialInfo(@RequestParam String materialNo) { + if (ObjectUtil.isEmpty(materialNo)) { + return ResultVO.error("物料编码不能为空"); + } + List materialBaseInfo = materialMainService.getMaterialBaseInfo(Collections.singletonList(materialNo)); + if (CollectionUtil.isEmpty(materialBaseInfo)) { + return ResultVO.error("物料编码不存在"); + } + return ResultVO.success(materialBaseInfo.get(0)); + } + + @PostMapping("getParentBomList") + @ApiOperation("获取指定物料号的所有父级BOM列表") + public ResultVO, BomTbHeaderVO>> getParentBomList(@Valid @RequestBody @NotNull BatchBomQuery batchBomQuery) { + return ResultVO.success(batchBomService.getParentBomList(batchBomQuery)); + } + + @PostMapping("updateEBom") + @ApiOperation("更新EBOM并导入SAP") + public ResultVO> updateEBom(@RequestBody List baseBomVOList) { + List addRowIds = batchBomService.updateEBom(baseBomVOList); + List errorMsgVOS = new ArrayList<>(); + // 导入SAP + if (CollUtil.isNotEmpty(addRowIds)) { + addRowIds.forEach(rootRowId -> { + BomNewEbomExportToSAP exportToSAP = new BomNewEbomExportToSAP(); + errorMsgVOS.addAll(exportToSAP.export(rootRowId)); + }); + } + return ResultVO.success(errorMsgVOS); + } + + @PostMapping("updatePBom") + @ApiOperation("更新PBOM并导入SAP") + public ResultVO> updatePBom(@RequestBody List baseBomVOList) { + List addRowIds = batchBomService.updatePBom(baseBomVOList); + List errorMsgVOS = new ArrayList<>(); + // 导入SAP + if (CollUtil.isNotEmpty(addRowIds)) { + addRowIds.forEach(rootRowId -> { + PbomImportToSAPQuery query = new PbomImportToSAPQuery(); + query.setRootBomRowId(rootRowId); + query.setIsForSale(false); + errorMsgVOS.addAll(bomNewPbomParentService.importToSAP2(query)); + }); + } + return ResultVO.success(errorMsgVOS); + } + + @PostMapping("exportExcel") + @ApiOperation("数据导出") + public void exportExcel(@RequestBody BatchBomQuery query, HttpServletResponse response) throws IOException { + EecExcelUtil.setResponseExcelHeader(response, "批量替代" + query.getMaterialNo() + "_" + new Date().getTime()); + batchBomService.getExportExcelWork(query).writeTo(response.getOutputStream()); + } +} diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/constant/DateTypeEnum.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/constant/DateTypeEnum.java new file mode 100644 index 00000000..a5abd2ed --- /dev/null +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/constant/DateTypeEnum.java @@ -0,0 +1,23 @@ +package com.nflg.product.bomnew.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 物料创建时间,1=7天,2=30天,3=90天,4=一段时间 + * @decription + * @Author LYK + * @Date 2022/9/2 10:15 + **/ +@Getter +@AllArgsConstructor +public enum DateTypeEnum { + ZERO(0,"全部"), + SEVEN(1,"7天"), + THIRTY(2,"30天"), + NINETY(3,"90天"), + LONGDATE(4,"一段时间"); + + private final Integer code; + private final String msg; +} diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/query/BatchBomQuery.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/query/BatchBomQuery.java new file mode 100644 index 00000000..b1344768 --- /dev/null +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/query/BatchBomQuery.java @@ -0,0 +1,62 @@ +package com.nflg.product.bomnew.pojo.query; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.math.BigDecimal; + +@Data +public class BatchBomQuery implements Serializable { + + @ApiModelProperty(value = "原物料号") + @NotNull + private String materialNo; + + @ApiModelProperty(value = "新物料号") + @NotNull + private String newMaterialNo; + + @ApiModelProperty(value = "原物料单位") + @NotNull + private String materialUnit; + + @ApiModelProperty(value = "新物料单位") + @NotNull + private String newMaterialUnit; + + @ApiModelProperty(value = "换算前") +// @NotNull + private BigDecimal replaceTimes; + + @ApiModelProperty(value = "换算后") +// @NotNull + private BigDecimal newReplaceTimes; + + @ApiModelProperty(value = "新数量小数位") +// @NotNull + private Integer decimalScale; + + @ApiModelProperty(value = "BOM类型") + @NotNull + private String bomType; + + @ApiModelProperty(value = "工厂") + private String factory; + + @ApiModelProperty(value = "日期类型") + private Integer dateType; + + @ApiModelProperty("统计开始时间") + private String startDate; + + @ApiModelProperty("统计结束时间") + private String endDate; + + @ApiModelProperty(value = "设置每页显示条数") + private Long pageSize = 20L; + + @ApiModelProperty(value = "当前页") + private Long page = 1L; +} diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/vo/BaseBomVO.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/vo/BaseBomVO.java new file mode 100644 index 00000000..8e4442f4 --- /dev/null +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/vo/BaseBomVO.java @@ -0,0 +1,98 @@ +package com.nflg.product.bomnew.pojo.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Data +public class BaseBomVO { + + @ApiModelProperty("序号") + private Long orderNum; + + @ApiModelProperty("父级BOM ID") + private Long parentRowId; + + @ApiModelProperty("父级物料主数据行ID") + private Long parentMaterialRowId; + + @ApiModelProperty("父级物料编码") + private String parentMaterialNo; + + @ApiModelProperty("父级物料描述") + private String parentMaterialDesc; + + @ApiModelProperty("物料大类别") + private String relCategoryCode; + + @ApiModelProperty("物料类别代码") + private String categoryCode; + + @ApiModelProperty("物料类别") + private String categoryName; + + @ApiModelProperty("父级BOM版本号") + private String parentVersion; + + @ApiModelProperty("子级BOM ID") + private Long childRowId; + + @ApiModelProperty("原物料编码") + private String materialNo; + + @ApiModelProperty("原数量") + private BigDecimal num; + + @ApiModelProperty("原单位") + private String unit; + + @ApiModelProperty("新物料编码") + private String newMaterialNo; + + @ApiModelProperty("新数量") + private BigDecimal newNum; + + @ApiModelProperty("新单位") + private String newUnit; + + @ApiModelProperty("新版本号") + private String newVersion; + + /** + * 设计人员编码 + */ + @ApiModelProperty(value = "设计人员编码") + private String deviseUserCode; + + /** + * 设计人员名称 + */ + @ApiModelProperty(value = "设计人员名称") + private String deviseName; + + /** + * 创建人编码 + */ + @ApiModelProperty(value = "创建人编码") + private String createdBy; + + /** + * 创建时间 + */ + @ApiModelProperty(value = "创建时间") + private LocalDateTime createdTime; + + /** + * 版本过期时间 + */ + @ApiModelProperty(value = "版本过期时间") + private LocalDateTime expireEndTime; + + /** + * 工厂 + */ + @ApiModelProperty(value = "工厂") + private String factory; +} diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/vo/BomPageVO.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/vo/BomPageVO.java new file mode 100644 index 00000000..397bb161 --- /dev/null +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/vo/BomPageVO.java @@ -0,0 +1,69 @@ +package com.nflg.product.bomnew.pojo.vo; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.nflg.product.base.core.vo.PageVO; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +/** + * 分页带状态统计 + * + * @author + * @Date 2021/6/16 10:02 + */ +public class BomPageVO extends PageVO { + + @Getter + @Setter + private List tbHeaders; + + public BomPageVO() { + super(); + } + + public BomPageVO(long page, long pageSize) { + super(page, pageSize); + } + + public BomPageVO(long page, long pageSize, long total) { + super(page, pageSize, total); + } + + public BomPageVO(long current, long size, boolean isSearchCount) { + super(current, size, isSearchCount); + } + + public BomPageVO(long current, long size, long total, boolean isSearchCount) { + super(current, size, total, isSearchCount); + } + + /** + * 将 IPage 转换为 CountPageVO + * + * @param page 要转换的 IPage + * @param 数据类型 + * @return 转换后的 CountPageVO + */ + public static BomPageVO valueOf(IPage page) { + return BomPageVO.valueOf(page, page.getRecords()); + } + + /** + * 将 IPage 转换为 CountPageVO,并且切换新的数据集合 + * 应该保证原有的分页信息可以正确的应用在新的数据集合之中 + * + * @param page 要转换的 IPage + * @param records 数据集合 + * @param 数据类型 + * @return 转换后的 CountPageVO + */ + public static BomPageVO valueOf(IPage page, List records) { + BomPageVO pageVO = new BomPageVO<>(page.getCurrent(), page.getSize(), page.getTotal(), page.searchCount()); + pageVO.setRecords(records); // 应该保证原有的分页信息可以正确的应用在新的数据集中 + return pageVO; + } + + +} diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/vo/BomTbHeaderVO.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/vo/BomTbHeaderVO.java new file mode 100644 index 00000000..13f772fa --- /dev/null +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/vo/BomTbHeaderVO.java @@ -0,0 +1,23 @@ +package com.nflg.product.bomnew.pojo.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * @decription + * @Author 大米 + * @Date 2022/9/25 9:25 + **/ +@Data +@AllArgsConstructor +public class BomTbHeaderVO { + @ApiModelProperty("表头显示名称") + private String displayHeaderName; + @ApiModelProperty("对应数据字段名称") + private String valueHeaderName; + +// @ApiModelProperty("是否显示 0:不显示 1:显示") +// private Integer displayState; + +} diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/BatchBomService.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/BatchBomService.java new file mode 100644 index 00000000..de62556d --- /dev/null +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/BatchBomService.java @@ -0,0 +1,615 @@ +package com.nflg.product.bomnew.service; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.lang.TypeReference; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.nflg.product.base.core.conmon.util.SessionUtil; +import com.nflg.product.base.core.exception.NflgBusinessException; +import com.nflg.product.bomnew.constant.*; +import com.nflg.product.bomnew.mapper.master.BomNewEbomChildMapper; +import com.nflg.product.bomnew.mapper.master.BomNewEbomParentMapper; +import com.nflg.product.bomnew.mapper.master.BomNewPbomChildMapper; +import com.nflg.product.bomnew.mapper.master.BomNewPbomParentMapper; +import com.nflg.product.bomnew.pojo.entity.BomNewEbomChildEntity; +import com.nflg.product.bomnew.pojo.entity.BomNewEbomParentEntity; +import com.nflg.product.bomnew.pojo.entity.BomNewPbomChildEntity; +import com.nflg.product.bomnew.pojo.entity.BomNewPbomParentEntity; +import com.nflg.product.bomnew.pojo.query.BatchBomQuery; +import com.nflg.product.bomnew.pojo.vo.BaseBomVO; +import com.nflg.product.bomnew.pojo.vo.BaseMaterialVO; +import com.nflg.product.bomnew.pojo.vo.BomPageVO; +import com.nflg.product.bomnew.pojo.vo.BomTbHeaderVO; +import com.nflg.product.bomnew.util.DateUtils; +import com.nflg.product.bomnew.util.ListCommonUtil; +import com.nflg.product.bomnew.util.VersionUtil; +import lombok.extern.slf4j.Slf4j; +import nflg.product.common.constant.STATE; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.ttzero.excel.entity.Column; +import org.ttzero.excel.entity.ListMapSheet; +import org.ttzero.excel.entity.Workbook; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; + +@Service +@Slf4j +public class BatchBomService { + + @Resource + private BomNewEbomParentService bomNewEbomParentService; + @Resource + private BomNewEbomChildService bomNewEbomChildService; + @Resource + private BomNewEbomParentMapper bomNewEbomParentMapper; + @Resource + private BomNewEbomChildMapper bomNewEbomChildMapper; + @Resource + private BomNewPbomParentService bomNewPbomParentService; + @Resource + private BomNewPbomChildService bomNewPbomChildService; + @Resource + private BomNewPbomParentMapper bomNewPbomParentMapper; + @Resource + private BomNewPbomChildMapper bomNewPbomChildMapper; + @Resource + private MaterialMainService materialMainService; + @Resource + private UserRoleService userRoleService; + + public BomPageVO, BomTbHeaderVO> getParentBomList(BatchBomQuery batchBomQuery) { + if (!(batchBomQuery.getMaterialUnit().equals(batchBomQuery.getNewMaterialUnit())) + && (batchBomQuery.getReplaceTimes().compareTo(BigDecimal.ZERO) == 0 || batchBomQuery.getNewReplaceTimes().compareTo(BigDecimal.ZERO) == 0)) { + throw new NflgBusinessException(STATE.ParamErr, "参数错误,换算关系不能为0"); + } + List resultList = new ArrayList<>(); + String bomType = batchBomQuery.getBomType(); + int decimalScale = ObjectUtil.isNotEmpty(batchBomQuery.getDecimalScale()) ? batchBomQuery.getDecimalScale() : 3; + BigDecimal replaceTimes = ObjectUtil.isNotEmpty(batchBomQuery.getReplaceTimes()) ? batchBomQuery.getReplaceTimes() : BigDecimal.ONE; + BigDecimal newReplaceTimes = ObjectUtil.isNotEmpty(batchBomQuery.getNewReplaceTimes()) ? batchBomQuery.getNewReplaceTimes() : BigDecimal.ONE; + buildQueryCondition(batchBomQuery); + if ("ebom".equals(bomType)) { + String materialNo = batchBomQuery.getMaterialNo(); + // 查询出子级 + List ebomChildEntities = bomNewEbomChildService.lambdaQuery() + .eq(BomNewEbomChildEntity::getMaterialNo, materialNo) + .list(); + if (CollectionUtil.isNotEmpty(ebomChildEntities)) { + // 根据子级的parentRowId查询父级(状态是已发布PBOM,即正式表数据) + List parentRowIds = ebomChildEntities.stream().map(BomNewEbomChildEntity::getParentRowId).collect(Collectors.toList()); + List ebomParentEntities = bomNewEbomParentService.lambdaQuery() + .in(BomNewEbomParentEntity::getRowId, parentRowIds) + .eq(BomNewEbomParentEntity::getStatus, EBomStatusEnum.PUBLISHED.getValue()) + .orderByDesc(BomNewEbomParentEntity::getCreatedTime) + .list(); + if (CollectionUtil.isNotEmpty(ebomParentEntities)) { + for (BomNewEbomParentEntity parent : ebomParentEntities) { + // 按创建时间过滤 + if (ObjectUtil.isNotEmpty(batchBomQuery.getStartDate())) { + LocalDateTime startTime = LocalDateTime.parse(batchBomQuery.getStartDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + if (parent.getCreatedTime().isBefore(startTime)) { + continue; + } + } + if (ObjectUtil.isNotEmpty(batchBomQuery.getEndDate())) { + LocalDateTime endTime = LocalDateTime.parse(batchBomQuery.getEndDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + if (parent.getCreatedTime().isAfter(endTime)) { + continue; + } + } + BaseBomVO baseBomVO = new BaseBomVO(); + baseBomVO.setParentRowId(parent.getRowId()); + baseBomVO.setParentMaterialNo(parent.getMaterialNo()); + baseBomVO.setParentVersion(parent.getCurrentVersion()); + baseBomVO.setCreatedBy(parent.getCreatedBy()); + baseBomVO.setCreatedTime(parent.getCreatedTime()); + baseBomVO.setExpireEndTime(parent.getExpireEndTime()); + baseBomVO.setDeviseUserCode(parent.getDeviseUserCode()); + baseBomVO.setDeviseName(parent.getDeviseName()); + Optional first = ebomChildEntities.stream().filter(item -> item.getParentRowId().equals(parent.getRowId())).findFirst(); + if (first.isPresent()) { + BomNewEbomChildEntity ebomChild = first.get(); + baseBomVO.setChildRowId(ebomChild.getRowId()); + baseBomVO.setMaterialNo(ebomChild.getMaterialNo()); + baseBomVO.setNum(ebomChild.getNum()); + baseBomVO.setUnit(ebomChild.getMaterialUnit()); + } + baseBomVO.setNewMaterialNo(batchBomQuery.getNewMaterialNo()); + baseBomVO.setNewNum(newReplaceTimes.divide(replaceTimes, decimalScale, RoundingMode.HALF_UP).multiply(baseBomVO.getNum())); + baseBomVO.setNewUnit(batchBomQuery.getNewMaterialUnit()); + baseBomVO.setNewVersion(VersionUtil.getNextVersion(baseBomVO.getParentVersion())); + resultList.add(baseBomVO); + } + } + } + } else if ("pbom".equals(bomType)) { + String materialNo = batchBomQuery.getMaterialNo(); + // 查询出子级 + List pbomChildEntities = bomNewPbomChildService.lambdaQuery() + .eq(BomNewPbomChildEntity::getMaterialNo, materialNo) + .eq(BomNewPbomChildEntity::getFacCode, batchBomQuery.getFactory()) // 工厂查询 + .list(); + if (CollectionUtil.isNotEmpty(pbomChildEntities)) { + // 根据子级的parentRowId查询父级(状态是>=已发布,即正式表数据) + List parentRowIds = pbomChildEntities.stream().map(BomNewPbomChildEntity::getParentRowId).collect(Collectors.toList()); + List pbomParentEntities = bomNewPbomParentService.lambdaQuery() + .in(BomNewPbomParentEntity::getRowId, parentRowIds) + .ge(BomNewPbomParentEntity::getStatus, PBomStatusEnum.PUBLISH.getValue()) + .orderByDesc(BomNewPbomParentEntity::getCreatedTime) + .list(); + if (CollectionUtil.isNotEmpty(pbomParentEntities)) { + for (BomNewPbomParentEntity parent : pbomParentEntities) { + // 按创建时间过滤 + if (ObjectUtil.isNotEmpty(batchBomQuery.getStartDate())) { + LocalDateTime startTime = LocalDateTimeUtil.parse(batchBomQuery.getStartDate(), DatePattern.NORM_DATE_PATTERN); + if (parent.getCreatedTime().isBefore(startTime)) { + continue; + } + } + if (ObjectUtil.isNotEmpty(batchBomQuery.getEndDate())) { + LocalDateTime endTime = LocalDateTimeUtil.parse(batchBomQuery.getEndDate(), DatePattern.NORM_DATE_PATTERN); + if (parent.getCreatedTime().isAfter(endTime)) { + continue; + } + } + BaseBomVO baseBomVO = new BaseBomVO(); + baseBomVO.setParentRowId(parent.getRowId()); + baseBomVO.setParentMaterialNo(parent.getMaterialNo()); + baseBomVO.setParentVersion(parent.getCurrentVersion()); + baseBomVO.setCreatedBy(parent.getCreatedBy()); + baseBomVO.setCreatedTime(parent.getCreatedTime()); + baseBomVO.setExpireEndTime(parent.getExpireEndTime()); + baseBomVO.setDeviseUserCode(parent.getDeviseUserCode()); + baseBomVO.setDeviseName(parent.getDeviseName()); + baseBomVO.setFactory(parent.getFacCode()); + Optional first = pbomChildEntities.stream().filter(item -> item.getParentRowId().equals(parent.getRowId())).findFirst(); + if (first.isPresent()) { + BomNewPbomChildEntity pbomChild = first.get(); + baseBomVO.setChildRowId(pbomChild.getRowId()); + baseBomVO.setMaterialNo(pbomChild.getMaterialNo()); + baseBomVO.setNum(pbomChild.getNum()); + baseBomVO.setUnit(pbomChild.getMaterialUnit()); + } + baseBomVO.setNewMaterialNo(batchBomQuery.getNewMaterialNo()); + baseBomVO.setNewNum(newReplaceTimes.divide(replaceTimes, decimalScale, RoundingMode.HALF_UP).multiply(baseBomVO.getNum())); + baseBomVO.setNewUnit(batchBomQuery.getNewMaterialUnit()); + baseBomVO.setNewVersion(VersionUtil.getNextVersion(baseBomVO.getParentVersion())); + resultList.add(baseBomVO); + } + } + } + } + if (CollectionUtil.isEmpty(resultList)) { + return null; + } + initMaterialInfoAndFilter(resultList); + if (CollectionUtil.isNotEmpty(resultList)) { + long counter = 0; + for (BaseBomVO result : resultList) { + result.setOrderNum(++counter); + } + } + + BomPageVO, BomTbHeaderVO> pageVO = new BomPageVO<>(); + List> records = new ArrayList<>(resultList.size()); + resultList.forEach(result -> records.add(BeanUtil.beanToMap(result))); + pageVO.setRecords(records); + pageVO.setPages(1L); + pageVO.setCurrent(1L); + pageVO.setPageSize(Long.MAX_VALUE); + pageVO.setTotal(records.size()); + pageVO.setTbHeaders(getTbHeaders()); + return pageVO; + } + + /** + * 初始化物料信息,并过滤掉冻结物料 + */ + private void initMaterialInfoAndFilter(List resultList) { + // 实时查询物料的物料描述,物料类别等字段 + List tempList = new ArrayList<>(); + resultList.forEach(result -> { + BaseMaterialVO parent = new BaseMaterialVO(); + parent.setMaterialNo(result.getParentMaterialNo()); + tempList.add(parent); + }); + materialMainService.intiMaterialInfo(tempList); + Map materialMp = ListCommonUtil.listToMap(tempList, BaseMaterialVO::getMaterialNo); + ListIterator listIterator = resultList.listIterator(); + while (listIterator.hasNext()) { + BaseBomVO result = listIterator.next(); + // 过滤掉冻结物料 + if (ObjectUtil.isNotEmpty(materialMp.get(result.getParentMaterialNo())) + && (MaterialGetEnum.MaterialStateEnum.STATE_NO_4.equalsValue(materialMp.get(result.getParentMaterialNo()).getMaterialState()) + || MaterialGetEnum.MaterialStateEnum.STATE_NO_5.equalsValue(materialMp.get(result.getParentMaterialNo()).getMaterialState()))) { + listIterator.remove(); + continue; + } + result.setParentMaterialRowId(materialMp.get(result.getParentMaterialNo()).getMaterialRowId()); + result.setParentMaterialDesc(materialMp.get(result.getParentMaterialNo()).getMaterialDesc()); + result.setCategoryCode(materialMp.get(result.getParentMaterialNo()).getMaterialCategoryCode()); + result.setRelCategoryCode(materialMp.get(result.getParentMaterialNo()).getRelCategoryCode()); + result.setCategoryName(materialMp.get(result.getParentMaterialNo()).getCategoryName()); + } + } + + private List getTbHeaders() { + List headerVOS = new ArrayList<>(); + headerVOS.add(new BomTbHeaderVO("序号", "orderNum")); + headerVOS.add(new BomTbHeaderVO("父级物料编码", "parentMaterialNo")); + headerVOS.add(new BomTbHeaderVO("父级物料描述", "parentMaterialDesc")); + headerVOS.add(new BomTbHeaderVO("物料类别", "categoryName")); + headerVOS.add(new BomTbHeaderVO("父级BOM版本号", "parentVersion")); + headerVOS.add(new BomTbHeaderVO("原物料编码", "materialNo")); + headerVOS.add(new BomTbHeaderVO("原数量", "num")); + headerVOS.add(new BomTbHeaderVO("原单位", "unit")); + headerVOS.add(new BomTbHeaderVO("新物料编码", "newMaterialNo")); + headerVOS.add(new BomTbHeaderVO("新数量", "newNum")); + headerVOS.add(new BomTbHeaderVO("新单位", "newUnit")); + headerVOS.add(new BomTbHeaderVO("新版本号", "newVersion")); + headerVOS.add(new BomTbHeaderVO("创建时间", "createdTime")); + headerVOS.add(new BomTbHeaderVO("版本过期时间", "expireEndTime")); + headerVOS.add(new BomTbHeaderVO("设计人员", "deviseName")); + return headerVOS; + } + + private void buildQueryCondition(BatchBomQuery query) { + if (query.getDateType() != null) { + if (query.getDateType().compareTo(DateTypeEnum.ZERO.getCode()) == 0) { + query.setStartDate(null); + query.setEndDate(null); + } else { + if (query.getDateType().compareTo(DateTypeEnum.SEVEN.getCode()) == 0) { + String endDate = DateUtils.date2Str(DateUtils.datetimeFormat.get()); + query.setEndDate(endDate); + ZonedDateTime zonedDateTime = ZonedDateTime.now().minusDays(6).withHour(0).withMinute(0).withSecond(0).withNano(0); + String startDate = zonedDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + query.setStartDate(startDate); + } + if (query.getDateType().compareTo(DateTypeEnum.THIRTY.getCode()) == 0) { + String endDate = DateUtils.date2Str(DateUtils.datetimeFormat.get()); + query.setEndDate(endDate); + ZonedDateTime zonedDateTime = ZonedDateTime.now().minusDays(29).withHour(0).withMinute(0).withSecond(0).withNano(0); + String startDate = zonedDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + query.setStartDate(startDate); + } + if (query.getDateType().compareTo(DateTypeEnum.NINETY.getCode()) == 0) { + String endDate = DateUtils.date2Str(DateUtils.datetimeFormat.get()); + query.setEndDate(endDate); + ZonedDateTime zonedDateTime = ZonedDateTime.now().minusDays(89).withHour(0).withMinute(0).withSecond(0).withNano(0); + String startDate = zonedDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + query.setStartDate(startDate); + } + if (query.getDateType().compareTo(DateTypeEnum.LONGDATE.getCode()) == 0 && ObjectUtil.isNotEmpty(query.getStartDate()) && ObjectUtil.isNotEmpty(query.getEndDate())) { + query.setEndDate(query.getEndDate() + " 00:00:00"); + query.setStartDate(query.getStartDate() + " 00:00:00"); + } + } + } + } + + /** + * 更新BOM并导入SAP(但是EBOM的话,不生成PBOM工作表) + * @param baseBomVOList + */ + @Transactional(rollbackFor = Exception.class) + public List updateEBom(List baseBomVOList) { + if (CollectionUtil.isEmpty(baseBomVOList)) { + return null; + } + List materialBaseInfo = materialMainService.getMaterialBaseInfo(Collections.singletonList(baseBomVOList.get(0).getNewMaterialNo())); + if (CollectionUtil.isEmpty(materialBaseInfo)) { + throw new NflgBusinessException(STATE.ParamErr, "新物料编码不存在"); + } + BaseMaterialVO newMaterialInfo= materialBaseInfo.get(0); + List addRowIds = new ArrayList<>(baseBomVOList.size()); // 需要加入历史表的父级BOM ID + List delRowIds = new ArrayList<>(baseBomVOList.size()); // 需要从正式表删除的父级BOM ID + LocalDateTime now = LocalDateTime.now(); + int createdJob = userRoleService.technician() ? UserJobEnum.ENGINEER.getValue() : UserJobEnum.DESIGNER.getValue(); + for (BaseBomVO baseBomVO: baseBomVOList) { + // 找到父级 + BomNewEbomParentEntity ebomParentEntity = bomNewEbomParentService.lambdaQuery().eq(BomNewEbomParentEntity::getRowId, baseBomVO.getParentRowId()).one(); + if (ObjectUtil.isNotEmpty(ebomParentEntity)) { + // 找到该父级的所有子级列表 + List ebomChildEntities = bomNewEbomChildService.lambdaQuery().eq(BomNewEbomChildEntity::getParentRowId, baseBomVO.getParentRowId()).list(); + // 在子级列表中找到要被替换的那条子级 + List collect = ebomChildEntities.stream().filter(item -> item.getRowId().equals(baseBomVO.getChildRowId())).collect(Collectors.toList()); + BomNewEbomChildEntity replaceChild = collect.get(0); + // 其他子级 + List otherChildren = ebomChildEntities.stream().filter(item -> !item.getRowId().equals(baseBomVO.getChildRowId())).collect(Collectors.toList()); + // 构建新版的父级规则:大版本号+1(如果该BOM还有编辑中的草稿版本,则草稿版本号也+1) + BomNewEbomParentEntity newParent = new BomNewEbomParentEntity(); + BeanUtil.copyProperties(ebomParentEntity, newParent); + newParent.setRowId(IdWorker.getId()); + newParent.setCurrentVersion(baseBomVO.getNewVersion()); // 新版本号 + // 新版本创建时间要更新,创建人要不要更新待定(根据权限管理考虑) + newParent.setCreatedTime(now); + newParent.setModifyTime(now); + newParent.setSapState(SapStatusEnum.UNPUB_SAP.getValue()); + newParent.setSapTime(null); + newParent.setDeptRowId(SessionUtil.getDepartRowId()); + newParent.setDeptName(SessionUtil.getDepartName()); + newParent.setDeviseName(SessionUtil.getRealName()); + newParent.setDeviseUserCode(SessionUtil.getUserCode()); + newParent.setCreatedBy(SessionUtil.getUserCode()); + newParent.setCreatedJob(createdJob); + // 构建新版的子级规则:其他子级复制一份,被替换的子级改物料编码,数量,单位等 + List newChildList = new ArrayList<>(ebomChildEntities.size()); + otherChildren.forEach(item -> { + BomNewEbomChildEntity newChild = new BomNewEbomChildEntity(); + BeanUtil.copyProperties(item, newChild); + newChild.setRowId(IdWorker.getId()); + newChild.setParentRowId(newParent.getRowId()); + newChild.setIdentityNo(newParent.getRowId() + "_" + newChild.getRowId()); + // 新版本创建时间要更新,创建人要不要更新待定(根据权限管理考虑) + newChild.setCreatedTime(now); + newChild.setModifyTime(now); + newChild.setCreatedBy(SessionUtil.getUserCode()); + newChildList.add(newChild); + }); + BomNewEbomChildEntity newReplaceChild = new BomNewEbomChildEntity(); + BeanUtil.copyProperties(replaceChild, newReplaceChild); + newReplaceChild.setRowId(IdWorker.getId()); + newReplaceChild.setParentRowId(newParent.getRowId()); + newReplaceChild.setIdentityNo(newParent.getRowId() + "_" + newReplaceChild.getRowId()); + newReplaceChild.setMaterialNo(baseBomVO.getNewMaterialNo()); // 新物料编码 + newReplaceChild.setDrawingNo(newMaterialInfo.getDrawingNo()); + newReplaceChild.setMaterialName(newMaterialInfo.getMaterialName()); + newReplaceChild.setMaterialDesc(newMaterialInfo.getMaterialDesc()); // 新物料描述 + newReplaceChild.setMaterialTexture(newMaterialInfo.getMaterialTexture()); + newReplaceChild.setMaterialUnit(baseBomVO.getNewUnit()); // 新单位 + newReplaceChild.setNum(baseBomVO.getNewNum()); // 新数量 + newReplaceChild.setMaterialCategoryCode(newMaterialInfo.getMaterialCategoryCode()); + // TODO 新单重?新总重?要不要更新 + // 新版本创建时间要更新,创建人要不要更新待定(根据权限管理考虑) + newReplaceChild.setCreatedTime(now); + newReplaceChild.setModifyTime(now); + newReplaceChild.setCreatedBy(SessionUtil.getUserCode()); + newReplaceChild.setRemark("【批量替代BOM】由" + baseBomVO.getMaterialNo() + "替代为" + baseBomVO.getNewMaterialNo()); + newChildList.add(newReplaceChild); + bomNewEbomParentService.save(newParent); + bomNewEbomChildService.saveBatch(newChildList); + addRowIds.add(newParent.getRowId()); + } + delRowIds.add(ebomParentEntity.getRowId()); + } + // 转入历史表 + if (CollUtil.isNotEmpty(addRowIds)) { + bomNewEbomParentMapper.insertEBomFormalParent(addRowIds); + bomNewEbomParentMapper.insertEBomFormalChild(addRowIds); + } + if (CollUtil.isNotEmpty(delRowIds)){ + // 转移后删除 + bomNewEbomParentService.delEBomHistory(delRowIds); + } + // TODO 如果有草稿中数据,草稿版本+1 + for (BaseBomVO baseBomVO: baseBomVOList) { + BomNewEbomParentEntity draftParent = bomNewEbomParentService.lambdaQuery() + .eq(BomNewEbomParentEntity::getMaterialNo, baseBomVO.getParentMaterialNo()) + .lt(BomNewEbomParentEntity::getStatus, EBomStatusEnum.PUBLISHED.getValue()) + .one(); + if (ObjectUtil.isNotEmpty(draftParent)) { + // 草稿版本 A01 -> A02,A01.1 -> A02.1 + String[] currentVersionArr = draftParent.getCurrentVersion().split("\\."); + String newVersion = VersionUtil.getNextVersion(currentVersionArr[0]); + if (currentVersionArr.length > 1) { + newVersion += "." + currentVersionArr[1]; + } + draftParent.setCurrentVersion(newVersion); + draftParent.setModifyTime(LocalDateTime.now()); + bomNewEbomParentService.updateById(draftParent); + // 子级有原物料号,也要替代成新物料号 + List draftChildren = bomNewEbomChildService.lambdaQuery().eq(BomNewEbomChildEntity::getParentRowId, baseBomVO.getParentRowId()).list(); + if (CollectionUtil.isNotEmpty(draftChildren)) { + List replaceChildren = draftChildren.stream().filter(child -> baseBomVO.getMaterialNo().equals(child.getMaterialNo())).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(replaceChildren)) { + for (BomNewEbomChildEntity newReplaceChild: replaceChildren) { + newReplaceChild.setRowId(IdWorker.getId()); + newReplaceChild.setIdentityNo(draftParent.getRowId() + "_" + newReplaceChild.getRowId()); + newReplaceChild.setMaterialNo(baseBomVO.getNewMaterialNo()); // 新物料编码 + newReplaceChild.setDrawingNo(newMaterialInfo.getDrawingNo()); + newReplaceChild.setMaterialName(newMaterialInfo.getMaterialName()); + newReplaceChild.setMaterialDesc(newMaterialInfo.getMaterialDesc()); // 新物料描述 + newReplaceChild.setMaterialTexture(newMaterialInfo.getMaterialTexture()); + newReplaceChild.setMaterialUnit(baseBomVO.getNewUnit()); // 新单位 + newReplaceChild.setNum(baseBomVO.getNewNum()); // 新数量 + newReplaceChild.setMaterialCategoryCode(newMaterialInfo.getMaterialCategoryCode()); + // TODO 新单重?新总重?要不要更新 + // 新版本创建时间要更新,创建人要不要更新待定(根据权限管理考虑) + newReplaceChild.setCreatedTime(now); + newReplaceChild.setModifyTime(now); + newReplaceChild.setCreatedBy(SessionUtil.getUserCode()); + newReplaceChild.setRemark("【批量替代BOM】由" + baseBomVO.getMaterialNo() + "替代为" + baseBomVO.getNewMaterialNo()); + } + bomNewEbomChildService.updateBatchById(replaceChildren); + } + } + } + } + return addRowIds; + } + + /** + * 更新BOM并导入SAP + * @param baseBomVOList + */ + @Transactional(rollbackFor = Exception.class) + public List updatePBom(List baseBomVOList) { + if (CollectionUtil.isEmpty(baseBomVOList)) { + return null; + } + List materialBaseInfo = materialMainService.getMaterialBaseInfo(Collections.singletonList(baseBomVOList.get(0).getNewMaterialNo())); + if (CollectionUtil.isEmpty(materialBaseInfo)) { + throw new NflgBusinessException(STATE.ParamErr, "新物料编码不存在"); + } + BaseMaterialVO newMaterialInfo= materialBaseInfo.get(0); + List addRowIds = new ArrayList<>(baseBomVOList.size()); // 需要加入历史表的父级BOM ID + List delRowIds = new ArrayList<>(baseBomVOList.size()); // 需要从正式表删除的父级BOM ID + LocalDateTime now = LocalDateTime.now(); + int createdJob = userRoleService.technician() ? UserJobEnum.ENGINEER.getValue() : UserJobEnum.DESIGNER.getValue(); + for (BaseBomVO baseBomVO: baseBomVOList) { + // 找到父级 + BomNewPbomParentEntity pbomParentEntity = bomNewPbomParentService.lambdaQuery().eq(BomNewPbomParentEntity::getRowId, baseBomVO.getParentRowId()).one(); + if (ObjectUtil.isNotEmpty(pbomParentEntity)) { + // 找到该父级的所有子级列表 + List pbomChildEntities = bomNewPbomChildService.lambdaQuery().eq(BomNewPbomChildEntity::getParentRowId, baseBomVO.getParentRowId()).list(); + // 在子级列表中找到要被替换的那条子级 + List collect = pbomChildEntities.stream().filter(item -> item.getRowId().equals(baseBomVO.getChildRowId())).collect(Collectors.toList()); + BomNewPbomChildEntity replaceChild = collect.get(0); + // 其他子级 + List otherChildren = pbomChildEntities.stream().filter(item -> !item.getRowId().equals(baseBomVO.getChildRowId())).collect(Collectors.toList()); + // 构建新版的父级规则:大版本号+1(如果该BOM还有编辑中的草稿版本,则草稿版本号也+1) + BomNewPbomParentEntity newParent = new BomNewPbomParentEntity(); + BeanUtil.copyProperties(pbomParentEntity, newParent); + newParent.setRowId(IdWorker.getId()); + newParent.setCurrentVersion(baseBomVO.getNewVersion()); // 新版本号 + // 新版本创建时间要更新,创建人要不要更新待定(根据权限管理考虑) + newParent.setCreatedTime(now); + newParent.setModifyTime(now); + newParent.setSapState(SapStatusEnum.UNPUB_SAP.getValue()); + newParent.setSapTime(null); + newParent.setDeptRowId(SessionUtil.getDepartRowId()); + newParent.setDeptName(SessionUtil.getDepartName()); + newParent.setDeviseName(SessionUtil.getRealName()); + newParent.setDeviseUserCode(SessionUtil.getUserCode()); + newParent.setCreatedBy(SessionUtil.getUserCode()); + newParent.setCreatedJob(createdJob); + // 构建新版的子级规则:其他子级复制一份,被替换的子级改物料编码,数量,单位等 + List newChildList = new ArrayList<>(pbomChildEntities.size()); + otherChildren.forEach(item -> { + BomNewPbomChildEntity newChild = new BomNewPbomChildEntity(); + BeanUtil.copyProperties(item, newChild); + newChild.setRowId(IdWorker.getId()); + newChild.setParentRowId(newParent.getRowId()); + newChild.setIdentityNo(newParent.getRowId() + "_" + newChild.getRowId()); + // 新版本创建时间要更新,创建人要不要更新待定(根据权限管理考虑) + newChild.setCreatedTime(now); + newChild.setModifyTime(now); + newChild.setCreatedBy(SessionUtil.getUserCode()); + newChildList.add(newChild); + }); + BomNewPbomChildEntity newReplaceChild = new BomNewPbomChildEntity(); + BeanUtil.copyProperties(replaceChild, newReplaceChild); + newReplaceChild.setRowId(IdWorker.getId()); + newReplaceChild.setParentRowId(newParent.getRowId()); + newReplaceChild.setIdentityNo(newParent.getRowId() + "_" + newReplaceChild.getRowId()); + newReplaceChild.setMaterialNo(baseBomVO.getNewMaterialNo()); // 新物料编码 + newReplaceChild.setDrawingNo(newMaterialInfo.getDrawingNo()); + newReplaceChild.setMaterialName(newMaterialInfo.getMaterialName()); + newReplaceChild.setMaterialDesc(newMaterialInfo.getMaterialDesc()); // 新物料描述 + newReplaceChild.setMaterialTexture(newMaterialInfo.getMaterialTexture()); + newReplaceChild.setMaterialUnit(baseBomVO.getNewUnit()); // 新单位 + newReplaceChild.setNum(baseBomVO.getNewNum()); // 新数量 + newReplaceChild.setMaterialCategoryCode(newMaterialInfo.getMaterialCategoryCode()); + // TODO 新单重?新总重?要不要更新 + // 新版本创建时间要更新,创建人要不要更新待定(根据权限管理考虑) + newReplaceChild.setCreatedTime(now); + newReplaceChild.setModifyTime(now); + newReplaceChild.setCreatedBy(SessionUtil.getUserCode()); + newReplaceChild.setRemark("【批量替代BOM】由" + baseBomVO.getMaterialNo() + "替代为" + baseBomVO.getNewMaterialNo()); + newChildList.add(newReplaceChild); + bomNewPbomParentService.save(newParent); + bomNewPbomChildService.saveBatch(newChildList); + addRowIds.add(newParent.getRowId()); + } + delRowIds.add(pbomParentEntity.getRowId()); + } + // 转入历史表 + if (CollUtil.isNotEmpty(addRowIds)) { + bomNewPbomParentMapper.insertPBomParentToFormal(addRowIds); + bomNewPbomParentMapper.insertPBomChildToFormal(addRowIds); + } + if (CollUtil.isNotEmpty(delRowIds)){ + // 转移后删除 + bomNewPbomParentService.delPBom(delRowIds); + } + // TODO 如果有草稿中数据,草稿版本+1 + for (BaseBomVO baseBomVO: baseBomVOList) { + BomNewPbomParentEntity draftParent = bomNewPbomParentService.lambdaQuery() + .eq(BomNewPbomParentEntity::getMaterialNo, baseBomVO.getParentMaterialNo()) + .eq(BomNewPbomParentEntity::getFacCode, baseBomVO.getFactory()) + .lt(BomNewPbomParentEntity::getStatus, PBomStatusEnum.PUBLISH.getValue()) + .one(); + if (ObjectUtil.isNotEmpty(draftParent)) { + // 草稿版本 A01 -> A02,A01.1 -> A02.1 + String[] currentVersionArr = draftParent.getCurrentVersion().split("\\."); + String newVersion = VersionUtil.getNextVersion(currentVersionArr[0]); + if (currentVersionArr.length > 1) { + newVersion += "." + currentVersionArr[1]; + } + draftParent.setCurrentVersion(newVersion); + draftParent.setModifyTime(LocalDateTime.now()); + bomNewPbomParentService.updateById(draftParent); + // 子级有原物料号,也要替代成新物料号 + List draftChildren = bomNewPbomChildService.lambdaQuery().eq(BomNewPbomChildEntity::getParentRowId, baseBomVO.getParentRowId()).list(); + if (CollectionUtil.isNotEmpty(draftChildren)) { + List replaceChildren = draftChildren.stream().filter(child -> baseBomVO.getMaterialNo().equals(child.getMaterialNo())).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(replaceChildren)) { + for (BomNewPbomChildEntity newReplaceChild: replaceChildren) { + newReplaceChild.setRowId(IdWorker.getId()); + newReplaceChild.setIdentityNo(draftParent.getRowId() + "_" + newReplaceChild.getRowId()); + newReplaceChild.setMaterialNo(baseBomVO.getNewMaterialNo()); // 新物料编码 + newReplaceChild.setDrawingNo(newMaterialInfo.getDrawingNo()); + newReplaceChild.setMaterialName(newMaterialInfo.getMaterialName()); + newReplaceChild.setMaterialDesc(newMaterialInfo.getMaterialDesc()); // 新物料描述 + newReplaceChild.setMaterialTexture(newMaterialInfo.getMaterialTexture()); + newReplaceChild.setMaterialUnit(baseBomVO.getNewUnit()); // 新单位 + newReplaceChild.setNum(baseBomVO.getNewNum()); // 新数量 + newReplaceChild.setMaterialCategoryCode(newMaterialInfo.getMaterialCategoryCode()); + // TODO 新单重?新总重?要不要更新 + // 新版本创建时间要更新,创建人要不要更新待定(根据权限管理考虑) + newReplaceChild.setCreatedTime(now); + newReplaceChild.setModifyTime(now); + newReplaceChild.setCreatedBy(SessionUtil.getUserCode()); + newReplaceChild.setRemark("【批量替代BOM】由" + baseBomVO.getMaterialNo() + "替代为" + baseBomVO.getNewMaterialNo()); + } + bomNewPbomChildService.updateBatchById(replaceChildren); + } + } + } + } + return addRowIds; + } + + public Workbook getExportExcelWork(BatchBomQuery query) { + BomPageVO list = this.getParentBomList(query); + if (ObjectUtil.isEmpty(list)) { + return new Workbook().addSheet(new ListMapSheet("bom")); + } + long pages = list.getPages(); + List voList = list.getRecords(); + Integer pageCount = Math.toIntExact(pages + 1); + return new Workbook().addSheet(new ListMapSheet("bom", getExcelColumns(getTbHeaders())) { + Long n = 1L; + + @Override + protected List> more() { + query.setPage(n); + return n++ < pageCount ? Convert.convert(new TypeReference>>() { + }, voList) : null; + } + }); + } + + public Column[] getExcelColumns(List headers) { + Column[] excelColumns = new Column[headers.size()]; + for (int i = 0; i < headers.size(); i++) { + BomTbHeaderVO h = headers.get(i); + excelColumns[i] = new Column(h.getDisplayHeaderName(), h.getValueHeaderName(), String.class); + } + return excelColumns; + } +} diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/EBomImportService.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/EBomImportService.java index dee2ed6c..5fc49142 100644 --- a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/EBomImportService.java +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/EBomImportService.java @@ -402,6 +402,7 @@ public class EBomImportService { child.setDrawingNo(vo.getDrawingNo()); child.setUnitWeight(vo.getMaterialWeight()); child.setMaterialUnit(vo.getMaterialUnit()); + child.setMaterialOriginalUnit(vo.getMaterialUnit()); child.setMaterialTexture(vo.getMaterialTexture()); if (StrUtil.isBlank(child.getMaterialDesc())) { child.setMaterialDesc(vo.getMaterialDesc()); diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/util/DateUtils.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/util/DateUtils.java new file mode 100644 index 00000000..c4eae47c --- /dev/null +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/util/DateUtils.java @@ -0,0 +1,650 @@ +package com.nflg.product.bomnew.util; + +import org.springframework.util.StringUtils; + +import java.beans.PropertyEditorSupport; +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +/** + * @Author 大米 + * @Date 2022-03-11 + */ +public class DateUtils extends PropertyEditorSupport { + + public static ThreadLocal date_sdf = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd"); + } + }; + public static ThreadLocal yyyyMMdd = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyyMMdd"); + } + }; + public static ThreadLocal date_sdf_wz = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy年MM月dd日"); + } + }; + public static ThreadLocal time_sdf = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm"); + } + }; + public static ThreadLocal yyyymmddhhmmss = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyyMMddHHmmss"); + } + }; + public static ThreadLocal short_time_sdf = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("HH:mm"); + } + }; + public static ThreadLocal datetimeFormat = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + }; + + // 以毫秒表示的时间 + private static final long DAY_IN_MILLIS = 24 * 3600 * 1000; + private static final long HOUR_IN_MILLIS = 3600 * 1000; + private static final long MINUTE_IN_MILLIS = 60 * 1000; + private static final long SECOND_IN_MILLIS = 1000; + + // 指定模式的时间格式 + private static SimpleDateFormat getSDFormat(String pattern) { + return new SimpleDateFormat(pattern); + } + + /** + * 当前日历,这里用中国时间表示 + * + * @return 以当地时区表示的系统当前日历 + */ + public static Calendar getCalendar() { + return Calendar.getInstance(); + } + + /** + * 指定毫秒数表示的日历 + * + * @param millis 毫秒数 + * @return 指定毫秒数表示的日历 + */ + public static Calendar getCalendar(long millis) { + Calendar cal = Calendar.getInstance(); + // --------------------cal.setTimeInMillis(millis); + cal.setTime(new Date(millis)); + return cal; + } + + // //////////////////////////////////////////////////////////////////////////// + // getDate + // 各种方式获取的Date + // //////////////////////////////////////////////////////////////////////////// + + /** + * 当前日期 + * + * @return 系统当前时间 + */ + public static Date getDate() { + return new Date(); + } + + /** + * 指定毫秒数表示的日期 + * + * @param millis 毫秒数 + * @return 指定毫秒数表示的日期 + */ + public static Date getDate(long millis) { + return new Date(millis); + } + + /** + * 时间戳转换为字符串 + * + * @param time + * @return + */ + public static String timestamptoStr(Timestamp time) { + Date date = null; + if (null != time) { + date = new Date(time.getTime()); + } + return date2Str(date_sdf.get()); + } + + /** + * 字符串转换时间戳 + * + * @param str + * @return + */ + public static Timestamp str2Timestamp(String str) { + Date date = str2Date(str, date_sdf.get()); + return new Timestamp(date.getTime()); + } + + /** + * 字符串转换成日期 + * + * @param str + * @param sdf + * @return + */ + public static Date str2Date(String str, SimpleDateFormat sdf) { + if (null == str || "".equals(str)) { + return null; + } + Date date = null; + try { + date = sdf.parse(str); + return date; + } catch (ParseException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 日期转换为字符串 + * + * @param date_sdf 日期格式 + * @return 字符串 + */ + public static String date2Str(SimpleDateFormat date_sdf) { + Date date = getDate(); + if (null == date) { + return null; + } + return date_sdf.format(date); + } + + /** + * 格式化时间 + * + * @param date + * @param format + * @return + */ + public static String dateformat(String date, String format) { + SimpleDateFormat sformat = new SimpleDateFormat(format); + Date _date = null; + try { + _date = sformat.parse(date); + } catch (ParseException e) { + e.printStackTrace(); + } + return sformat.format(_date); + } + + /** + * 日期转换为字符串 + * + * @param date 日期 + * @param date_sdf 日期格式 + * @return 字符串 + */ + public static String date2Str(Date date, SimpleDateFormat date_sdf) { + if (null == date) { + return null; + } + return date_sdf.format(date); + } + + /** + * 日期转换为字符串 + * + * @param format 日期格式 + * @return 字符串 + */ + public static String getDate(String format) { + Date date = new Date(); + if (null == date) { + return null; + } + SimpleDateFormat sdf = new SimpleDateFormat(format); + return sdf.format(date); + } + + /** + * 指定毫秒数的时间戳 + * + * @param millis 毫秒数 + * @return 指定毫秒数的时间戳 + */ + public static Timestamp getTimestamp(long millis) { + return new Timestamp(millis); + } + + /** + * 以字符形式表示的时间戳 + * + * @param time 毫秒数 + * @return 以字符形式表示的时间戳 + */ + public static Timestamp getTimestamp(String time) { + return new Timestamp(Long.parseLong(time)); + } + + /** + * 系统当前的时间戳 + * + * @return 系统当前的时间戳 + */ + public static Timestamp getTimestamp() { + return new Timestamp(System.currentTimeMillis()); + } + + /** + * 当前时间,格式 yyyy-MM-dd HH:mm:ss + * + * @return 当前时间的标准形式字符串 + */ + public static String now() { + return datetimeFormat.get().format(getCalendar().getTime()); + } + + /** + * 指定日期的时间戳 + * + * @param date 指定日期 + * @return 指定日期的时间戳 + */ + public static Timestamp getTimestamp(Date date) { + return new Timestamp(date.getTime()); + } + + /** + * 指定日历的时间戳 + * + * @param cal 指定日历 + * @return 指定日历的时间戳 + */ + public static Timestamp getCalendarTimestamp(Calendar cal) { + // ---------------------return new Timestamp(cal.getTimeInMillis()); + return new Timestamp(cal.getTime().getTime()); + } + + public static Timestamp gettimestamp() { + Date dt = new Date(); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String nowTime = df.format(dt); + Timestamp buydate = Timestamp.valueOf(nowTime); + return buydate; + } + + // //////////////////////////////////////////////////////////////////////////// + // getMillis + // 各种方式获取的Millis + // //////////////////////////////////////////////////////////////////////////// + + /** + * 系统时间的毫秒数 + * + * @return 系统时间的毫秒数 + */ + public static long getMillis() { + return System.currentTimeMillis(); + } + + /** + * 指定日历的毫秒数 + * + * @param cal 指定日历 + * @return 指定日历的毫秒数 + */ + public static long getMillis(Calendar cal) { + // --------------------return cal.getTimeInMillis(); + return cal.getTime().getTime(); + } + + /** + * 指定日期的毫秒数 + * + * @param date 指定日期 + * @return 指定日期的毫秒数 + */ + public static long getMillis(Date date) { + return date.getTime(); + } + + /** + * 指定时间戳的毫秒数 + * + * @param ts 指定时间戳 + * @return 指定时间戳的毫秒数 + */ + public static long getMillis(Timestamp ts) { + return ts.getTime(); + } + + // //////////////////////////////////////////////////////////////////////////// + // formatDate + // 将日期按照一定的格式转化为字符串 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 默认方式表示的系统当前日期,具体格式:年-月-日 + * + * @return 默认日期按“年-月-日“格式显示 + */ + public static String formatDate() { + return date_sdf.get().format(getCalendar().getTime()); + } + + /** + * 默认方式表示的系统当前日期,具体格式:yyyy-MM-dd HH:mm:ss + * + * @return 默认日期按“yyyy-MM-dd HH:mm:ss“格式显示 + */ + public static String formatDateTime() { + return datetimeFormat.get().format(getCalendar().getTime()); + } + + /** + * 获取时间字符串 + */ + public static String getDataString(SimpleDateFormat formatstr) { + return formatstr.format(getCalendar().getTime()); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 + * + * @param cal 指定的日期 + * @return 指定日期按“年-月-日“格式显示 + */ + public static String formatDate(Calendar cal) { + return date_sdf.get().format(cal.getTime()); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 + * + * @param date 指定的日期 + * @return 指定日期按“年-月-日“格式显示 + */ + public static String formatDate(Date date) { + return date_sdf.get().format(date); + } + + /** + * 指定毫秒数表示日期的默认显示,具体格式:年-月-日 + * + * @param millis 指定的毫秒数 + * @return 指定毫秒数表示日期按“年-月-日“格式显示 + */ + public static String formatDate(long millis) { + return date_sdf.get().format(new Date(millis)); + } + + /** + * 默认日期按指定格式显示 + * + * @param pattern 指定的格式 + * @return 默认日期按指定格式显示 + */ + public static String formatDate(String pattern) { + return getSDFormat(pattern).format(getCalendar().getTime()); + } + + /** + * 指定日期按指定格式显示 + * + * @param cal 指定的日期 + * @param pattern 指定的格式 + * @return 指定日期按指定格式显示 + */ + public static String formatDate(Calendar cal, String pattern) { + return getSDFormat(pattern).format(cal.getTime()); + } + + /** + * 指定日期按指定格式显示 + * + * @param date 指定的日期 + * @param pattern 指定的格式 + * @return 指定日期按指定格式显示 + */ + public static String formatDate(Date date, String pattern) { + return getSDFormat(pattern).format(date); + } + + // //////////////////////////////////////////////////////////////////////////// + // formatTime + // 将日期按照一定的格式转化为字符串 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 默认方式表示的系统当前日期,具体格式:年-月-日 时:分 + * + * @return 默认日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime() { + return time_sdf.get().format(getCalendar().getTime()); + } + + /** + * 指定毫秒数表示日期的默认显示,具体格式:年-月-日 时:分 + * + * @param millis 指定的毫秒数 + * @return 指定毫秒数表示日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime(long millis) { + return time_sdf.get().format(new Date(millis)); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 时:分 + * + * @param cal 指定的日期 + * @return 指定日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime(Calendar cal) { + return time_sdf.get().format(cal.getTime()); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 时:分 + * + * @param date 指定的日期 + * @return 指定日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime(Date date) { + return time_sdf.get().format(date); + } + + // //////////////////////////////////////////////////////////////////////////// + // formatShortTime + // 将日期按照一定的格式转化为字符串 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 默认方式表示的系统当前日期,具体格式:时:分 + * + * @return 默认日期按“时:分“格式显示 + */ + public static String formatShortTime() { + return short_time_sdf.get().format(getCalendar().getTime()); + } + + /** + * 指定毫秒数表示日期的默认显示,具体格式:时:分 + * + * @param millis 指定的毫秒数 + * @return 指定毫秒数表示日期按“时:分“格式显示 + */ + public static String formatShortTime(long millis) { + return short_time_sdf.get().format(new Date(millis)); + } + + /** + * 指定日期的默认显示,具体格式:时:分 + * + * @param cal 指定的日期 + * @return 指定日期按“时:分“格式显示 + */ + public static String formatShortTime(Calendar cal) { + return short_time_sdf.get().format(cal.getTime()); + } + + /** + * 指定日期的默认显示,具体格式:时:分 + * + * @param date 指定的日期 + * @return 指定日期按“时:分“格式显示 + */ + public static String formatShortTime(Date date) { + return short_time_sdf.get().format(date); + } + + // //////////////////////////////////////////////////////////////////////////// + // parseDate + // parseCalendar + // parseTimestamp + // 将字符串按照一定的格式转化为日期或时间 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间 + * + * @param src 将要转换的原始字符窜 + * @param pattern 转换的匹配格式 + * @return 如果转换成功则返回转换后的日期 + * @throws ParseException + */ + public static Date parseDate(String src, String pattern) throws ParseException { + return getSDFormat(pattern).parse(src); + + } + + /** + * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间 + * + * @param src 将要转换的原始字符窜 + * @param pattern 转换的匹配格式 + * @return 如果转换成功则返回转换后的日期 + * @throws ParseException + */ + public static Calendar parseCalendar(String src, String pattern) throws ParseException { + + Date date = parseDate(src, pattern); + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return cal; + } + + public static String formatAddDate(String src, String pattern, int amount) throws ParseException { + Calendar cal; + cal = parseCalendar(src, pattern); + cal.add(Calendar.DATE, amount); + return formatDate(cal); + } + + /** + * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间 + * + * @param src 将要转换的原始字符窜 + * @param pattern 转换的匹配格式 + * @return 如果转换成功则返回转换后的时间戳 + * @throws ParseException + */ + public static Timestamp parseTimestamp(String src, String pattern) throws ParseException { + Date date = parseDate(src, pattern); + return new Timestamp(date.getTime()); + } + + // //////////////////////////////////////////////////////////////////////////// + // dateDiff + // 计算两个日期之间的差值 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 计算两个时间之间的差值,根据标志的不同而不同 + * + * @param flag 计算标志,表示按照年/月/日/时/分/秒等计算 + * @param calSrc 减数 + * @param calDes 被减数 + * @return 两个日期之间的差值 + */ + public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) { + + long millisDiff = getMillis(calSrc) - getMillis(calDes); + + if (flag == 'y') { + return (calSrc.get(Calendar.YEAR) - calDes.get(Calendar.YEAR)); + } + + if (flag == 'd') { + return (int) (millisDiff / DAY_IN_MILLIS); + } + + if (flag == 'h') { + return (int) (millisDiff / HOUR_IN_MILLIS); + } + + if (flag == 'm') { + return (int) (millisDiff / MINUTE_IN_MILLIS); + } + + if (flag == 's') { + return (int) (millisDiff / SECOND_IN_MILLIS); + } + + return 0; + } + + public static Long getCurrentTimestamp() { + return Long.valueOf(DateUtils.yyyymmddhhmmss.get().format(new Date())); + } + + /** + * String类型 转换为Date, 如果参数长度为10 转换格式”yyyy-MM-dd“ 如果参数长度为19 转换格式”yyyy-MM-dd + * HH:mm:ss“ * @param text String类型的时间值 + */ + @Override + public void setAsText(String text) throws IllegalArgumentException { + if (StringUtils.hasText(text)) { + try { + if (text.indexOf(":") == -1 && text.length() == 10) { + setValue(DateUtils.date_sdf.get().parse(text)); + } else if (text.indexOf(":") > 0 && text.length() == 19) { + setValue(DateUtils.datetimeFormat.get().parse(text)); + } else { + throw new IllegalArgumentException("Could not parse date, date format is error "); + } + } catch (ParseException ex) { + IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage()); + iae.initCause(ex); + throw iae; + } + } else { + setValue(null); + } + } + + public static int getYear() { + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(getDate()); + return calendar.get(Calendar.YEAR); + } + +} \ No newline at end of file