From 58e71449b4afd96a732080872d899edc2d109e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Tue, 3 Dec 2024 17:31:26 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E4=BA=A7=E5=93=81=E6=88=90=E6=9C=AC?= =?UTF-8?q?=E5=88=86=E6=9E=90):=20BOM=E7=BB=84=E4=BB=B6=E6=88=90=E6=9C=AC?= =?UTF-8?q?=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/RedisTemplateConfig.java | 13 + .../technology/constant/BomConstant.java | 5 + .../mapper/master/EBomChildMapper.java | 7 + .../mapper/master/EBomParentMapper.java | 7 + .../mapper/master/MaterialMainMapper.java | 12 + .../pojo/BomCostCalculateConfig.java | 15 + .../technology/pojo/dto/EBomCostCacheDTO.java | 123 +++++++ .../product/technology/pojo/dto/EBomDTO.java | 69 ++++ .../pojo/dto/ProductionCostDTO.java | 20 ++ .../pojo/entity/EBomChildEntity.java | 104 ++++++ .../pojo/entity/EBomParentEntity.java | 90 +++++ .../pojo/entity/MaterialMainEntity.java | 111 ++++++ .../pojo/query/VirtualWorkingManday.java | 7 + .../pojo/vo/BomCostMultilayerVO.java | 68 +--- .../service/BomCostCalculateService.java | 320 ++++++++++++++++++ .../technology/service/EBomChildService.java | 12 + .../technology/service/EBomParentService.java | 12 + .../technology/service/EBomService.java | 42 +++ .../service/MaterialMainService.java | 20 ++ .../service/PaintCostConfigService.java | 4 + .../service/ProductCostAnalysisService.java | 162 +++++++-- .../service/SteelsCostConfigService.java | 4 + .../service/VirtualWorkingService.java | 3 + .../product/technology/util/JsonUtil.java | 28 ++ .../src/main/resources/logback-sit.xml | 3 +- .../mapper/master/EBomChildMapper.xml | 5 + .../mapper/master/EBomParentMapper.xml | 5 + .../mapper/master/MaterialMainMapper.xml | 17 + 28 files changed, 1195 insertions(+), 93 deletions(-) create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/constant/BomConstant.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/EBomChildMapper.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/EBomParentMapper.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/MaterialMainMapper.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/BomCostCalculateConfig.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/dto/EBomCostCacheDTO.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/dto/EBomDTO.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/dto/ProductionCostDTO.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/entity/EBomChildEntity.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/entity/EBomParentEntity.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/entity/MaterialMainEntity.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/BomCostCalculateService.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/EBomChildService.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/EBomParentService.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/EBomService.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/MaterialMainService.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/util/JsonUtil.java create mode 100644 nflg_project_dev/nflg-technology/src/main/resources/mapper/master/EBomChildMapper.xml create mode 100644 nflg_project_dev/nflg-technology/src/main/resources/mapper/master/EBomParentMapper.xml create mode 100644 nflg_project_dev/nflg-technology/src/main/resources/mapper/master/MaterialMainMapper.xml diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/config/RedisTemplateConfig.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/config/RedisTemplateConfig.java index cfbc4e64..1b9c527f 100644 --- a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/config/RedisTemplateConfig.java +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/config/RedisTemplateConfig.java @@ -3,6 +3,7 @@ package com.nflg.product.technology.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; +import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; @@ -27,4 +28,16 @@ public class RedisTemplateConfig { return redisTemplate; } + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory factory) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(factory); + + // 设置 key 和 value 的序列化方式 + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(new StringRedisSerializer()); + + return template; + } + } diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/constant/BomConstant.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/constant/BomConstant.java new file mode 100644 index 00000000..1028397c --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/constant/BomConstant.java @@ -0,0 +1,5 @@ +package com.nflg.product.technology.constant; + +public class BomConstant { + public static final String PROJECT_TYPE_TEMPORARY = "T"; +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/EBomChildMapper.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/EBomChildMapper.java new file mode 100644 index 00000000..2d662750 --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/EBomChildMapper.java @@ -0,0 +1,7 @@ +package com.nflg.product.technology.mapper.master; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.nflg.product.technology.pojo.entity.EBomChildEntity; + +public interface EBomChildMapper extends BaseMapper { +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/EBomParentMapper.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/EBomParentMapper.java new file mode 100644 index 00000000..ab0f945d --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/EBomParentMapper.java @@ -0,0 +1,7 @@ +package com.nflg.product.technology.mapper.master; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.nflg.product.technology.pojo.entity.EBomParentEntity; + +public interface EBomParentMapper extends BaseMapper { +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/MaterialMainMapper.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/MaterialMainMapper.java new file mode 100644 index 00000000..a6008d1e --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/MaterialMainMapper.java @@ -0,0 +1,12 @@ +package com.nflg.product.technology.mapper.master; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.nflg.product.technology.pojo.dto.EBomDTO; +import com.nflg.product.technology.pojo.entity.MaterialMainEntity; + +import java.util.List; +import java.util.Set; + +public interface MaterialMainMapper extends BaseMapper { + List getInfos(Set materialNos); +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/BomCostCalculateConfig.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/BomCostCalculateConfig.java new file mode 100644 index 00000000..0455df37 --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/BomCostCalculateConfig.java @@ -0,0 +1,15 @@ +package com.nflg.product.technology.pojo; + +import com.nflg.product.technology.pojo.entity.VirtualWorkingEntity; +import com.nflg.product.technology.pojo.query.VirtualWorkingManday; +import lombok.Data; + +import java.util.List; + +@Data +public class BomCostCalculateConfig { + + private List virtualWorkings; + + private VirtualWorkingManday manday; +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/dto/EBomCostCacheDTO.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/dto/EBomCostCacheDTO.java new file mode 100644 index 00000000..862defed --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/dto/EBomCostCacheDTO.java @@ -0,0 +1,123 @@ +package com.nflg.product.technology.pojo.dto; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +@Data +public class EBomCostCacheDTO implements Serializable { + + /** + * 物料编码 + */ + private String materialNo; + + /** + * 钢材成本 + */ + private BigDecimal steelsCost = BigDecimal.ZERO; + + /** + * 外购件成本 + */ + private BigDecimal purchasedPartsCost = BigDecimal.ZERO; + + /** + * 标准计件工资 + */ + private BigDecimal pieceRateSalary = BigDecimal.ZERO; + + /** + * 福利费用 + */ + private BigDecimal welfareExpenses = BigDecimal.ZERO; + + /** + * 水电生产耗材成本 + */ + private BigDecimal hydropowerCost = BigDecimal.ZERO; + + /** + * 折旧成本 + */ + private BigDecimal depreciationCost = BigDecimal.ZERO; + + /** + * 车间管理人工费 + */ + private BigDecimal workshopManagementLaborCost = BigDecimal.ZERO; + + /** + * 车间办公室费用 + */ + private BigDecimal workshopOfficeExpenses = BigDecimal.ZERO; + + /** + * 辅助部门人工费 + */ + private BigDecimal auxiliaryDepartmentLaborCost = BigDecimal.ZERO; + + /** + * 辅助部门费用 + */ + private BigDecimal auxiliaryDepartmentExpenses = BigDecimal.ZERO; + + /** + * 油漆成本 + */ + private BigDecimal paintCost = BigDecimal.ZERO; + + /** + * 制作成本 + */ + private List productionCosts; + + /** + * 是否外购件 + */ + private boolean isPurchasedParts; + + /** + * 材料成本 + */ + @JsonIgnore + private BigDecimal materialCost; + + public BigDecimal getMaterialCost() { + return getSteelsCost().add(getPurchasedPartsCost()); + } + + /** + * 直接人工制做成本 + */ + @JsonIgnore + private BigDecimal directManualProductionCost; + + public BigDecimal getDirectManualProductionCost() { + return getPieceRateSalary().add(getWelfareExpenses()); + } + + /** + * 辅助制造成本 + */ + @JsonIgnore + private BigDecimal auxiliaryManufacturingCost; + + public BigDecimal getAuxiliaryManufacturingCost() { + return getHydropowerCost().add(getDepreciationCost()).add(getWorkshopManagementLaborCost()) + .add(getWorkshopOfficeExpenses()).add(getAuxiliaryDepartmentLaborCost()).add(getAuxiliaryDepartmentExpenses()); + } + + /** + * 产品总成本 + */ + @JsonIgnore + private BigDecimal totalCost; + + public BigDecimal getTotalCost() { + return getMaterialCost().add(getDirectManualProductionCost()).add(getAuxiliaryManufacturingCost()).add(getPaintCost()); + } +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/dto/EBomDTO.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/dto/EBomDTO.java new file mode 100644 index 00000000..2eb498b7 --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/dto/EBomDTO.java @@ -0,0 +1,69 @@ +package com.nflg.product.technology.pojo.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class EBomDTO { + + /** + * 物料编码 + */ + private String materialNo; + + /** + * 图号 + */ + private String drawingNo; + + /** + * 物料描述 + */ + private String materialDesc; + + /** + * 单位 + */ + private String materialUnit; + + /** + * 单重 + */ + private BigDecimal unitWeight; + + /** + * 最近采购价格 + */ + private BigDecimal lastPurchasePrice; + + /** + * 物料分类编码 + */ + private String materialCategoryCode; + + /** + * 物料分类名称 + */ + private String categoryName; + + /** + * 关联物料分类编码 + */ + private String relCategoryCode; + + /** + * 版本号 + */ + private String currentVersion; + + /** + * 数量 + */ + private BigDecimal num; + + /** + * 父物料编码 + */ + private String parentMaterialNo; +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/dto/ProductionCostDTO.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/dto/ProductionCostDTO.java new file mode 100644 index 00000000..613cd264 --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/dto/ProductionCostDTO.java @@ -0,0 +1,20 @@ +package com.nflg.product.technology.pojo.dto; + +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +@Data +public class ProductionCostDTO implements Serializable { + + /** + * 费用名称 + */ + private String name; + + /** + * 成本 + */ + private BigDecimal cost = BigDecimal.ZERO; +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/entity/EBomChildEntity.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/entity/EBomChildEntity.java new file mode 100644 index 00000000..1b3b8bac --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/entity/EBomChildEntity.java @@ -0,0 +1,104 @@ +package com.nflg.product.technology.pojo.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.math.BigDecimal; + +@Data +@Accessors(chain = true) +@ApiModel(value = "com-nflg-product-technology-pojo-entity-EBomChildEntity") +@TableName(value = "t_bom_new_ebom_child") +public class EBomChildEntity implements Serializable { + + /** + * 主键-雪花 + */ + @TableId(value = "row_id", type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键-雪花") + private Long rowId; + + /** + * 父行ID + */ + @TableField(value = "parent_row_id") + @ApiModelProperty(value = "父行ID") + private Long parentRowId; + + /** + * 排序号 + */ + @TableField(value = "order_number") + @ApiModelProperty(value = "排序号") + private String orderNumber; + + // /** + // * 图号 + // */ + // @TableField(value = "drawing_no") + // @ApiModelProperty(value = "图号") + // private String drawingNo; + + /** + * 物料编码 + */ + @TableField(value = "material_no") + @ApiModelProperty(value = "物料编码") + private String materialNo; + + // /** + // * 物料描述 + // */ + // @TableField(value = "material_desc") + // @ApiModelProperty(value = "物料描述") + // private String materialDesc; + + /** + * 单位 + */ + @TableField(value = "material_unit") + @ApiModelProperty(value = "单位") + private String materialUnit; + + // /** + // * 物料分类编码 + // */ + // @TableField(value = "material_category_code") + // @ApiModelProperty(value = "物料分类编码") + // private String materialCategoryCode; + + /** + * 单重 + */ + @TableField(value = "unit_weight") + @ApiModelProperty(value = "单重") + private BigDecimal unitWeight; + + /** + * 数量 + */ + @TableField(value = "num") + @ApiModelProperty(value = "数量") + private BigDecimal num; + + // /** + // * 总重 + // */ + // @TableField(value = "total_weight") + // @ApiModelProperty(value = "总重") + // private BigDecimal totalWeight; + + /** + * 项目类型 + */ + @TableField(value = "project_type") + @ApiModelProperty(value = "项目类型") + private String projectType; +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/entity/EBomParentEntity.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/entity/EBomParentEntity.java new file mode 100644 index 00000000..d611d7c1 --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/entity/EBomParentEntity.java @@ -0,0 +1,90 @@ +package com.nflg.product.technology.pojo.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.math.BigDecimal; + +@Data +@Accessors(chain = true) +@ApiModel(value = "com-nflg-product-technology-pojo-entity-EBomParentEntity") +@TableName(value = "t_bom_new_ebom_parent") +public class EBomParentEntity implements Serializable { + + /** + * 主键行ID-雪花 + */ + @TableId(value = "row_id", type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键行ID-雪花") + private Long rowId; + + // /** + // * 图号 + // */ + // @TableField(value = "drawing_no") + // @ApiModelProperty(value = "图号") + // private String drawingNo; + + /** + * 物料编码 + */ + @TableField(value = "material_no") + @ApiModelProperty(value = "物料编码") + private String materialNo; + + // /** + // * 物料描述 + // */ + // @TableField(value = "material_desc") + // @ApiModelProperty(value = "物料描述") + // private String materialDesc; + + /** + * 单位 + */ + @TableField(value = "material_unit") + @ApiModelProperty(value = "单位") + private String materialUnit; + + /** + * 单重 + */ + @TableField(value = "unit_weight") + @ApiModelProperty(value = "单重") + private BigDecimal unitWeight; + + // /** + // * 总重 + // */ + // @TableField(value = "total_weight") + // @ApiModelProperty(value = "总重") + // private BigDecimal totalWeight; + + /** + * 版本号 + */ + @TableField(value = "current_version") + @ApiModelProperty(value = "版本号") + private String currentVersion; + + /** + * 数量 + */ + @TableField(value = "num") + @ApiModelProperty(value = "数量") + private BigDecimal num; + + /** + * 1=待复核、2=已复核、3=已退回、4=定版(已发布PBOM) + */ + @TableField(value = "status") + @ApiModelProperty(value = "1=待复核、2=已复核、3=已退回、4=定版(已发布PBOM)") + private Integer status; +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/entity/MaterialMainEntity.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/entity/MaterialMainEntity.java new file mode 100644 index 00000000..09a7ea86 --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/entity/MaterialMainEntity.java @@ -0,0 +1,111 @@ +package com.nflg.product.technology.pojo.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.math.BigDecimal; + +@Data +@Accessors(chain = true) +@ApiModel(value = "com-nflg-product-technology-pojo-main-entity-MaterialMainEntity") +@TableName(value = "t_material_main") +public class MaterialMainEntity implements Serializable { + + /** + * 行ID 雪花 + */ + @TableId(value = "row_id", type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "行ID 雪花") + private Long rowId; + + /** + * 物料编码 + */ + @TableField(value = "material_no") + @ApiModelProperty(value = "物料编码") + private String materialNo; + + /** + * 物料描述 + */ + @TableField(value = "material_desc") + @ApiModelProperty(value = "物料描述") + private String materialDesc; + + /** + * 物料分类编码 + */ + @TableField(value = "material_category_code") + @ApiModelProperty(value = "物料分类编码") + private String materialCategoryCode; + + /** + * 图号 + */ + @TableField(value = "drawing_no") + @ApiModelProperty(value = "图号") + private String drawingNo; + + /** + * 重量-kg + */ + @TableField(value = "material_weight") + @ApiModelProperty(value = "重量-kg") + private String materialWeight; + + /** + * 基本计量单位 + */ + @TableField(value = "material_unit") + @ApiModelProperty(value = "基本计量单位") + private String materialUnit; + + /** + * 物料类型:0:外购 1:自制 + */ + @TableField(value = "material_type") + @ApiModelProperty(value = "物料类型:0:外购 1:自制") + private Integer materialType; + + /** + * 库存量 + */ + @TableField(value = "material_stock") + @ApiModelProperty(value = "库存量") + private BigDecimal materialStock; + + /** + * 最近采购价格 + */ + @TableField(value = "last_purchase_price") + @ApiModelProperty(value = "最近采购价格") + private BigDecimal lastPurchasePrice; + + /** + * 订单保护价 + */ + @TableField(value = "order_protect_price") + @ApiModelProperty(value = "订单保护价") + private BigDecimal orderProtectPrice; + + /** + * 物料状态 1:激活 2:禁止采购 3:售后专用 4:冻结 5:完全弃用 + */ + @TableField(value = "material_state") + @ApiModelProperty(value = "物料状态 1:激活 2:禁止采购 3:售后专用 4:冻结 5:完全弃用") + private Integer materialState; + + /** + * 制作物料获取类型:1=自制、2=外协、3=采购 + */ + @TableField(value = "material_get_type") + @ApiModelProperty(value = "制作物料获取类型:1=自制、2=外协、3=采购") + private Integer materialGetType; +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/query/VirtualWorkingManday.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/query/VirtualWorkingManday.java index 269e01a1..e227d9d1 100644 --- a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/query/VirtualWorkingManday.java +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/query/VirtualWorkingManday.java @@ -1,5 +1,8 @@ package com.nflg.product.technology.pojo.query; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.nflg.product.base.core.config.BigDecimalSerializer; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -21,9 +24,13 @@ public class VirtualWorkingManday implements Serializable { @ApiModelProperty("计件人工工时工资(一线)") @Positive(message = "计件人工工时工资(一线)必须大于0") + @JsonFormat(pattern = "#.##") + @JsonSerialize(using = BigDecimalSerializer.class) private BigDecimal hourlyWages; @ApiModelProperty("一线人工福利") @Min(value = 0, message = "一线人工福利必须大于等于0") + @JsonFormat(pattern = "#.##") + @JsonSerialize(using = BigDecimalSerializer.class) private BigDecimal benefit; } diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/vo/BomCostMultilayerVO.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/vo/BomCostMultilayerVO.java index 3bb7dbe1..06bd6bc4 100644 --- a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/vo/BomCostMultilayerVO.java +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/vo/BomCostMultilayerVO.java @@ -1,6 +1,5 @@ package com.nflg.product.technology.pojo.vo; -import com.nflg.product.technology.util.RandomUtil; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -8,6 +7,7 @@ import lombok.experimental.Accessors; import java.io.Serializable; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.List; /** @@ -22,115 +22,51 @@ public class BomCostMultilayerVO implements Serializable { @ApiModelProperty("物料编码") private String materialNo; - public String getMaterialNo() { - return RandomUtil.randomString(10); - } - @ApiModelProperty("物料描述") private String materialDesc; - public String getMaterialDesc() { - return RandomUtil.randomString(20); - } - @ApiModelProperty("物料类别") private String materialCategoryName; - public String getMaterialCategoryName() { - return RandomUtil.randomString(10); - } - @ApiModelProperty("单位") private String materialUnit; - public String getMaterialUnit() { - return "PC"; - } - @ApiModelProperty("单件成本") private BigDecimal price; - public BigDecimal getPrice() { - return RandomUtil.randomBigDecimal(1000, 2); - } - @ApiModelProperty("单层数量") private BigDecimal num; - public BigDecimal getNum() { - return RandomUtil.randomBigDecimal(100, 2); - } - @ApiModelProperty("累乘数量") private BigDecimal totalNum; - public BigDecimal getTotalNum() { - return RandomUtil.randomBigDecimal(1000, 2); - } - @ApiModelProperty("总成本") private BigDecimal totalCost; - public BigDecimal getTotalCost() { - return RandomUtil.randomBigDecimal(100000, 2); - } - @ApiModelProperty("单件材料成本") private BigDecimal materialCost; - public BigDecimal getMaterialCost() { - return RandomUtil.randomBigDecimal(100000, 2); - } - @ApiModelProperty("材料成本") private BigDecimal totalMaterialCost; - public BigDecimal getTotalMaterialCost() { - return RandomUtil.randomBigDecimal(100000, 2); - } - @ApiModelProperty("单件油漆成本") private BigDecimal paintCost; - public BigDecimal getPaintCost() { - return RandomUtil.randomBigDecimal(100000, 2); - } - @ApiModelProperty("油漆成本") private BigDecimal totalPaintCost; - public BigDecimal getTotalPaintCost() { - return RandomUtil.randomBigDecimal(100000, 2); - } - @ApiModelProperty("单件标准人工工资") private BigDecimal standardPieceRateSalary; - public BigDecimal getStandardPieceRateSalary() { - return RandomUtil.randomBigDecimal(100000, 2); - } - @ApiModelProperty("标准人工工资") private BigDecimal totalStandardPieceRateSalary; - public BigDecimal getTotalStandardPieceRateSalary() { - return RandomUtil.randomBigDecimal(100000, 2); - } - @ApiModelProperty("单件辅助费用") private BigDecimal auxiliaryManufacturingCost; - public BigDecimal getAuxiliaryManufacturingCost() { - return RandomUtil.randomBigDecimal(100000, 2); - } - @ApiModelProperty("辅助费用") private BigDecimal totalAuxiliaryManufacturingCost; - public BigDecimal getTotalAuxiliaryManufacturingCost() { - return RandomUtil.randomBigDecimal(100000, 2); - } - @ApiModelProperty("子物料列表") - private List children; + private List children = new ArrayList<>(); } diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/BomCostCalculateService.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/BomCostCalculateService.java new file mode 100644 index 00000000..f2eb22c0 --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/BomCostCalculateService.java @@ -0,0 +1,320 @@ +package com.nflg.product.technology.service; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.StrUtil; +import com.nflg.product.technology.constant.BomConstant; +import com.nflg.product.technology.pojo.BomCostCalculateConfig; +import com.nflg.product.technology.pojo.dto.EBomCostCacheDTO; +import com.nflg.product.technology.pojo.dto.EBomDTO; +import com.nflg.product.technology.pojo.dto.ProductionCostDTO; +import com.nflg.product.technology.pojo.entity.*; +import com.nflg.product.technology.pojo.query.VirtualWorkingManday; +import com.nflg.product.technology.util.JsonUtil; +import com.nflg.product.technology.util.VUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.time.Duration; +import java.util.*; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class BomCostCalculateService { + + @Resource + private EBomService ebomService; + + @Resource + private MaterialMainService materialMainService; + + @Resource + private SteelsCostConfigService steelsCostConfigService; + + @Resource + private PaintCostConfigService paintCostConfigService; + + @Resource + private RedisTemplate redisTemplate; + + /** + * 缓存时长 + */ + private static final Duration CACHE_DURATION = Duration.ofHours(1); + + /** + * 钢件类别 + */ + private static final List STEELS_CATEGORY_CODE = Arrays.asList("10010101", "10010102", "10010103", "10010104", "10010105", "10010110"); + + public List calculate(String materialNo, BomCostCalculateConfig config) { + VUtils.isTure(StrUtil.isBlank(materialNo)).throwMessage("物料编号不能为空"); + List datas = new ArrayList<>(); + EBomParentEntity parent = ebomService.getParent(materialNo); + VUtils.isTure(Objects.isNull(parent)).throwMessage("未找到BOM: " + materialNo); + log.debug(StrUtil.format("BOM成本计算 {} 起始节点", materialNo)); + EBomDTO pDto = convert(parent); + datas.add(pDto); + getChildren(materialNo, datas); + List result = new ArrayList<>(50); + calculateBom(pDto, datas, config, result); + return result; + } + + private EBomCostCacheDTO calculateBom(EBomDTO dto, List datas, BomCostCalculateConfig config, List result) { + String cdata = redisTemplate.opsForValue().get(buildKey(dto)); + List children = datas.stream() + .filter(d -> StrUtil.equals(d.getParentMaterialNo(), dto.getMaterialNo())) + .collect(Collectors.toList()); + if (StrUtil.isBlank(cdata)) { + EBomCostCacheDTO cdto = new EBomCostCacheDTO(); + cdto.setMaterialNo(dto.getMaterialNo()); + cdto.setPurchasedParts(!STEELS_CATEGORY_CODE.contains(dto.getMaterialCategoryCode())); + if (CollectionUtil.isEmpty(children)) { + //没有子级,直接计算成本 + log.debug(StrUtil.format("BOM成本计算 {} 直接计算", dto.getMaterialNo())); + if (cdto.isPurchasedParts()) { + cdto.setPurchasedPartsCost(calculatePurchasedPartsCost(dto)); + } else { + cdto.setSteelsCost(calculateSteelsCost(dto)); + cdto.setPieceRateSalary(calculatePieceRateSalary(dto, config.getManday())); + cdto.setWelfareExpenses(calculateWelfareExpenses(dto, config.getManday())); + cdto.setHydropowerCost(calculateHydropowerCost(config.getVirtualWorkings())); + cdto.setDepreciationCost(calculateDepreciationCost(config.getVirtualWorkings())); + cdto.setWorkshopManagementLaborCost(calculateWorkshopManagementLaborCost(config.getVirtualWorkings())); + cdto.setWorkshopOfficeExpenses(calculateWorkshopOfficeExpenses(config.getVirtualWorkings())); + cdto.setAuxiliaryDepartmentLaborCost(calculateAuxiliaryDepartmentLaborCost(config.getVirtualWorkings())); + cdto.setAuxiliaryDepartmentExpenses(calculateAuxiliaryDepartmentExpenses(config.getVirtualWorkings())); + cdto.setPaintCost(calculatePaintCost(dto)); + cdto.setProductionCosts(calculateProductionCosts(config)); + } + } else { + //有子级,先计算子级成本 + List childrenCost = children.stream() + .map(c -> calculateBom(c, datas, config, result)) + .collect(Collectors.toList()); + List productionCosts = new ArrayList<>(); + for (EBomCostCacheDTO c : childrenCost) { + EBomDTO dto1 = children.stream().filter(cc -> StrUtil.equals(cc.getMaterialNo(), c.getMaterialNo())).findFirst().orElse(null); + cdto.setSteelsCost(cdto.getSteelsCost().add(c.getSteelsCost().multiply(dto1.getNum()))); + cdto.setPurchasedPartsCost(cdto.getPurchasedPartsCost().add(c.getPurchasedPartsCost().multiply(dto1.getNum()))); + cdto.setPieceRateSalary(cdto.getPieceRateSalary().add(c.getPieceRateSalary().multiply(dto1.getNum()))); + cdto.setWelfareExpenses(cdto.getWelfareExpenses().add(c.getWelfareExpenses().multiply(dto1.getNum()))); + cdto.setHydropowerCost(cdto.getHydropowerCost().add(c.getHydropowerCost().multiply(dto1.getNum()))); + cdto.setDepreciationCost(cdto.getDepreciationCost().add(c.getDepreciationCost().multiply(dto1.getNum()))); + cdto.setWorkshopManagementLaborCost(cdto.getWorkshopManagementLaborCost().add(c.getWorkshopManagementLaborCost().multiply(dto1.getNum()))); + cdto.setWorkshopOfficeExpenses(cdto.getWorkshopOfficeExpenses().add(c.getWorkshopOfficeExpenses().multiply(dto1.getNum()))); + cdto.setAuxiliaryDepartmentLaborCost(cdto.getAuxiliaryDepartmentLaborCost().add(c.getAuxiliaryDepartmentLaborCost().multiply(dto1.getNum()))); + cdto.setAuxiliaryDepartmentExpenses(cdto.getAuxiliaryDepartmentExpenses().add(c.getAuxiliaryDepartmentExpenses().multiply(dto1.getNum()))); + cdto.setPaintCost(cdto.getPaintCost().add(c.getPaintCost().multiply(dto1.getNum()))); + if (CollectionUtil.isNotEmpty(cdto.getProductionCosts())) { + cdto.getProductionCosts().forEach(pc -> { + ProductionCostDTO pdto = productionCosts.stream() + .filter(p -> StrUtil.equals(p.getName(), pc.getName())) + .findFirst() + .orElse(null); + if (Objects.isNull(pdto)) { + pdto = new ProductionCostDTO(); + pdto.setName(pc.getName()); + productionCosts.add(pdto); + } + pdto.setCost(pdto.getCost().add(pc.getCost().multiply(dto1.getNum()))); + }); + cdto.setProductionCosts(productionCosts); + } + } + log.debug(StrUtil.format("BOM成本计算 {} 根据子级计算", dto.getMaterialNo())); + } + result.add(cdto); + cdata = JsonUtil.toJson(cdto); + log.debug(cdata); + redisTemplate.opsForValue().set(buildKey(dto), cdata, CACHE_DURATION); + return cdto; + } else { + log.debug(StrUtil.format("BOM成本计算 {} 从缓存读取", dto.getMaterialNo())); + log.debug(cdata); + EBomCostCacheDTO cdto = JsonUtil.fromJson(cdata, EBomCostCacheDTO.class); + result.add(cdto); + children.forEach(c -> calculateBom(c, datas, config, result)); + return cdto; + } + } + + private List calculateProductionCosts(BomCostCalculateConfig config) { + List productionCosts = new ArrayList<>(); + BigDecimal hourlyWages; + BigDecimal benefit; + BigDecimal auxiliaryMaterialsAndConsumables; + BigDecimal feeEquipmentDepreciation; + BigDecimal feeWorkshopLaborCost; + BigDecimal feeWorkshopOffice; + BigDecimal auxiliaryDepartmentLaborCosts; + BigDecimal assistantFee; + for (VirtualWorkingEntity vw : config.getVirtualWorkings()) { + ProductionCostDTO dto = new ProductionCostDTO(); + dto.setName(vw.getName()); + hourlyWages = Optional.ofNullable(config.getManday().getHourlyWages()).orElse(BigDecimal.ZERO); + benefit = Optional.ofNullable(config.getManday().getBenefit()).orElse(BigDecimal.ZERO); + auxiliaryMaterialsAndConsumables = Optional.ofNullable(vw.getConsumablesFee()).orElse(BigDecimal.ZERO); + feeEquipmentDepreciation = Optional.ofNullable(vw.getEquipmentDepreciationFee()).orElse(BigDecimal.ZERO); + feeWorkshopLaborCost = Optional.ofNullable(vw.getWorkshopLaborFee()).orElse(BigDecimal.ZERO); + feeWorkshopOffice = Optional.ofNullable(vw.getWorkshopOfficeFee()).orElse(BigDecimal.ZERO); + auxiliaryDepartmentLaborCosts = Optional.ofNullable(vw.getAssistantLaborFee()).orElse(BigDecimal.ZERO); + assistantFee = Optional.ofNullable(vw.getAssistantFee()).orElse(BigDecimal.ZERO); + dto.setCost(hourlyWages.add(benefit).add(auxiliaryMaterialsAndConsumables).add(feeEquipmentDepreciation) + .add(feeEquipmentDepreciation).add(feeWorkshopLaborCost).add(feeWorkshopOffice) + .add(auxiliaryDepartmentLaborCosts).add(assistantFee) + .multiply(getGsForWorkingType(vw.getName()))); + } + return productionCosts; + } + + private BigDecimal calculatePaintCost(EBomDTO dto) { + String lable = "";// TODO 物料标签对应的油漆标签 + PaintCostConfigEntity entity = paintCostConfigService.getCost(lable); + if (Objects.nonNull(entity)) { + return NumberUtil.mul(dto.getUnitWeight(), entity.getCost()); + } else { + return BigDecimal.ZERO; + } + } + + private BigDecimal calculateWorkshopOfficeExpenses(List virtualWorkings) { + BigDecimal cost = BigDecimal.ZERO; + for (VirtualWorkingEntity vw : virtualWorkings) { + cost = cost.add(vw.getWorkshopOfficeFee().multiply(getGsForWorkingType(vw.getName()))); + } + return cost; + } + + private BigDecimal calculateAuxiliaryDepartmentExpenses(List virtualWorkings) { + BigDecimal cost = BigDecimal.ZERO; + for (VirtualWorkingEntity vw : virtualWorkings) { + cost = cost.add(vw.getAssistantFee().multiply(getGsForWorkingType(vw.getName()))); + } + return cost; + } + + private BigDecimal calculateAuxiliaryDepartmentLaborCost(List virtualWorkings) { + BigDecimal cost = BigDecimal.ZERO; + for (VirtualWorkingEntity vw : virtualWorkings) { + cost = cost.add(vw.getAssistantLaborFee().multiply(getGsForWorkingType(vw.getName()))); + } + return cost; + } + + private BigDecimal calculateWorkshopManagementLaborCost(List virtualWorkings) { + BigDecimal cost = BigDecimal.ZERO; + for (VirtualWorkingEntity vw : virtualWorkings) { + cost = cost.add(vw.getWorkshopLaborFee().multiply(getGsForWorkingType(vw.getName()))); + } + return cost; + } + + private BigDecimal calculateDepreciationCost(List virtualWorkings) { + BigDecimal cost = BigDecimal.ZERO; + for (VirtualWorkingEntity vw : virtualWorkings) { + cost = cost.add(vw.getEquipmentDepreciationFee().multiply(getGsForWorkingType(vw.getName()))); + } + return cost; + } + + private BigDecimal calculateHydropowerCost(List virtualWorkings) { + BigDecimal cost = BigDecimal.ZERO; + for (VirtualWorkingEntity vw : virtualWorkings) { + cost = cost.add(vw.getConsumablesFee().multiply(getGsForWorkingType(vw.getName()))); + } + return cost; + } + + private BigDecimal getGsForWorkingType(String type) { + //TODO 获取工时类型对应的工时 + return BigDecimal.ZERO; + } + + private BigDecimal calculateWelfareExpenses(EBomDTO dto, VirtualWorkingManday manday) { + return getTGS().multiply(Optional.ofNullable(manday.getBenefit()).orElse(BigDecimal.ZERO)); + } + + private BigDecimal calculatePieceRateSalary(EBomDTO dto, VirtualWorkingManday manday) { + return getTGS().multiply(Optional.ofNullable(manday.getHourlyWages()).orElse(BigDecimal.ZERO)); + } + + private BigDecimal getTGS() { + // TODO 获取总工时 + return BigDecimal.ZERO; + } + + private BigDecimal calculatePurchasedPartsCost(EBomDTO dto) { + return Optional.ofNullable(dto.getLastPurchasePrice()).orElse(BigDecimal.ZERO); + } + + private BigDecimal calculateSteelsCost(EBomDTO dto) { + //是钢材 + // TODO 物料标签是哪个字段?单价是哪个字段? + BigDecimal price = Optional.ofNullable(dto.getLastPurchasePrice()).orElse(BigDecimal.ZERO); + BigDecimal unitWeight = Optional.ofNullable(dto.getUnitWeight()).orElse(BigDecimal.ZERO); + BigDecimal wastage = BigDecimal.ZERO; + String lable = "物料标签"; + if (StrUtil.isNotBlank(lable)) { + SteelsCostConfigEntity steelsCostConfigEntity = steelsCostConfigService.getCost(lable); + if (Objects.nonNull(steelsCostConfigEntity)) { + price = Optional.ofNullable(steelsCostConfigEntity.getCost()).orElse(BigDecimal.ZERO); + wastage = Optional.ofNullable(steelsCostConfigEntity.getWastage()).orElse(BigDecimal.ZERO); + } + } + return price.multiply(BigDecimal.ONE.add(wastage).multiply(unitWeight)); + } + + private String buildKey(EBomDTO dto) { + return StrUtil.format("technology:cost:{}:{}", dto.getMaterialNo() + , StrUtil.isBlank(dto.getCurrentVersion()) ? "A00" : dto.getCurrentVersion()); + } + + private void getChildren(String materialNo, List datas) { + EBomParentEntity parent = ebomService.getParent(materialNo); + if (Objects.nonNull(parent)) { + List children = ebomService.getChildren(parent.getRowId()); + if (CollectionUtil.isNotEmpty(children)) { + datas.addAll(convert(children, parent.getMaterialNo())); + children.forEach(c -> { + getChildren(c.getMaterialNo(), datas); + }); + } + } + } + + private EBomDTO convert(EBomParentEntity entity) { + List mainEntities = materialMainService.getInfos(Collections.singleton(entity.getMaterialNo())); + VUtils.isTure(CollectionUtil.isEmpty(mainEntities)).throwMessage("未找到主物料: " + entity.getMaterialNo()); + EBomDTO dto = mainEntities.get(0); + dto.setNum(entity.getNum()); + dto.setCurrentVersion(entity.getCurrentVersion()); + return dto; + } + + private List convert(List children, String parentMaterialNo) { + Set materialNos = children.stream() + .filter(c -> !StrUtil.equals(c.getProjectType(), BomConstant.PROJECT_TYPE_TEMPORARY)) + .map(EBomChildEntity::getMaterialNo) + .collect(Collectors.toSet()); + List mainEntities = materialMainService.getInfos(materialNos); + materialNos.removeAll(mainEntities.stream().map(EBomDTO::getMaterialNo).collect(Collectors.toSet())); + VUtils.isTure(CollectionUtil.isNotEmpty(materialNos)).throwMessage(parentMaterialNo + "的下级物料不在主物料表中: " + String.join(",", materialNos)); + if (CollectionUtil.isNotEmpty(mainEntities)) { + mainEntities.forEach(e -> { + //相同编号合并数量 + e.setNum(children.stream() + .filter(c -> StrUtil.equals(c.getMaterialNo(), e.getMaterialNo())) + .map(EBomChildEntity::getNum) + .reduce(BigDecimal.ZERO, BigDecimal::add)); + e.setParentMaterialNo(parentMaterialNo); + }); + } + return mainEntities; + } +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/EBomChildService.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/EBomChildService.java new file mode 100644 index 00000000..a15c88bc --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/EBomChildService.java @@ -0,0 +1,12 @@ +package com.nflg.product.technology.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.nflg.product.technology.mapper.master.EBomChildMapper; +import com.nflg.product.technology.pojo.entity.EBomChildEntity; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class EBomChildService extends ServiceImpl { +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/EBomParentService.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/EBomParentService.java new file mode 100644 index 00000000..d01dd443 --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/EBomParentService.java @@ -0,0 +1,12 @@ +package com.nflg.product.technology.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.nflg.product.technology.mapper.master.EBomParentMapper; +import com.nflg.product.technology.pojo.entity.EBomParentEntity; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class EBomParentService extends ServiceImpl { +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/EBomService.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/EBomService.java new file mode 100644 index 00000000..618aa507 --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/EBomService.java @@ -0,0 +1,42 @@ +package com.nflg.product.technology.service; + +import com.nflg.product.technology.pojo.entity.EBomChildEntity; +import com.nflg.product.technology.pojo.entity.EBomParentEntity; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Set; + +@Component +@Slf4j +public class EBomService { + + @Resource + private EBomParentService ebomParentService; + + @Resource + private EBomChildService ebomChildService; + + public EBomParentEntity getParent(String materialNo) { + return ebomParentService.lambdaQuery() + .eq(EBomParentEntity::getMaterialNo, materialNo) + .ge(EBomParentEntity::getStatus, 4) + .one(); + } + + public List getParents(Set materialNos) { + return ebomParentService.lambdaQuery() + .in(EBomParentEntity::getMaterialNo, materialNos) + .ge(EBomParentEntity::getStatus, 4) + .list(); + } + + public List getChildren(long parentRowId) { + return ebomChildService.lambdaQuery() + .eq(EBomChildEntity::getParentRowId, parentRowId) + .orderByAsc(EBomChildEntity::getOrderNumber) + .list(); + } +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/MaterialMainService.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/MaterialMainService.java new file mode 100644 index 00000000..70462417 --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/MaterialMainService.java @@ -0,0 +1,20 @@ +package com.nflg.product.technology.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.nflg.product.technology.mapper.master.MaterialMainMapper; +import com.nflg.product.technology.pojo.dto.EBomDTO; +import com.nflg.product.technology.pojo.entity.MaterialMainEntity; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Set; + +@Component +@Slf4j +public class MaterialMainService extends ServiceImpl { + + public List getInfos(Set materialNos) { + return baseMapper.getInfos(materialNos); + } +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/PaintCostConfigService.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/PaintCostConfigService.java index bbfddbf5..5e24da64 100644 --- a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/PaintCostConfigService.java +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/PaintCostConfigService.java @@ -53,4 +53,8 @@ public class PaintCostConfigService extends ServiceImpl getBomCostSingleLayer(String materialNo) { - // TODO 待实现 - List list = new ArrayList<>(); - int count = RandomUtil.randomInt(0, 10); - for (int i = 0; i < count; i++) { - BomCostSingleLayerVO bomCostSingleLayerVO = new BomCostSingleLayerVO(); - bomCostSingleLayerVO.setMaterialNo("物料编号" + i); - bomCostSingleLayerVO.setPrice(RandomUtil.randomBigDecimal(10000, 2)); - bomCostSingleLayerVO.setNum(RandomUtil.randomBigDecimal(1000, 2)); - bomCostSingleLayerVO.setTotalPrice(RandomUtil.randomBigDecimal(1000, 2)); - bomCostSingleLayerVO.setMaterialDesc("物料描述" + i); - bomCostSingleLayerVO.setMaterialCategoryName("物料类别" + i); - bomCostSingleLayerVO.setMaterialUnit("PC"); - bomCostSingleLayerVO.setVersion("版本号" + i); - bomCostSingleLayerVO.setMaterialTotalPrice(RandomUtil.randomBigDecimal(1000, 2)); - bomCostSingleLayerVO.setLaborCosts(RandomUtil.randomBigDecimal(1000, 2)); - bomCostSingleLayerVO.setAuxiliaryManufacturingCost(RandomUtil.randomBigDecimal(1000, 2)); - list.add(bomCostSingleLayerVO); - } - return list; + BomCostCalculateConfig cnfig = new BomCostCalculateConfig(); + VirtualWorkingManday manday = new VirtualWorkingManday(); + manday.setHourlyWages(technologyConfigService.getHourlyWages()); + manday.setBenefit(technologyConfigService.getBenefit()); + cnfig.setManday(manday); + cnfig.setVirtualWorkings(virtualWorkingService.list()); + List datas = bomCostCalculateService.calculate(materialNo, cnfig); + EBomParentEntity parent = ebomService.getParent(materialNo); + return buildSingleLayerChildren(parent.getRowId(), datas); + } + + public List buildSingleLayerChildren(long parentRowId, List datas) { + List children = ebomService.getChildren(parentRowId); + Set materialNos = children.stream() + .filter(c -> !StrUtil.equals(c.getProjectType(), BomConstant.PROJECT_TYPE_TEMPORARY)) + .map(EBomChildEntity::getMaterialNo) + .collect(Collectors.toSet()); + List parents = ebomService.getParents(materialNos); + List vos = new ArrayList<>(MapUtil.calculateInitialCapacity(children.size())); + List materials = materialMainService.getInfos(materialNos); + children.forEach(child -> { + BomCostSingleLayerVO cvo = new BomCostSingleLayerVO(); + cvo.setMaterialNo(child.getMaterialNo()); + EBomDTO cpm = materials.stream().filter(m -> StrUtil.equals(m.getMaterialNo(), child.getMaterialNo())).findFirst().orElse(null); + if (Objects.nonNull(cpm)) { + cvo.setMaterialDesc(cpm.getMaterialDesc()); + cvo.setMaterialCategoryName(cpm.getCategoryName()); + cvo.setMaterialUnit(cpm.getMaterialUnit()); + } + EBomParentEntity parent = parents.stream().filter(p -> StrUtil.equals(p.getMaterialNo(), child.getMaterialNo())).findFirst().orElse(null); + cvo.setVersion(Objects.isNull(parent) ? "A00" : parent.getCurrentVersion()); + EBomCostCacheDTO ccost = datas.stream().filter(d -> StrUtil.equals(d.getMaterialNo(), child.getMaterialNo())).findFirst().orElse(null); + if (Objects.nonNull(ccost)) { + cvo.setPrice(ccost.getTotalCost()); + cvo.setNum(child.getNum()); + cvo.setTotalPrice(cvo.getPrice().multiply(cvo.getNum())); + cvo.setMaterialTotalPrice(ccost.getMaterialCost().multiply(cvo.getNum())); + cvo.setLaborCosts(ccost.getDirectManualProductionCost().multiply(cvo.getNum())); + cvo.setAuxiliaryManufacturingCost(ccost.getAuxiliaryManufacturingCost().multiply(cvo.getNum())); + } + vos.add(cvo); + }); + return vos; } public BomCostMultilayerVO getBomCostMultilayer(String materialNo) { - // TODO 待实现 + BomCostCalculateConfig cnfig = new BomCostCalculateConfig(); + VirtualWorkingManday manday = new VirtualWorkingManday(); + manday.setHourlyWages(technologyConfigService.getHourlyWages()); + manday.setBenefit(technologyConfigService.getBenefit()); + cnfig.setManday(manday); + cnfig.setVirtualWorkings(virtualWorkingService.list()); + List datas = bomCostCalculateService.calculate(materialNo, cnfig); + List materials = materialMainService.getInfos(datas.stream().map(EBomCostCacheDTO::getMaterialNo).collect(Collectors.toSet())); + EBomParentEntity parent = ebomService.getParent(materialNo); BomCostMultilayerVO vo = new BomCostMultilayerVO(); - List list = new ArrayList<>(); - int count = RandomUtil.randomInt(0, 10); - for (int i = 0; i < count; i++) { - BomCostMultilayerVO bomCostMultilayerVO = buildEBomCostMultilayerVO(); - list.add(bomCostMultilayerVO); + vo.setMaterialNo(parent.getMaterialNo()); + EBomDTO pm = materials.stream().filter(m -> StrUtil.equals(m.getMaterialNo(), parent.getMaterialNo())).findFirst().orElse(null); + if (Objects.nonNull(pm)) { + vo.setMaterialDesc(pm.getMaterialDesc()); + vo.setMaterialCategoryName(pm.getCategoryName()); + vo.setMaterialUnit(pm.getMaterialUnit()); } - vo.setChildren(list); + EBomCostCacheDTO cost = datas.stream().filter(d -> StrUtil.equals(d.getMaterialNo(), parent.getMaterialNo())).findFirst().orElse(null); + if (Objects.nonNull(cost)) { + vo.setPrice(cost.getTotalCost()); + vo.setNum(BigDecimal.ONE); + vo.setTotalNum(BigDecimal.ONE); + vo.setTotalCost(vo.getPrice()); + vo.setMaterialCost(cost.getMaterialCost()); + vo.setTotalMaterialCost(cost.getMaterialCost()); + vo.setPaintCost(cost.getPaintCost()); + vo.setTotalPaintCost(cost.getPaintCost()); + vo.setStandardPieceRateSalary(cost.getPieceRateSalary()); + vo.setTotalStandardPieceRateSalary(cost.getPieceRateSalary()); + vo.setAuxiliaryManufacturingCost(cost.getAuxiliaryManufacturingCost()); + vo.setTotalAuxiliaryManufacturingCost(cost.getAuxiliaryManufacturingCost()); + } + buildMultilayerChildren(parent.getRowId(), vo, materials, datas); return vo; } + private void buildMultilayerChildren(long parentRowId, BomCostMultilayerVO pvo, List materials, List datas) { + List children = ebomService.getChildren(parentRowId); + children.forEach(child -> { + BomCostMultilayerVO cvo = new BomCostMultilayerVO(); + cvo.setMaterialNo(child.getMaterialNo()); + EBomDTO cpm = materials.stream().filter(m -> StrUtil.equals(m.getMaterialNo(), child.getMaterialNo())).findFirst().orElse(null); + if (Objects.nonNull(cpm)) { + cvo.setMaterialDesc(cpm.getMaterialDesc()); + cvo.setMaterialCategoryName(cpm.getCategoryName()); + cvo.setMaterialUnit(cpm.getMaterialUnit()); + } + EBomCostCacheDTO ccost = datas.stream().filter(d -> StrUtil.equals(d.getMaterialNo(), child.getMaterialNo())).findFirst().orElse(null); + if (Objects.nonNull(ccost)) { + cvo.setPrice(ccost.getTotalCost()); + cvo.setNum(child.getNum()); + cvo.setTotalNum(cvo.getNum().multiply(pvo.getTotalNum())); + cvo.setTotalCost(cvo.getPrice().multiply(cvo.getTotalNum())); + cvo.setMaterialCost(ccost.getMaterialCost()); + cvo.setTotalMaterialCost(ccost.getMaterialCost().multiply(cvo.getTotalNum())); + cvo.setPaintCost(ccost.getPaintCost()); + cvo.setTotalPaintCost(ccost.getPaintCost().multiply(cvo.getTotalNum())); + cvo.setStandardPieceRateSalary(ccost.getPieceRateSalary().multiply(cvo.getTotalNum())); + cvo.setTotalStandardPieceRateSalary(ccost.getPieceRateSalary()); + cvo.setAuxiliaryManufacturingCost(ccost.getAuxiliaryManufacturingCost()); + cvo.setTotalAuxiliaryManufacturingCost(ccost.getAuxiliaryManufacturingCost().multiply(cvo.getTotalNum())); + } + pvo.getChildren().add(cvo); + EBomParentEntity cparent = ebomService.getParent(child.getMaterialNo()); + if (Objects.nonNull(cparent)) { + buildMultilayerChildren(cparent.getRowId(), cvo, materials, datas); + } + }); + } + private BomCostMultilayerVO buildEBomCostMultilayerVO() { BomCostMultilayerVO vo = new BomCostMultilayerVO(); if (RandomUtil.randomInt(0, 10) >= 7) { diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/SteelsCostConfigService.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/SteelsCostConfigService.java index da5fe2e9..4827b823 100644 --- a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/SteelsCostConfigService.java +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/SteelsCostConfigService.java @@ -54,4 +54,8 @@ public class SteelsCostConfigService extends ServiceImpl list) { if (CollectionUtil.isEmpty(list)) { diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/util/JsonUtil.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/util/JsonUtil.java new file mode 100644 index 00000000..5c50ad7c --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/util/JsonUtil.java @@ -0,0 +1,28 @@ +package com.nflg.product.technology.util; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nflg.product.base.core.exception.NflgBusinessException; +import com.nflg.product.technology.pojo.dto.EBomCostCacheDTO; +import nflg.product.common.constant.STATE; + +public class JsonUtil { + + private static final ObjectMapper objectmapper = new ObjectMapper(); + + public static T fromJson(String json, Class clazz) { + try { + return objectmapper.readValue(json, clazz); + } catch (JsonProcessingException e) { + throw new NflgBusinessException(STATE.BusinessError, "JSON反序列化失败"); + } + } + + public static String toJson(EBomCostCacheDTO cdto) { + try { + return objectmapper.writeValueAsString(cdto); + } catch (JsonProcessingException e) { + throw new NflgBusinessException(STATE.BusinessError, "JSON序列化失败"); + } + } +} diff --git a/nflg_project_dev/nflg-technology/src/main/resources/logback-sit.xml b/nflg_project_dev/nflg-technology/src/main/resources/logback-sit.xml index 67c26348..7313b4d5 100644 --- a/nflg_project_dev/nflg-technology/src/main/resources/logback-sit.xml +++ b/nflg_project_dev/nflg-technology/src/main/resources/logback-sit.xml @@ -62,12 +62,13 @@ + - + diff --git a/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/EBomChildMapper.xml b/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/EBomChildMapper.xml new file mode 100644 index 00000000..2491886f --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/EBomChildMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/EBomParentMapper.xml b/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/EBomParentMapper.xml new file mode 100644 index 00000000..142cf5ba --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/EBomParentMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/MaterialMainMapper.xml b/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/MaterialMainMapper.xml new file mode 100644 index 00000000..752a0b96 --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/MaterialMainMapper.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file