feat(产品成本分析): BOM组件成本分析

This commit is contained in:
曹鹏飞 2024-12-05 18:18:28 +08:00
parent d31e00cec2
commit 8665c1a793
29 changed files with 518 additions and 149 deletions

View File

@ -0,0 +1,12 @@
package com.nflg.product.technology.mapper.master;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.nflg.product.technology.pojo.entity.BomCostEntity;
import java.util.List;
import java.util.Set;
public interface BomCostMapper extends BaseMapper<BomCostEntity> {
List<BomCostEntity> getLatest(Set<String> materialNos);
}

View File

@ -3,6 +3,10 @@ package com.nflg.product.technology.mapper.master;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.nflg.product.technology.pojo.entity.ProcessRouteTaskProcessesEntity; import com.nflg.product.technology.pojo.entity.ProcessRouteTaskProcessesEntity;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Set;
/** /**
* <p> * <p>
* 工艺路线-工序 Mapper 接口 * 工艺路线-工序 Mapper 接口
@ -13,4 +17,5 @@ import com.nflg.product.technology.pojo.entity.ProcessRouteTaskProcessesEntity;
*/ */
public interface ProcessRouteTaskProcessesMapper extends BaseMapper<ProcessRouteTaskProcessesEntity> { public interface ProcessRouteTaskProcessesMapper extends BaseMapper<ProcessRouteTaskProcessesEntity> {
Map<String, BigDecimal> getWorkingHours(Set<String> materialNos);
} }

View File

@ -2,10 +2,14 @@ package com.nflg.product.technology.mapper.master;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.nflg.product.technology.pojo.entity.VirtualWorkingEntity; import com.nflg.product.technology.pojo.entity.VirtualWorkingEntity;
import com.nflg.product.technology.pojo.vo.VirtualWorkingItemVO;
import java.util.List;
/** /**
* @author 曹鹏飞 * @author 曹鹏飞
* @date 2024/11/23 10:26:09 * @date 2024/11/23 10:26:09
*/ */
public interface VirtualWorkingMapper extends BaseMapper<VirtualWorkingEntity> { public interface VirtualWorkingMapper extends BaseMapper<VirtualWorkingEntity> {
List<VirtualWorkingItemVO> listDTO();
} }

View File

@ -1,7 +1,7 @@
package com.nflg.product.technology.pojo; package com.nflg.product.technology.pojo;
import com.nflg.product.technology.pojo.entity.VirtualWorkingEntity;
import com.nflg.product.technology.pojo.query.VirtualWorkingManday; import com.nflg.product.technology.pojo.query.VirtualWorkingManday;
import com.nflg.product.technology.pojo.vo.VirtualWorkingItemVO;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
@ -9,7 +9,7 @@ import java.util.List;
@Data @Data
public class BomCostCalculateConfig { public class BomCostCalculateConfig {
private List<VirtualWorkingEntity> virtualWorkings; private List<VirtualWorkingItemVO> virtualWorkings;
private VirtualWorkingManday manday; private VirtualWorkingManday manday;
} }

View File

@ -66,4 +66,11 @@ public class EBomDTO {
* 父物料编码 * 父物料编码
*/ */
private String parentMaterialNo; private String parentMaterialNo;
/**
* 材料分组名称
*/
private String groupName;
private Long materialRowId;
} }

View File

@ -0,0 +1,22 @@
package com.nflg.product.technology.pojo.dto;
import lombok.Data;
@Data
public class MaterialRawMaterialGroupDTO {
/**
* 物料编码
*/
private String materialNo;
/**
* 编码
*/
private String groupCode;
/**
* 名称
*/
private String groupName;
}

View File

@ -0,0 +1,91 @@
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;
import java.time.LocalDateTime;
@Data
@Accessors(chain = true)
@ApiModel(value = "com-nflg-product-technology-pojo-entity-BomCostEntity")
@TableName(value = "t_technology_bom_cost")
public class BomCostEntity implements Serializable {
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value = "主键")
private Long id;
/**
* 物料编号
*/
@TableField(value = "material_no")
@ApiModelProperty(value = "物料编号")
private String materialNo;
/**
* 版本号
*/
@TableField(value = "version")
@ApiModelProperty(value = "版本号")
private String version;
/**
* 总成本
*/
@TableField(value = "total_price")
@ApiModelProperty(value = "总成本")
private BigDecimal totalPrice;
/**
* 材料成本
*/
@TableField(value = "material_price")
@ApiModelProperty(value = "材料成本")
private BigDecimal materialPrice;
/**
* 油漆成本
*/
@TableField(value = "paint_price")
@ApiModelProperty(value = "油漆成本")
private BigDecimal paintPrice;
/**
* 标准人工工资
*/
@TableField(value = "manday_price")
@ApiModelProperty(value = "标准人工工资")
private BigDecimal mandayPrice;
/**
* 辅助费用
*/
@TableField(value = "assistant_price")
@ApiModelProperty(value = "辅助费用")
private BigDecimal assistantPrice;
/**
* 创建人
*/
@TableField(value = "create_by")
@ApiModelProperty(value = "创建人")
private String createBy;
/**
* 创建时间
*/
@TableField(value = "create_time")
@ApiModelProperty(value = "创建时间")
private LocalDateTime createTime;
}

View File

@ -26,9 +26,9 @@ public class VirtualWorkingEntity extends EntityBase implements Serializable {
@ApiModelProperty(value = "主键行id") @ApiModelProperty(value = "主键行id")
private Integer id; private Integer id;
@TableField(value = "name") @TableField(value = "workingtype_id")
@ApiModelProperty(value = "工时类型") @ApiModelProperty("工时类型行id")
private String name; private Integer workingTypeId;
@TableField(value = "hourly_auxiliary_fee") @TableField(value = "hourly_auxiliary_fee")
@ApiModelProperty(value = "每小时辅助费用") @ApiModelProperty(value = "每小时辅助费用")

View File

@ -10,13 +10,12 @@ import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime;
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
@ApiModel(value = "com-nflg-product-technology-pojo-entity-WorkingTypeEntity") @ApiModel(value = "com-nflg-product-technology-pojo-entity-WorkingTypeEntity")
@TableName(value = "t_technology_working_type") @TableName(value = "t_technology_working_type")
public class WorkingTypeEntity implements Serializable { public class WorkingTypeEntity extends EntityBase implements Serializable {
@TableId(value = "id", type = IdType.AUTO) @TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value = "主键行id") @ApiModelProperty(value = "主键行id")
@ -26,11 +25,7 @@ public class WorkingTypeEntity implements Serializable {
@ApiModelProperty(value = "名称") @ApiModelProperty(value = "名称")
private String name; private String name;
@TableField(value = "create_by") @TableField(value = "code")
@ApiModelProperty(value = "创建人") @ApiModelProperty(value = "编号")
private String createBy; private String code;
@TableField(value = "create_time")
@ApiModelProperty(value = "创建时间")
private LocalDateTime createTime;
} }

View File

@ -6,8 +6,7 @@ import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import javax.validation.constraints.Min; import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -23,16 +22,23 @@ public class VirtualWorking implements Serializable {
@ApiModelProperty(value = "主键行id") @ApiModelProperty(value = "主键行id")
private Integer id; private Integer id;
@ApiModelProperty("工时类型") @ApiModelProperty("工时类型行id")
@NotBlank(message = "工时类型不能为空") @NotNull(message = "工时类型行id不能为空")
private String name; @Min(value = 1, message = "工时类型行id无效")
private Integer workingTypeId;
@ApiModelProperty("工时类型名称")
private String workingTypeName;
@ApiModelProperty("工时类型编号")
private String workingTypeCode;
@ApiModelProperty("每小时辅助费用") @ApiModelProperty("每小时辅助费用")
@Min(value = 0, message = "每小时辅助费用必须大于等于0") @Min(value = 0, message = "每小时辅助费用必须大于等于0")
private BigDecimal hourlyAuxiliaryFee; private BigDecimal hourlyAuxiliaryFee;
@ApiModelProperty("本车间一线人数") @ApiModelProperty("本车间一线人数")
@Positive(message = "本车间一线人数必须大于0") @Min(value = 0, message = "本车间一线人数必须大于等于0")
private Integer userNum; private Integer userNum;
@ApiModelProperty("年度总费用") @ApiModelProperty("年度总费用")

View File

@ -21,4 +21,9 @@ public class WorkingTypeQuery implements Serializable {
@NotBlank(message = "名称不能为空") @NotBlank(message = "名称不能为空")
@Length(max = 10, message = "名称不能超过10个字") @Length(max = 10, message = "名称不能超过10个字")
private String name; private String name;
@ApiModelProperty("编号")
@NotBlank(message = "编号不能为空")
@Length(max = 10, message = "编号不能超过10个字")
private String code;
} }

View File

@ -56,10 +56,10 @@ public class BomCostMultilayerVO implements Serializable {
private BigDecimal totalPaintCost; private BigDecimal totalPaintCost;
@ApiModelProperty("单件标准人工工资") @ApiModelProperty("单件标准人工工资")
private BigDecimal standardPieceRateSalary; private BigDecimal directManualProductionCost;
@ApiModelProperty("标准人工工资") @ApiModelProperty("标准人工工资")
private BigDecimal totalStandardPieceRateSalary; private BigDecimal totalDirectManualProductionCost;
@ApiModelProperty("单件辅助费用") @ApiModelProperty("单件辅助费用")
private BigDecimal auxiliaryManufacturingCost; private BigDecimal auxiliaryManufacturingCost;
@ -69,4 +69,9 @@ public class BomCostMultilayerVO implements Serializable {
@ApiModelProperty("子物料列表") @ApiModelProperty("子物料列表")
private List<BomCostMultilayerVO> children = new ArrayList<>(); private List<BomCostMultilayerVO> children = new ArrayList<>();
@ApiModelProperty("物料行id")
private Long materialRowId;
private String relCategoryCode;
} }

View File

@ -49,4 +49,9 @@ public class BomCostSingleLayerVO implements Serializable {
@ApiModelProperty("辅助制造成本") @ApiModelProperty("辅助制造成本")
private BigDecimal auxiliaryManufacturingCost; private BigDecimal auxiliaryManufacturingCost;
@ApiModelProperty("物料行id")
private Long materialRowId;
private String relCategoryCode;
} }

View File

@ -80,4 +80,17 @@ public class MaterialCostVO implements Serializable {
public Integer getLeadTime() { public Integer getLeadTime() {
return RandomUtil.randomInt(1000); return RandomUtil.randomInt(1000);
} }
@ApiModelProperty("物料行id")
private Long materialRowId;
public Long getMaterialRowId() {
return 1730039758209073154L;
}
private String relCategoryCode;
public String getRelCategoryCode() {
return "21";
}
} }

View File

@ -1,12 +1,13 @@
package com.nflg.product.technology.pojo.vo; package com.nflg.product.technology.pojo.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.nflg.product.technology.pojo.entity.EntityBase;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime;
/** /**
* @author 曹鹏飞 * @author 曹鹏飞
@ -15,17 +16,16 @@ import java.time.LocalDateTime;
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
@ApiModel(value = "com-nflg-product-technology-pojo-vo-WorkingTypeVO") @ApiModel(value = "com-nflg-product-technology-pojo-vo-WorkingTypeVO")
public class WorkingTypeVO implements Serializable { public class WorkingTypeVO extends EntityBase implements Serializable {
@ApiModelProperty(value = "主键行id") @ApiModelProperty(value = "主键行id")
private Integer id; private Integer id;
@ApiModelProperty("工时类型") @ApiModelProperty("工时类型名称")
@JsonProperty("workingTypeName")
private String name; private String name;
@ApiModelProperty(value = "创建人") @ApiModelProperty("工时类型编号")
private String createBy; @JsonProperty("workingTypeCode")
private String code;
@ApiModelProperty(value = "创建时间")
private LocalDateTime createTime;
} }

View File

@ -8,8 +8,12 @@ import com.nflg.product.technology.pojo.BomCostCalculateConfig;
import com.nflg.product.technology.pojo.dto.EBomCostCacheDTO; import com.nflg.product.technology.pojo.dto.EBomCostCacheDTO;
import com.nflg.product.technology.pojo.dto.EBomDTO; import com.nflg.product.technology.pojo.dto.EBomDTO;
import com.nflg.product.technology.pojo.dto.ProductionCostDTO; import com.nflg.product.technology.pojo.dto.ProductionCostDTO;
import com.nflg.product.technology.pojo.entity.*; import com.nflg.product.technology.pojo.entity.EBomChildEntity;
import com.nflg.product.technology.pojo.entity.EBomParentEntity;
import com.nflg.product.technology.pojo.entity.PaintCostConfigEntity;
import com.nflg.product.technology.pojo.entity.SteelsCostConfigEntity;
import com.nflg.product.technology.pojo.query.VirtualWorkingManday; import com.nflg.product.technology.pojo.query.VirtualWorkingManday;
import com.nflg.product.technology.pojo.vo.VirtualWorkingItemVO;
import com.nflg.product.technology.util.JsonUtil; import com.nflg.product.technology.util.JsonUtil;
import com.nflg.product.technology.util.VUtils; import com.nflg.product.technology.util.VUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -41,6 +45,15 @@ public class BomCostCalculateService {
@Resource @Resource
private RedisTemplate<String, String> redisTemplate; private RedisTemplate<String, String> redisTemplate;
@Resource
private TechnologyConfigService technologyConfigService;
@Resource
private VirtualWorkingService virtualWorkingService;
@Resource
private ProcessRouteTaskProcessesService processRouteTaskProcessesService;
/** /**
* 缓存时长 * 缓存时长
*/ */
@ -51,7 +64,7 @@ public class BomCostCalculateService {
*/ */
private static final List<String> STEELS_CATEGORY_CODE = Arrays.asList("10010101", "10010102", "10010103", "10010104", "10010105", "10010110"); private static final List<String> STEELS_CATEGORY_CODE = Arrays.asList("10010101", "10010102", "10010103", "10010104", "10010105", "10010110");
public List<EBomCostCacheDTO> calculate(String materialNo, BomCostCalculateConfig config) { public List<EBomCostCacheDTO> calculate(String materialNo) {
VUtils.isTure(StrUtil.isBlank(materialNo)).throwMessage("物料编号不能为空"); VUtils.isTure(StrUtil.isBlank(materialNo)).throwMessage("物料编号不能为空");
List<EBomDTO> datas = new ArrayList<>(); List<EBomDTO> datas = new ArrayList<>();
EBomParentEntity parent = ebomService.getParent(materialNo); EBomParentEntity parent = ebomService.getParent(materialNo);
@ -60,12 +73,18 @@ public class BomCostCalculateService {
EBomDTO pDto = convert(parent); EBomDTO pDto = convert(parent);
datas.add(pDto); datas.add(pDto);
getChildren(materialNo, datas); getChildren(materialNo, datas);
BomCostCalculateConfig config = new BomCostCalculateConfig();
VirtualWorkingManday manday = new VirtualWorkingManday();
manday.setHourlyWages(technologyConfigService.getHourlyWages());
manday.setBenefit(technologyConfigService.getBenefit());
config.setManday(manday);
config.setVirtualWorkings(virtualWorkingService.listDTO());
List<EBomCostCacheDTO> result = new ArrayList<>(50); List<EBomCostCacheDTO> result = new ArrayList<>(50);
calculateBom(pDto, datas, config, result); calculateBom(pDto, datas, config, processRouteTaskProcessesService.getWorkingHours(Collections.singleton(materialNo)), result);
return result; return result;
} }
private EBomCostCacheDTO calculateBom(EBomDTO dto, List<EBomDTO> datas, BomCostCalculateConfig config, List<EBomCostCacheDTO> result) { private EBomCostCacheDTO calculateBom(EBomDTO dto, List<EBomDTO> datas, BomCostCalculateConfig config, Map<String, BigDecimal> workingHours, List<EBomCostCacheDTO> result) {
String cdata = redisTemplate.opsForValue().get(buildKey(dto)); String cdata = redisTemplate.opsForValue().get(buildKey(dto));
List<EBomDTO> children = datas.stream() List<EBomDTO> children = datas.stream()
.filter(d -> StrUtil.equals(d.getParentMaterialNo(), dto.getMaterialNo())) .filter(d -> StrUtil.equals(d.getParentMaterialNo(), dto.getMaterialNo()))
@ -73,29 +92,32 @@ public class BomCostCalculateService {
if (StrUtil.isBlank(cdata)) { if (StrUtil.isBlank(cdata)) {
EBomCostCacheDTO cdto = new EBomCostCacheDTO(); EBomCostCacheDTO cdto = new EBomCostCacheDTO();
cdto.setMaterialNo(dto.getMaterialNo()); cdto.setMaterialNo(dto.getMaterialNo());
cdto.setPurchasedParts(!STEELS_CATEGORY_CODE.contains(dto.getMaterialCategoryCode())); cdto.setPieceRateSalary(calculatePieceRateSalary(dto, config, workingHours));
cdto.setWelfareExpenses(calculateWelfareExpenses(dto, config, workingHours));
cdto.setHydropowerCost(calculateHydropowerCost(dto, config, workingHours));
cdto.setDepreciationCost(calculateDepreciationCost(dto, config, workingHours));
cdto.setWorkshopManagementLaborCost(calculateWorkshopManagementLaborCost(dto, config, workingHours));
cdto.setWorkshopOfficeExpenses(calculateWorkshopOfficeExpenses(dto, config, workingHours));
cdto.setAuxiliaryDepartmentLaborCost(calculateAuxiliaryDepartmentLaborCost(dto, config, workingHours));
cdto.setAuxiliaryDepartmentExpenses(calculateAuxiliaryDepartmentExpenses(dto, config, workingHours));
cdto.setPaintCost(calculatePaintCost(dto));
cdto.setProductionCosts(calculateProductionCosts(dto, config, workingHours));
if (CollectionUtil.isEmpty(children)) { if (CollectionUtil.isEmpty(children)) {
//没有子级直接计算成本 // 计算自身
log.debug(StrUtil.format("BOM成本计算 {} 直接计算", dto.getMaterialNo())); cdto.setPurchasedParts(!STEELS_CATEGORY_CODE.contains(dto.getMaterialCategoryCode()));
if (cdto.isPurchasedParts()) { if (cdto.isPurchasedParts()) {
// 外购件只计算采购成本
cdto.setPurchasedPartsCost(calculatePurchasedPartsCost(dto)); cdto.setPurchasedPartsCost(calculatePurchasedPartsCost(dto));
} else { } else {
// 非外购件计算材料成本和制作成本
// 计算制作成本
cdto.setSteelsCost(calculateSteelsCost(dto)); 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 { } else {
//有子级先计算子级成本 cdto.setPurchasedParts(false);
//计算子级成本
List<EBomCostCacheDTO> childrenCost = children.stream() List<EBomCostCacheDTO> childrenCost = children.stream()
.map(c -> calculateBom(c, datas, config, result)) .map(c -> calculateBom(c, datas, config, processRouteTaskProcessesService.getWorkingHours(children.stream().map(EBomDTO::getMaterialNo).collect(Collectors.toSet())), result))
.collect(Collectors.toList()); .collect(Collectors.toList());
List<ProductionCostDTO> productionCosts = new ArrayList<>(); List<ProductionCostDTO> productionCosts = new ArrayList<>();
for (EBomCostCacheDTO c : childrenCost) { for (EBomCostCacheDTO c : childrenCost) {
@ -127,8 +149,8 @@ public class BomCostCalculateService {
cdto.setProductionCosts(productionCosts); cdto.setProductionCosts(productionCosts);
} }
} }
log.debug(StrUtil.format("BOM成本计算 {} 根据子级计算", dto.getMaterialNo()));
} }
log.debug(StrUtil.format("BOM成本计算 {} 实时计算", dto.getMaterialNo()));
result.add(cdto); result.add(cdto);
cdata = JsonUtil.toJson(cdto); cdata = JsonUtil.toJson(cdto);
log.debug(cdata); log.debug(cdata);
@ -139,12 +161,12 @@ public class BomCostCalculateService {
log.debug(cdata); log.debug(cdata);
EBomCostCacheDTO cdto = JsonUtil.fromJson(cdata, EBomCostCacheDTO.class); EBomCostCacheDTO cdto = JsonUtil.fromJson(cdata, EBomCostCacheDTO.class);
result.add(cdto); result.add(cdto);
children.forEach(c -> calculateBom(c, datas, config, result)); children.forEach(c -> calculateBom(c, datas, config, processRouteTaskProcessesService.getWorkingHours(children.stream().map(EBomDTO::getMaterialNo).collect(Collectors.toSet())), result));
return cdto; return cdto;
} }
} }
private List<ProductionCostDTO> calculateProductionCosts(BomCostCalculateConfig config) { private List<ProductionCostDTO> calculateProductionCosts(EBomDTO d, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
List<ProductionCostDTO> productionCosts = new ArrayList<>(); List<ProductionCostDTO> productionCosts = new ArrayList<>();
BigDecimal hourlyWages; BigDecimal hourlyWages;
BigDecimal benefit; BigDecimal benefit;
@ -154,9 +176,9 @@ public class BomCostCalculateService {
BigDecimal feeWorkshopOffice; BigDecimal feeWorkshopOffice;
BigDecimal auxiliaryDepartmentLaborCosts; BigDecimal auxiliaryDepartmentLaborCosts;
BigDecimal assistantFee; BigDecimal assistantFee;
for (VirtualWorkingEntity vw : config.getVirtualWorkings()) { for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
ProductionCostDTO dto = new ProductionCostDTO(); ProductionCostDTO dto = new ProductionCostDTO();
dto.setName(vw.getName()); dto.setName(vw.getWorkingTypeName());
hourlyWages = Optional.ofNullable(config.getManday().getHourlyWages()).orElse(BigDecimal.ZERO); hourlyWages = Optional.ofNullable(config.getManday().getHourlyWages()).orElse(BigDecimal.ZERO);
benefit = Optional.ofNullable(config.getManday().getBenefit()).orElse(BigDecimal.ZERO); benefit = Optional.ofNullable(config.getManday().getBenefit()).orElse(BigDecimal.ZERO);
auxiliaryMaterialsAndConsumables = Optional.ofNullable(vw.getConsumablesFee()).orElse(BigDecimal.ZERO); auxiliaryMaterialsAndConsumables = Optional.ofNullable(vw.getConsumablesFee()).orElse(BigDecimal.ZERO);
@ -168,14 +190,13 @@ public class BomCostCalculateService {
dto.setCost(hourlyWages.add(benefit).add(auxiliaryMaterialsAndConsumables).add(feeEquipmentDepreciation) dto.setCost(hourlyWages.add(benefit).add(auxiliaryMaterialsAndConsumables).add(feeEquipmentDepreciation)
.add(feeEquipmentDepreciation).add(feeWorkshopLaborCost).add(feeWorkshopOffice) .add(feeEquipmentDepreciation).add(feeWorkshopLaborCost).add(feeWorkshopOffice)
.add(auxiliaryDepartmentLaborCosts).add(assistantFee) .add(auxiliaryDepartmentLaborCosts).add(assistantFee)
.multiply(getGsForWorkingType(vw.getName()))); .multiply(getGsForWorkingType(d, workHours, vw)));
} }
return productionCosts; return productionCosts;
} }
private BigDecimal calculatePaintCost(EBomDTO dto) { private BigDecimal calculatePaintCost(EBomDTO dto) {
String lable = "";// TODO 物料标签对应的油漆标签 PaintCostConfigEntity entity = paintCostConfigService.getCost(dto.getGroupName());
PaintCostConfigEntity entity = paintCostConfigService.getCost(lable);
if (Objects.nonNull(entity)) { if (Objects.nonNull(entity)) {
return NumberUtil.mul(dto.getUnitWeight(), entity.getCost()); return NumberUtil.mul(dto.getUnitWeight(), entity.getCost());
} else { } else {
@ -183,70 +204,72 @@ public class BomCostCalculateService {
} }
} }
private BigDecimal calculateWorkshopOfficeExpenses(List<VirtualWorkingEntity> virtualWorkings) { private BigDecimal calculateWorkshopOfficeExpenses(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
BigDecimal cost = BigDecimal.ZERO; BigDecimal cost = BigDecimal.ZERO;
for (VirtualWorkingEntity vw : virtualWorkings) { for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
cost = cost.add(vw.getWorkshopOfficeFee().multiply(getGsForWorkingType(vw.getName()))); cost = cost.add(vw.getWorkshopOfficeFee().multiply(getGsForWorkingType(dto, workHours, vw)));
} }
return cost; return cost;
} }
private BigDecimal calculateAuxiliaryDepartmentExpenses(List<VirtualWorkingEntity> virtualWorkings) { private BigDecimal calculateAuxiliaryDepartmentExpenses(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
BigDecimal cost = BigDecimal.ZERO; BigDecimal cost = BigDecimal.ZERO;
for (VirtualWorkingEntity vw : virtualWorkings) { for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
cost = cost.add(vw.getAssistantFee().multiply(getGsForWorkingType(vw.getName()))); cost = cost.add(vw.getAssistantFee().multiply(getGsForWorkingType(dto, workHours, vw)));
} }
return cost; return cost;
} }
private BigDecimal calculateAuxiliaryDepartmentLaborCost(List<VirtualWorkingEntity> virtualWorkings) { private BigDecimal calculateAuxiliaryDepartmentLaborCost(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
BigDecimal cost = BigDecimal.ZERO; BigDecimal cost = BigDecimal.ZERO;
for (VirtualWorkingEntity vw : virtualWorkings) { for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
cost = cost.add(vw.getAssistantLaborFee().multiply(getGsForWorkingType(vw.getName()))); cost = cost.add(vw.getAssistantLaborFee().multiply(getGsForWorkingType(dto, workHours, vw)));
} }
return cost; return cost;
} }
private BigDecimal calculateWorkshopManagementLaborCost(List<VirtualWorkingEntity> virtualWorkings) { private BigDecimal calculateWorkshopManagementLaborCost(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
BigDecimal cost = BigDecimal.ZERO; BigDecimal cost = BigDecimal.ZERO;
for (VirtualWorkingEntity vw : virtualWorkings) { for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
cost = cost.add(vw.getWorkshopLaborFee().multiply(getGsForWorkingType(vw.getName()))); cost = cost.add(vw.getWorkshopLaborFee().multiply(getGsForWorkingType(dto, workHours, vw)));
} }
return cost; return cost;
} }
private BigDecimal calculateDepreciationCost(List<VirtualWorkingEntity> virtualWorkings) { private BigDecimal calculateDepreciationCost(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
BigDecimal cost = BigDecimal.ZERO; BigDecimal cost = BigDecimal.ZERO;
for (VirtualWorkingEntity vw : virtualWorkings) { for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
cost = cost.add(vw.getEquipmentDepreciationFee().multiply(getGsForWorkingType(vw.getName()))); cost = cost.add(vw.getEquipmentDepreciationFee().multiply(getGsForWorkingType(dto, workHours, vw)));
} }
return cost; return cost;
} }
private BigDecimal calculateHydropowerCost(List<VirtualWorkingEntity> virtualWorkings) { private BigDecimal calculateHydropowerCost(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
BigDecimal cost = BigDecimal.ZERO; BigDecimal cost = BigDecimal.ZERO;
for (VirtualWorkingEntity vw : virtualWorkings) { for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
cost = cost.add(vw.getConsumablesFee().multiply(getGsForWorkingType(vw.getName()))); cost = cost.add(vw.getConsumablesFee().multiply(getGsForWorkingType(dto, workHours, vw)));
} }
return cost; return cost;
} }
private BigDecimal getGsForWorkingType(String type) { private BigDecimal getGsForWorkingType(EBomDTO dto, Map<String, BigDecimal> workHours, VirtualWorkingItemVO vw) {
//TODO 获取工时类型对应的工时 return workHours.getOrDefault(dto.getMaterialNo() + '-' + vw.getWorkingTypeName(), BigDecimal.ZERO);
return BigDecimal.ZERO;
} }
private BigDecimal calculateWelfareExpenses(EBomDTO dto, VirtualWorkingManday manday) { private BigDecimal calculateWelfareExpenses(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
return getTGS().multiply(Optional.ofNullable(manday.getBenefit()).orElse(BigDecimal.ZERO)); return getTGS(dto, config, workHours).multiply(Optional.ofNullable(config.getManday().getBenefit()).orElse(BigDecimal.ZERO));
} }
private BigDecimal calculatePieceRateSalary(EBomDTO dto, VirtualWorkingManday manday) { private BigDecimal calculatePieceRateSalary(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
return getTGS().multiply(Optional.ofNullable(manday.getHourlyWages()).orElse(BigDecimal.ZERO)); return getTGS(dto, config, workHours).multiply(Optional.ofNullable(config.getManday().getHourlyWages()).orElse(BigDecimal.ZERO));
} }
private BigDecimal getTGS() { private BigDecimal getTGS(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
// TODO 获取总工时 BigDecimal gs = BigDecimal.ZERO;
return BigDecimal.ZERO; for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
gs = gs.add(getGsForWorkingType(dto, workHours, vw));
}
return gs;
} }
private BigDecimal calculatePurchasedPartsCost(EBomDTO dto) { private BigDecimal calculatePurchasedPartsCost(EBomDTO dto) {
@ -255,13 +278,11 @@ public class BomCostCalculateService {
private BigDecimal calculateSteelsCost(EBomDTO dto) { private BigDecimal calculateSteelsCost(EBomDTO dto) {
//是钢材 //是钢材
// TODO 物料标签是哪个字段单价是哪个字段
BigDecimal price = Optional.ofNullable(dto.getLastPurchasePrice()).orElse(BigDecimal.ZERO); BigDecimal price = Optional.ofNullable(dto.getLastPurchasePrice()).orElse(BigDecimal.ZERO);
BigDecimal unitWeight = Optional.ofNullable(dto.getUnitWeight()).orElse(BigDecimal.ZERO); BigDecimal unitWeight = Optional.ofNullable(dto.getUnitWeight()).orElse(BigDecimal.ZERO);
BigDecimal wastage = BigDecimal.ZERO; BigDecimal wastage = BigDecimal.ZERO;
String lable = "物料标签"; if (StrUtil.isNotBlank(dto.getGroupName())) {
if (StrUtil.isNotBlank(lable)) { SteelsCostConfigEntity steelsCostConfigEntity = steelsCostConfigService.getCost(dto.getGroupName());
SteelsCostConfigEntity steelsCostConfigEntity = steelsCostConfigService.getCost(lable);
if (Objects.nonNull(steelsCostConfigEntity)) { if (Objects.nonNull(steelsCostConfigEntity)) {
price = Optional.ofNullable(steelsCostConfigEntity.getCost()).orElse(BigDecimal.ZERO); price = Optional.ofNullable(steelsCostConfigEntity.getCost()).orElse(BigDecimal.ZERO);
wastage = Optional.ofNullable(steelsCostConfigEntity.getWastage()).orElse(BigDecimal.ZERO); wastage = Optional.ofNullable(steelsCostConfigEntity.getWastage()).orElse(BigDecimal.ZERO);

View File

@ -0,0 +1,72 @@
package com.nflg.product.technology.service;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nflg.product.base.core.conmon.util.SessionUtil;
import com.nflg.product.technology.mapper.master.BomCostMapper;
import com.nflg.product.technology.pojo.dto.EBomCostCacheDTO;
import com.nflg.product.technology.pojo.entity.BomCostEntity;
import com.nflg.product.technology.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@Service
@Slf4j
public class BomCostService extends ServiceImpl<BomCostMapper, BomCostEntity> {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
@Transactional
public void save(List<EBomCostCacheDTO> datas) {
if (CollectionUtil.isNotEmpty(datas)) {
Set<String> materialNos = datas.stream().map(EBomCostCacheDTO::getMaterialNo).collect(Collectors.toSet());
List<BomCostEntity> latest = baseMapper.getLatest(materialNos);
if (CollectionUtil.isEmpty(latest)) {
List<BomCostEntity> entities = datas.stream().map(this::convert).collect(Collectors.toList());
saveBatch(entities);
} else {
List<BomCostEntity> forAdd = new ArrayList<>();
List<Long> forDelete = new ArrayList<>();
datas.forEach(d -> {
BomCostEntity entity = latest.stream().filter(l -> StrUtil.equals(l.getMaterialNo(), d.getMaterialNo())).findFirst().orElse(null);
if (Objects.isNull(entity)) {
forAdd.add(convert(d));
} else if (!StringUtil.inSameInterval(entity.getVersion(), LocalDateTime.now().format(FORMATTER))) {
forDelete.add(entity.getId());
forAdd.add(convert(d));
}
});
if (CollectionUtil.isNotEmpty(forAdd)) {
saveBatch(forAdd);
}
if (CollectionUtil.isNotEmpty(forDelete)) {
removeByIds(forDelete);
}
}
}
}
private BomCostEntity convert(EBomCostCacheDTO dto) {
BomCostEntity entity = new BomCostEntity();
entity.setMaterialNo(dto.getMaterialNo());
entity.setVersion(LocalDateTime.now().format(FORMATTER));
entity.setTotalPrice(dto.getTotalCost());
entity.setMaterialPrice(dto.getMaterialCost());
entity.setPaintPrice(dto.getPaintCost());
entity.setMandayPrice(dto.getDirectManualProductionCost());
entity.setAssistantPrice(dto.getAuxiliaryManufacturingCost());
entity.setCreateBy(SessionUtil.getRealName());
entity.setCreateTime(LocalDateTime.now());
return entity;
}
}

View File

@ -2,7 +2,6 @@ package com.nflg.product.technology.service;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.nflg.product.technology.constant.TechnologyConfigEnum; import com.nflg.product.technology.constant.TechnologyConfigEnum;
import com.nflg.product.technology.pojo.entity.VirtualWorkingEntity; import com.nflg.product.technology.pojo.entity.VirtualWorkingEntity;
import com.nflg.product.technology.pojo.entity.WorkingTypeEntity; import com.nflg.product.technology.pojo.entity.WorkingTypeEntity;
@ -63,15 +62,16 @@ public class CostConfigService {
manday.setBenefit(technologyConfigService.getBenefit()); manday.setBenefit(technologyConfigService.getBenefit());
vo.setManday(manday); vo.setManday(manday);
List<VirtualWorkingEntity> virtualWorkingEntities = virtualWorkingService.list(); List<VirtualWorkingEntity> virtualWorkingEntities = virtualWorkingService.list();
List<WorkingTypeEntity> list = workingTypeService.list();
list.forEach(l -> {
if (virtualWorkingEntities.stream().noneMatch(v -> StrUtil.equals(l.getName(), v.getName()))) {
VirtualWorkingEntity entity = new VirtualWorkingEntity();
entity.setName(l.getName());
virtualWorkingEntities.add(entity);
}
});
if (CollectionUtil.isNotEmpty(virtualWorkingEntities)) { if (CollectionUtil.isNotEmpty(virtualWorkingEntities)) {
List<VirtualWorkingItemVO> vos = Convert.toList(VirtualWorkingItemVO.class, virtualWorkingEntities);
List<WorkingTypeEntity> workingTypeEntities = workingTypeService.list();
vos.forEach(cvo -> {
WorkingTypeEntity wt = workingTypeEntities.stream().filter(w -> Objects.equals(w.getId(), cvo.getWorkingTypeId())).findFirst().orElse(null);
if (Objects.nonNull(wt)) {
cvo.setWorkingTypeName(wt.getName());
cvo.setWorkingTypeCode(wt.getCode());
}
});
vo.setVirtualWorking(Convert.toList(VirtualWorkingItemVO.class, virtualWorkingEntities)); vo.setVirtualWorking(Convert.toList(VirtualWorkingItemVO.class, virtualWorkingEntities));
} }
return vo; return vo;
@ -88,7 +88,7 @@ public class CostConfigService {
@Transactional @Transactional
public void saveWorkingTypes(List<WorkingTypeQuery> types) { public void saveWorkingTypes(List<WorkingTypeQuery> types) {
workingTypeService.save(types); workingTypeService.save(types);
virtualWorkingService.deleteNotInNames(types.stream().map(WorkingTypeQuery::getName).collect(Collectors.toList())); virtualWorkingService.deleteNotInIds(types.stream().map(WorkingTypeQuery::getId).collect(Collectors.toList()));
} }
public void saveMonthlyWorkingHoursConfig(MonthlyWorkingHoursConfigQuery query) { public void saveMonthlyWorkingHoursConfig(MonthlyWorkingHoursConfigQuery query) {

View File

@ -1,6 +1,7 @@
package com.nflg.product.technology.service; package com.nflg.product.technology.service;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -59,6 +60,9 @@ public class PaintCostConfigService extends ServiceImpl<PaintCostConfigMapper, P
} }
public PaintCostConfigEntity getCost(String name) { public PaintCostConfigEntity getCost(String name) {
if (StrUtil.isBlank(name)) {
return null;
}
return lambdaQuery().eq(PaintCostConfigEntity::getName, name).one(); return lambdaQuery().eq(PaintCostConfigEntity::getName, name).one();
} }
} }

View File

@ -5,6 +5,12 @@ import com.nflg.product.technology.mapper.master.ProcessRouteTaskProcessesMapper
import com.nflg.product.technology.pojo.entity.ProcessRouteTaskProcessesEntity; import com.nflg.product.technology.pojo.entity.ProcessRouteTaskProcessesEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
/** /**
* <p> * <p>
* 工艺路线-工序 服务类 * 工艺路线-工序 服务类
@ -16,4 +22,7 @@ import org.springframework.stereotype.Service;
@Service @Service
public class ProcessRouteTaskProcessesService extends ServiceImpl<ProcessRouteTaskProcessesMapper, ProcessRouteTaskProcessesEntity> { public class ProcessRouteTaskProcessesService extends ServiceImpl<ProcessRouteTaskProcessesMapper, ProcessRouteTaskProcessesEntity> {
public Map<String, BigDecimal> getWorkingHours(Set<String> materialNos) {
return Optional.ofNullable(this.baseMapper.getWorkingHours(materialNos)).orElse(new HashMap<>());
}
} }

View File

@ -2,13 +2,11 @@ package com.nflg.product.technology.service;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.nflg.product.technology.constant.BomConstant; 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.EBomCostCacheDTO;
import com.nflg.product.technology.pojo.dto.EBomDTO; import com.nflg.product.technology.pojo.dto.EBomDTO;
import com.nflg.product.technology.pojo.entity.EBomChildEntity; import com.nflg.product.technology.pojo.entity.EBomChildEntity;
import com.nflg.product.technology.pojo.entity.EBomParentEntity; import com.nflg.product.technology.pojo.entity.EBomParentEntity;
import com.nflg.product.technology.pojo.query.MaterialVersionCostQuery; import com.nflg.product.technology.pojo.query.MaterialVersionCostQuery;
import com.nflg.product.technology.pojo.query.VirtualWorkingManday;
import com.nflg.product.technology.pojo.vo.*; import com.nflg.product.technology.pojo.vo.*;
import com.nflg.product.technology.util.MapUtil; import com.nflg.product.technology.util.MapUtil;
import com.nflg.product.technology.util.RandomUtil; import com.nflg.product.technology.util.RandomUtil;
@ -50,14 +48,11 @@ public class ProductCostAnalysisService {
@Resource @Resource
private TechnologyConfigService technologyConfigService; private TechnologyConfigService technologyConfigService;
@Resource
private BomCostService bomCostService;
public List<BomCostSingleLayerVO> getBomCostSingleLayer(String materialNo) { public List<BomCostSingleLayerVO> getBomCostSingleLayer(String materialNo) {
BomCostCalculateConfig cnfig = new BomCostCalculateConfig(); List<EBomCostCacheDTO> datas = bomCostCalculateService.calculate(materialNo);
VirtualWorkingManday manday = new VirtualWorkingManday();
manday.setHourlyWages(technologyConfigService.getHourlyWages());
manday.setBenefit(technologyConfigService.getBenefit());
cnfig.setManday(manday);
cnfig.setVirtualWorkings(virtualWorkingService.list());
List<EBomCostCacheDTO> datas = bomCostCalculateService.calculate(materialNo, cnfig);
EBomParentEntity parent = ebomService.getParent(materialNo); EBomParentEntity parent = ebomService.getParent(materialNo);
return buildSingleLayerChildren(parent.getRowId(), datas); return buildSingleLayerChildren(parent.getRowId(), datas);
} }
@ -79,6 +74,8 @@ public class ProductCostAnalysisService {
cvo.setMaterialDesc(cpm.getMaterialDesc()); cvo.setMaterialDesc(cpm.getMaterialDesc());
cvo.setMaterialCategoryName(cpm.getCategoryName()); cvo.setMaterialCategoryName(cpm.getCategoryName());
cvo.setMaterialUnit(cpm.getMaterialUnit()); cvo.setMaterialUnit(cpm.getMaterialUnit());
cvo.setMaterialRowId(cpm.getMaterialRowId());
cvo.setRelCategoryCode(cpm.getRelCategoryCode());
} }
EBomParentEntity parent = parents.stream().filter(p -> StrUtil.equals(p.getMaterialNo(), child.getMaterialNo())).findFirst().orElse(null); EBomParentEntity parent = parents.stream().filter(p -> StrUtil.equals(p.getMaterialNo(), child.getMaterialNo())).findFirst().orElse(null);
cvo.setVersion(Objects.isNull(parent) ? "A00" : parent.getCurrentVersion()); cvo.setVersion(Objects.isNull(parent) ? "A00" : parent.getCurrentVersion());
@ -97,13 +94,7 @@ public class ProductCostAnalysisService {
} }
public BomCostMultilayerVO getBomCostMultilayer(String materialNo) { public BomCostMultilayerVO getBomCostMultilayer(String materialNo) {
BomCostCalculateConfig cnfig = new BomCostCalculateConfig(); List<EBomCostCacheDTO> datas = bomCostCalculateService.calculate(materialNo);
VirtualWorkingManday manday = new VirtualWorkingManday();
manday.setHourlyWages(technologyConfigService.getHourlyWages());
manday.setBenefit(technologyConfigService.getBenefit());
cnfig.setManday(manday);
cnfig.setVirtualWorkings(virtualWorkingService.list());
List<EBomCostCacheDTO> datas = bomCostCalculateService.calculate(materialNo, cnfig);
List<EBomDTO> materials = materialMainService.getInfos(datas.stream().map(EBomCostCacheDTO::getMaterialNo).collect(Collectors.toSet())); List<EBomDTO> materials = materialMainService.getInfos(datas.stream().map(EBomCostCacheDTO::getMaterialNo).collect(Collectors.toSet()));
EBomParentEntity parent = ebomService.getParent(materialNo); EBomParentEntity parent = ebomService.getParent(materialNo);
BomCostMultilayerVO vo = new BomCostMultilayerVO(); BomCostMultilayerVO vo = new BomCostMultilayerVO();
@ -113,6 +104,8 @@ public class ProductCostAnalysisService {
vo.setMaterialDesc(pm.getMaterialDesc()); vo.setMaterialDesc(pm.getMaterialDesc());
vo.setMaterialCategoryName(pm.getCategoryName()); vo.setMaterialCategoryName(pm.getCategoryName());
vo.setMaterialUnit(pm.getMaterialUnit()); vo.setMaterialUnit(pm.getMaterialUnit());
vo.setMaterialRowId(pm.getMaterialRowId());
vo.setRelCategoryCode(pm.getRelCategoryCode());
} }
EBomCostCacheDTO cost = datas.stream().filter(d -> StrUtil.equals(d.getMaterialNo(), parent.getMaterialNo())).findFirst().orElse(null); EBomCostCacheDTO cost = datas.stream().filter(d -> StrUtil.equals(d.getMaterialNo(), parent.getMaterialNo())).findFirst().orElse(null);
if (Objects.nonNull(cost)) { if (Objects.nonNull(cost)) {
@ -124,8 +117,8 @@ public class ProductCostAnalysisService {
vo.setTotalMaterialCost(cost.getMaterialCost()); vo.setTotalMaterialCost(cost.getMaterialCost());
vo.setPaintCost(cost.getPaintCost()); vo.setPaintCost(cost.getPaintCost());
vo.setTotalPaintCost(cost.getPaintCost()); vo.setTotalPaintCost(cost.getPaintCost());
vo.setStandardPieceRateSalary(cost.getPieceRateSalary()); vo.setDirectManualProductionCost(cost.getDirectManualProductionCost());
vo.setTotalStandardPieceRateSalary(cost.getPieceRateSalary()); vo.setTotalDirectManualProductionCost(cost.getDirectManualProductionCost());
vo.setAuxiliaryManufacturingCost(cost.getAuxiliaryManufacturingCost()); vo.setAuxiliaryManufacturingCost(cost.getAuxiliaryManufacturingCost());
vo.setTotalAuxiliaryManufacturingCost(cost.getAuxiliaryManufacturingCost()); vo.setTotalAuxiliaryManufacturingCost(cost.getAuxiliaryManufacturingCost());
} }
@ -143,6 +136,8 @@ public class ProductCostAnalysisService {
cvo.setMaterialDesc(cpm.getMaterialDesc()); cvo.setMaterialDesc(cpm.getMaterialDesc());
cvo.setMaterialCategoryName(cpm.getCategoryName()); cvo.setMaterialCategoryName(cpm.getCategoryName());
cvo.setMaterialUnit(cpm.getMaterialUnit()); cvo.setMaterialUnit(cpm.getMaterialUnit());
cvo.setMaterialRowId(cpm.getMaterialRowId());
cvo.setRelCategoryCode(cpm.getRelCategoryCode());
} }
EBomCostCacheDTO ccost = datas.stream().filter(d -> StrUtil.equals(d.getMaterialNo(), child.getMaterialNo())).findFirst().orElse(null); EBomCostCacheDTO ccost = datas.stream().filter(d -> StrUtil.equals(d.getMaterialNo(), child.getMaterialNo())).findFirst().orElse(null);
if (Objects.nonNull(ccost)) { if (Objects.nonNull(ccost)) {
@ -154,8 +149,8 @@ public class ProductCostAnalysisService {
cvo.setTotalMaterialCost(ccost.getMaterialCost().multiply(cvo.getTotalNum())); cvo.setTotalMaterialCost(ccost.getMaterialCost().multiply(cvo.getTotalNum()));
cvo.setPaintCost(ccost.getPaintCost()); cvo.setPaintCost(ccost.getPaintCost());
cvo.setTotalPaintCost(ccost.getPaintCost().multiply(cvo.getTotalNum())); cvo.setTotalPaintCost(ccost.getPaintCost().multiply(cvo.getTotalNum()));
cvo.setStandardPieceRateSalary(ccost.getPieceRateSalary().multiply(cvo.getTotalNum())); cvo.setDirectManualProductionCost(ccost.getDirectManualProductionCost().multiply(cvo.getTotalNum()));
cvo.setTotalStandardPieceRateSalary(ccost.getPieceRateSalary()); cvo.setTotalDirectManualProductionCost(ccost.getDirectManualProductionCost());
cvo.setAuxiliaryManufacturingCost(ccost.getAuxiliaryManufacturingCost()); cvo.setAuxiliaryManufacturingCost(ccost.getAuxiliaryManufacturingCost());
cvo.setTotalAuxiliaryManufacturingCost(ccost.getAuxiliaryManufacturingCost().multiply(cvo.getTotalNum())); cvo.setTotalAuxiliaryManufacturingCost(ccost.getAuxiliaryManufacturingCost().multiply(cvo.getTotalNum()));
} }
@ -167,20 +162,6 @@ public class ProductCostAnalysisService {
}); });
} }
private BomCostMultilayerVO buildEBomCostMultilayerVO() {
BomCostMultilayerVO vo = new BomCostMultilayerVO();
if (RandomUtil.randomInt(0, 10) >= 7) {
List<BomCostMultilayerVO> list = new ArrayList<>();
int count = RandomUtil.randomInt(0, 8);
for (int i = 0; i < count; i++) {
BomCostMultilayerVO bomCostMultilayerVO = buildEBomCostMultilayerVO();
list.add(bomCostMultilayerVO);
}
vo.setChildren(list);
}
return vo;
}
public ProductCostVO getProductCostByMaterialNo(String materialNo) { public ProductCostVO getProductCostByMaterialNo(String materialNo) {
// TODO 待实现 // TODO 待实现
ProductCostVO vo = new ProductCostVO(); ProductCostVO vo = new ProductCostVO();
@ -309,7 +290,8 @@ public class ProductCostAnalysisService {
} }
public void saveCost(String materialNo) { public void saveCost(String materialNo) {
// TODO 待实现 List<EBomCostCacheDTO> datas = bomCostCalculateService.calculate(materialNo);
bomCostService.save(datas);
} }
public List<String> getCostVersion(@Valid @NotBlank String materialNo) { public List<String> getCostVersion(@Valid @NotBlank String materialNo) {

View File

@ -9,6 +9,7 @@ import com.nflg.product.technology.mapper.master.VirtualWorkingMapper;
import com.nflg.product.technology.pojo.entity.VirtualWorkingEntity; import com.nflg.product.technology.pojo.entity.VirtualWorkingEntity;
import com.nflg.product.technology.pojo.entity.WorkingTypeEntity; import com.nflg.product.technology.pojo.entity.WorkingTypeEntity;
import com.nflg.product.technology.pojo.query.VirtualWorking; import com.nflg.product.technology.pojo.query.VirtualWorking;
import com.nflg.product.technology.pojo.vo.VirtualWorkingItemVO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -33,9 +34,6 @@ public class VirtualWorkingService extends ServiceImpl<VirtualWorkingMapper, Vir
@Resource @Resource
private WorkingTypeService workingTypeService; private WorkingTypeService workingTypeService;
@Resource
private TechnologyConfigService technologyConfigService;
@Transactional() @Transactional()
public void save(List<VirtualWorking> list) { public void save(List<VirtualWorking> list) {
if (CollectionUtil.isEmpty(list)) { if (CollectionUtil.isEmpty(list)) {
@ -50,11 +48,11 @@ public class VirtualWorkingService extends ServiceImpl<VirtualWorkingMapper, Vir
List<VirtualWorkingEntity> forAdd = new ArrayList<>(); List<VirtualWorkingEntity> forAdd = new ArrayList<>();
List<VirtualWorkingEntity> forUpdate = new ArrayList<>(); List<VirtualWorkingEntity> forUpdate = new ArrayList<>();
list.forEach(vw -> { list.forEach(vw -> {
if (types.stream().anyMatch(t -> Objects.equals(t.getName(), vw.getName()))) { if (types.stream().anyMatch(t -> Objects.equals(t.getId(), vw.getWorkingTypeId()))) {
VirtualWorkingEntity entity = new VirtualWorkingEntity(); VirtualWorkingEntity entity = new VirtualWorkingEntity();
if (Objects.isNull(vw.getId()) || 0 == vw.getId()) { if (Objects.isNull(vw.getId()) || 0 == vw.getId()) {
entity = new VirtualWorkingEntity(); entity = new VirtualWorkingEntity();
entity.setName(vw.getName()); entity.setWorkingTypeId(vw.getWorkingTypeId());
entity.setCreateBy(SessionUtil.getRealName()); entity.setCreateBy(SessionUtil.getRealName());
entity.setCreateTime(LocalDateTime.now()); entity.setCreateTime(LocalDateTime.now());
forAdd.add(entity); forAdd.add(entity);
@ -85,9 +83,13 @@ public class VirtualWorkingService extends ServiceImpl<VirtualWorkingMapper, Vir
} }
@Transactional @Transactional
public void deleteNotInNames(@NotNull List<String> collect) { public void deleteNotInIds(@NotNull List<Integer> ids) {
if (CollectionUtil.isNotEmpty(collect)) { if (CollectionUtil.isNotEmpty(ids)) {
baseMapper.delete(Wrappers.lambdaQuery(VirtualWorkingEntity.class).notIn(VirtualWorkingEntity::getName, collect)); baseMapper.delete(Wrappers.lambdaQuery(VirtualWorkingEntity.class).notIn(VirtualWorkingEntity::getWorkingTypeId, ids));
} }
} }
public List<VirtualWorkingItemVO> listDTO() {
return baseMapper.listDTO();
}
} }

View File

@ -16,6 +16,7 @@ import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@ -28,12 +29,16 @@ public class WorkingTypeService extends ServiceImpl<WorkingTypeMapper, WorkingTy
remove(new QueryWrapper<>()); remove(new QueryWrapper<>());
return; return;
} }
baseMapper.delete(Wrappers.lambdaQuery(WorkingTypeEntity.class).notIn(WorkingTypeEntity::getId, list.stream().map(WorkingTypeQuery::getId).filter(Objects::nonNull).collect(Collectors.toSet()))); Set<Integer> ids = list.stream().map(WorkingTypeQuery::getId).filter(Objects::nonNull).collect(Collectors.toSet());
if (CollectionUtil.isNotEmpty(ids)) {
baseMapper.delete(Wrappers.lambdaQuery(WorkingTypeEntity.class).notIn(WorkingTypeEntity::getId, ids));
}
List<WorkingTypeEntity> forAdd = new ArrayList<>(); List<WorkingTypeEntity> forAdd = new ArrayList<>();
list.forEach(l -> { list.forEach(l -> {
if (Objects.isNull(l.getId()) || 0 == l.getId()) { if (Objects.isNull(l.getId()) || 0 == l.getId()) {
WorkingTypeEntity entity = new WorkingTypeEntity(); WorkingTypeEntity entity = new WorkingTypeEntity();
entity.setName(l.getName()); entity.setName(l.getName());
entity.setCode(l.getCode());
entity.setCreateBy(SessionUtil.getRealName()); entity.setCreateBy(SessionUtil.getRealName());
entity.setCreateTime(LocalDateTime.now()); entity.setCreateTime(LocalDateTime.now());
forAdd.add(entity); forAdd.add(entity);

View File

@ -140,4 +140,28 @@ public class StringUtil {
if (StrUtil.isBlank(str)) return str; if (StrUtil.isBlank(str)) return str;
return str.toUpperCase(); return str.toUpperCase();
} }
/**
* 判断两个版本号最后2位是否在同一个区间内1-11为一个区间12-20为一个区间21号到月底为一个区间
* @param v1 版本号1
* @param v2 版本号2
* @return true 表示在同一个区间内false 表示不在同一个区间内
*/
public static boolean inSameInterval(String v1, String v2) {
if (!StrUtil.equals(v1.substring(0, 6), v2.substring(0, 6))) {
return false;
}
int i1 = Integer.parseInt(v1.substring(6));
int i2 = Integer.parseInt(v2.substring(6));
boolean i1area1 = i1 >= 1 && i1 <= 11;
boolean i1area2 = i1 >= 12 && i1 <= 20;
boolean i1area3 = i1 >= 21;
boolean i2area1 = i2 >= 1 && i2 <= 11;
boolean i2area2 = i2 >= 12 && i2 <= 20;
boolean i2area3 = i2 >= 21;
return (i1area1 && i2area1) || (i1area2 && i2area2) || (i1area3 && i2area3);
}
} }

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nflg.product.technology.mapper.master.BomCostMapper">
<select id="getLatest" resultType="com.nflg.product.technology.pojo.entity.BomCostEntity">
SELECT MAX(id) id,material_no,MAX(version) version
FROM t_technology_bom_cost
WHERE material_no in
<foreach collection="materialNos" item="materialNo" open="(" close=")" separator=",">
#{materialNo}
</foreach>
GROUP BY material_no
</select>
</mapper>

View File

@ -79,12 +79,15 @@
</select> </select>
<select id="getInfos" resultType="com.nflg.product.technology.pojo.dto.EBomDTO"> <select id="getInfos" resultType="com.nflg.product.technology.pojo.dto.EBomDTO">
select a.material_no AS 'materialNo',a.drawing_no AS 'drawingNo',a.material_desc AS 'materialDesc' select a.row_id AS 'materialRowId',a.material_no AS 'materialNo',a.drawing_no AS 'drawingNo'
,a.material_unit AS 'materialUnit',CONVERT(a.material_weight, DECIMAL(12,4)) AS 'unitWeight' ,a.material_desc AS 'materialDesc',a.material_unit AS 'materialUnit'
,a.material_category_code AS 'materialCategoryCode',a.last_purchase_price AS 'lastPurchasePrice' ,CONVERT(a.material_weight, DECIMAL(12,4)) AS 'unitWeight',a.material_category_code AS
,b.rel_category_code AS 'relCategoryCode' 'materialCategoryCode',a.last_purchase_price AS 'lastPurchasePrice'
,b.category_name AS 'categoryName' ,b.rel_category_code AS 'relCategoryCode',b.category_name AS 'categoryName'
from t_material_main a join t_material_category b on a.material_category_code=b.category_code ,g.group_name AS 'groupName'
from t_material_main a
LEFT JOIN t_material_category b on a.material_category_code=b.category_code
LEFT JOIN t_material_raw_material_group g ON a.raw_material_group=g.group_code
where material_no in where material_no in
<foreach collection="materialNos" item="item" open="(" close=")" separator=","> <foreach collection="materialNos" item="item" open="(" close=")" separator=",">
#{item} #{item}

View File

@ -2,4 +2,21 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nflg.product.technology.mapper.master.ProcessRouteTaskProcessesMapper"> <mapper namespace="com.nflg.product.technology.mapper.master.ProcessRouteTaskProcessesMapper">
<select id="getWorkingHours" resultType="java.util.Map">
SELECT
CONCAT_WS('-',rt.material_no,t.`name`) AS 'material_work',
SUM(IFNULL(r.two_work_hours, 0)) work_hours
FROM
t_technology_working_type t
INNER JOIN t_process_workcenter w ON w.working_type = t.`code`
INNER JOIN t_process_route_task_processes r ON r.work_center = w.work_center
INNER JOIN t_process_route_task rt ON r.task_row_id = rt.row_id
WHERE
rt.material_no IN
<foreach collection="materialNos" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
GROUP BY
rt.material_no,t.`name`
</select>
</mapper> </mapper>

View File

@ -2,4 +2,9 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nflg.product.technology.mapper.master.VirtualWorkingMapper"> <mapper namespace="com.nflg.product.technology.mapper.master.VirtualWorkingMapper">
<select id="listDTO" resultType="com.nflg.product.technology.pojo.vo.VirtualWorkingItemVO">
SELECT v.*, t.`name` AS 'workingTypeName', t.`code` AS 'workingTypeCode'
FROM t_technology_virtual_working v
INNER JOIN t_technology_working_type t ON v.workingtype_id = t.id
</select>
</mapper> </mapper>

View File

@ -0,0 +1,41 @@
import com.nflg.product.technology.util.StringUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class StringUtilTest {
@Test
public void test1() {
String v1 = "20241204";
String v2 = "20241211";
Assertions.assertTrue(StringUtil.inSameInterval(v1, v2));
}
@Test
public void test2() {
String v1 = "20241204";
String v2 = "20241212";
Assertions.assertFalse(StringUtil.inSameInterval(v1, v2));
}
@Test
public void test3() {
String v1 = "20241212";
String v2 = "20241220";
Assertions.assertTrue(StringUtil.inSameInterval(v1, v2));
}
@Test
public void test4() {
String v1 = "20241112";
String v2 = "20241220";
Assertions.assertFalse(StringUtil.inSameInterval(v1, v2));
}
@Test
public void test5() {
String v1 = "20240521";
String v2 = "20240531";
Assertions.assertTrue(StringUtil.inSameInterval(v1, v2));
}
}