feat(产品成本分析): BOM组件成本分析
This commit is contained in:
parent
d31e00cec2
commit
8665c1a793
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -3,6 +3,10 @@ package com.nflg.product.technology.mapper.master;
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.nflg.product.technology.pojo.entity.ProcessRouteTaskProcessesEntity;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 工艺路线-工序 Mapper 接口
|
||||
|
|
@ -13,4 +17,5 @@ import com.nflg.product.technology.pojo.entity.ProcessRouteTaskProcessesEntity;
|
|||
*/
|
||||
public interface ProcessRouteTaskProcessesMapper extends BaseMapper<ProcessRouteTaskProcessesEntity> {
|
||||
|
||||
Map<String, BigDecimal> getWorkingHours(Set<String> materialNos);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,14 @@ package com.nflg.product.technology.mapper.master;
|
|||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.nflg.product.technology.pojo.entity.VirtualWorkingEntity;
|
||||
import com.nflg.product.technology.pojo.vo.VirtualWorkingItemVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 曹鹏飞
|
||||
* @date 2024/11/23 10:26:09
|
||||
*/
|
||||
public interface VirtualWorkingMapper extends BaseMapper<VirtualWorkingEntity> {
|
||||
List<VirtualWorkingItemVO> listDTO();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
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.vo.VirtualWorkingItemVO;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -9,7 +9,7 @@ import java.util.List;
|
|||
@Data
|
||||
public class BomCostCalculateConfig {
|
||||
|
||||
private List<VirtualWorkingEntity> virtualWorkings;
|
||||
private List<VirtualWorkingItemVO> virtualWorkings;
|
||||
|
||||
private VirtualWorkingManday manday;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,4 +66,11 @@ public class EBomDTO {
|
|||
* 父物料编码
|
||||
*/
|
||||
private String parentMaterialNo;
|
||||
|
||||
/**
|
||||
* 材料分组名称
|
||||
*/
|
||||
private String groupName;
|
||||
|
||||
private Long materialRowId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -26,9 +26,9 @@ public class VirtualWorkingEntity extends EntityBase implements Serializable {
|
|||
@ApiModelProperty(value = "主键行id")
|
||||
private Integer id;
|
||||
|
||||
@TableField(value = "name")
|
||||
@ApiModelProperty(value = "工时类型")
|
||||
private String name;
|
||||
@TableField(value = "workingtype_id")
|
||||
@ApiModelProperty("工时类型行id")
|
||||
private Integer workingTypeId;
|
||||
|
||||
@TableField(value = "hourly_auxiliary_fee")
|
||||
@ApiModelProperty(value = "每小时辅助费用")
|
||||
|
|
|
|||
|
|
@ -10,13 +10,12 @@ import lombok.Data;
|
|||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@ApiModel(value = "com-nflg-product-technology-pojo-entity-WorkingTypeEntity")
|
||||
@TableName(value = "t_technology_working_type")
|
||||
public class WorkingTypeEntity implements Serializable {
|
||||
public class WorkingTypeEntity extends EntityBase implements Serializable {
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "主键行id")
|
||||
|
|
@ -26,11 +25,7 @@ public class WorkingTypeEntity implements Serializable {
|
|||
@ApiModelProperty(value = "名称")
|
||||
private String name;
|
||||
|
||||
@TableField(value = "create_by")
|
||||
@ApiModelProperty(value = "创建人")
|
||||
private String createBy;
|
||||
|
||||
@TableField(value = "create_time")
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
@TableField(value = "code")
|
||||
@ApiModelProperty(value = "编号")
|
||||
private String code;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ import lombok.Data;
|
|||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Positive;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
|
|
@ -23,16 +22,23 @@ public class VirtualWorking implements Serializable {
|
|||
@ApiModelProperty(value = "主键行id")
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty("工时类型")
|
||||
@NotBlank(message = "工时类型不能为空")
|
||||
private String name;
|
||||
@ApiModelProperty("工时类型行id")
|
||||
@NotNull(message = "工时类型行id不能为空")
|
||||
@Min(value = 1, message = "工时类型行id无效")
|
||||
private Integer workingTypeId;
|
||||
|
||||
@ApiModelProperty("工时类型名称")
|
||||
private String workingTypeName;
|
||||
|
||||
@ApiModelProperty("工时类型编号")
|
||||
private String workingTypeCode;
|
||||
|
||||
@ApiModelProperty("每小时辅助费用")
|
||||
@Min(value = 0, message = "每小时辅助费用必须大于等于0")
|
||||
private BigDecimal hourlyAuxiliaryFee;
|
||||
|
||||
@ApiModelProperty("本车间一线人数")
|
||||
@Positive(message = "本车间一线人数必须大于0")
|
||||
@Min(value = 0, message = "本车间一线人数必须大于等于0")
|
||||
private Integer userNum;
|
||||
|
||||
@ApiModelProperty("年度总费用")
|
||||
|
|
|
|||
|
|
@ -21,4 +21,9 @@ public class WorkingTypeQuery implements Serializable {
|
|||
@NotBlank(message = "名称不能为空")
|
||||
@Length(max = 10, message = "名称不能超过10个字")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("编号")
|
||||
@NotBlank(message = "编号不能为空")
|
||||
@Length(max = 10, message = "编号不能超过10个字")
|
||||
private String code;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,10 +56,10 @@ public class BomCostMultilayerVO implements Serializable {
|
|||
private BigDecimal totalPaintCost;
|
||||
|
||||
@ApiModelProperty("单件标准人工工资")
|
||||
private BigDecimal standardPieceRateSalary;
|
||||
private BigDecimal directManualProductionCost;
|
||||
|
||||
@ApiModelProperty("标准人工工资")
|
||||
private BigDecimal totalStandardPieceRateSalary;
|
||||
private BigDecimal totalDirectManualProductionCost;
|
||||
|
||||
@ApiModelProperty("单件辅助费用")
|
||||
private BigDecimal auxiliaryManufacturingCost;
|
||||
|
|
@ -69,4 +69,9 @@ public class BomCostMultilayerVO implements Serializable {
|
|||
|
||||
@ApiModelProperty("子物料列表")
|
||||
private List<BomCostMultilayerVO> children = new ArrayList<>();
|
||||
|
||||
@ApiModelProperty("物料行id")
|
||||
private Long materialRowId;
|
||||
|
||||
private String relCategoryCode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,4 +49,9 @@ public class BomCostSingleLayerVO implements Serializable {
|
|||
|
||||
@ApiModelProperty("辅助制造成本")
|
||||
private BigDecimal auxiliaryManufacturingCost;
|
||||
|
||||
@ApiModelProperty("物料行id")
|
||||
private Long materialRowId;
|
||||
|
||||
private String relCategoryCode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,4 +80,17 @@ public class MaterialCostVO implements Serializable {
|
|||
public Integer getLeadTime() {
|
||||
return RandomUtil.randomInt(1000);
|
||||
}
|
||||
|
||||
@ApiModelProperty("物料行id")
|
||||
private Long materialRowId;
|
||||
|
||||
public Long getMaterialRowId() {
|
||||
return 1730039758209073154L;
|
||||
}
|
||||
|
||||
private String relCategoryCode;
|
||||
|
||||
public String getRelCategoryCode() {
|
||||
return "21";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
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.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author 曹鹏飞
|
||||
|
|
@ -15,17 +16,16 @@ import java.time.LocalDateTime;
|
|||
@Data
|
||||
@Accessors(chain = true)
|
||||
@ApiModel(value = "com-nflg-product-technology-pojo-vo-WorkingTypeVO")
|
||||
public class WorkingTypeVO implements Serializable {
|
||||
public class WorkingTypeVO extends EntityBase implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "主键行id")
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty("工时类型")
|
||||
@ApiModelProperty("工时类型名称")
|
||||
@JsonProperty("workingTypeName")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "创建人")
|
||||
private String createBy;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
@ApiModelProperty("工时类型编号")
|
||||
@JsonProperty("workingTypeCode")
|
||||
private String code;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.EBomDTO;
|
||||
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.vo.VirtualWorkingItemVO;
|
||||
import com.nflg.product.technology.util.JsonUtil;
|
||||
import com.nflg.product.technology.util.VUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -41,6 +45,15 @@ public class BomCostCalculateService {
|
|||
@Resource
|
||||
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");
|
||||
|
||||
public List<EBomCostCacheDTO> calculate(String materialNo, BomCostCalculateConfig config) {
|
||||
public List<EBomCostCacheDTO> calculate(String materialNo) {
|
||||
VUtils.isTure(StrUtil.isBlank(materialNo)).throwMessage("物料编号不能为空");
|
||||
List<EBomDTO> datas = new ArrayList<>();
|
||||
EBomParentEntity parent = ebomService.getParent(materialNo);
|
||||
|
|
@ -60,12 +73,18 @@ public class BomCostCalculateService {
|
|||
EBomDTO pDto = convert(parent);
|
||||
datas.add(pDto);
|
||||
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);
|
||||
calculateBom(pDto, datas, config, result);
|
||||
calculateBom(pDto, datas, config, processRouteTaskProcessesService.getWorkingHours(Collections.singleton(materialNo)), 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));
|
||||
List<EBomDTO> children = datas.stream()
|
||||
.filter(d -> StrUtil.equals(d.getParentMaterialNo(), dto.getMaterialNo()))
|
||||
|
|
@ -73,29 +92,32 @@ public class BomCostCalculateService {
|
|||
if (StrUtil.isBlank(cdata)) {
|
||||
EBomCostCacheDTO cdto = new EBomCostCacheDTO();
|
||||
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)) {
|
||||
//没有子级,直接计算成本
|
||||
log.debug(StrUtil.format("BOM成本计算 {} 直接计算", dto.getMaterialNo()));
|
||||
// 计算自身
|
||||
cdto.setPurchasedParts(!STEELS_CATEGORY_CODE.contains(dto.getMaterialCategoryCode()));
|
||||
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 {
|
||||
//有子级,先计算子级成本
|
||||
cdto.setPurchasedParts(false);
|
||||
//计算子级成本
|
||||
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());
|
||||
List<ProductionCostDTO> productionCosts = new ArrayList<>();
|
||||
for (EBomCostCacheDTO c : childrenCost) {
|
||||
|
|
@ -127,8 +149,8 @@ public class BomCostCalculateService {
|
|||
cdto.setProductionCosts(productionCosts);
|
||||
}
|
||||
}
|
||||
log.debug(StrUtil.format("BOM成本计算 {} 根据子级计算", dto.getMaterialNo()));
|
||||
}
|
||||
log.debug(StrUtil.format("BOM成本计算 {} 实时计算", dto.getMaterialNo()));
|
||||
result.add(cdto);
|
||||
cdata = JsonUtil.toJson(cdto);
|
||||
log.debug(cdata);
|
||||
|
|
@ -139,12 +161,12 @@ public class BomCostCalculateService {
|
|||
log.debug(cdata);
|
||||
EBomCostCacheDTO cdto = JsonUtil.fromJson(cdata, EBomCostCacheDTO.class);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
private List<ProductionCostDTO> calculateProductionCosts(BomCostCalculateConfig config) {
|
||||
private List<ProductionCostDTO> calculateProductionCosts(EBomDTO d, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
|
||||
List<ProductionCostDTO> productionCosts = new ArrayList<>();
|
||||
BigDecimal hourlyWages;
|
||||
BigDecimal benefit;
|
||||
|
|
@ -154,9 +176,9 @@ public class BomCostCalculateService {
|
|||
BigDecimal feeWorkshopOffice;
|
||||
BigDecimal auxiliaryDepartmentLaborCosts;
|
||||
BigDecimal assistantFee;
|
||||
for (VirtualWorkingEntity vw : config.getVirtualWorkings()) {
|
||||
for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
|
||||
ProductionCostDTO dto = new ProductionCostDTO();
|
||||
dto.setName(vw.getName());
|
||||
dto.setName(vw.getWorkingTypeName());
|
||||
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);
|
||||
|
|
@ -168,14 +190,13 @@ public class BomCostCalculateService {
|
|||
dto.setCost(hourlyWages.add(benefit).add(auxiliaryMaterialsAndConsumables).add(feeEquipmentDepreciation)
|
||||
.add(feeEquipmentDepreciation).add(feeWorkshopLaborCost).add(feeWorkshopOffice)
|
||||
.add(auxiliaryDepartmentLaborCosts).add(assistantFee)
|
||||
.multiply(getGsForWorkingType(vw.getName())));
|
||||
.multiply(getGsForWorkingType(d, workHours, vw)));
|
||||
}
|
||||
return productionCosts;
|
||||
}
|
||||
|
||||
private BigDecimal calculatePaintCost(EBomDTO dto) {
|
||||
String lable = "";// TODO 物料标签对应的油漆标签
|
||||
PaintCostConfigEntity entity = paintCostConfigService.getCost(lable);
|
||||
PaintCostConfigEntity entity = paintCostConfigService.getCost(dto.getGroupName());
|
||||
if (Objects.nonNull(entity)) {
|
||||
return NumberUtil.mul(dto.getUnitWeight(), entity.getCost());
|
||||
} 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;
|
||||
for (VirtualWorkingEntity vw : virtualWorkings) {
|
||||
cost = cost.add(vw.getWorkshopOfficeFee().multiply(getGsForWorkingType(vw.getName())));
|
||||
for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
|
||||
cost = cost.add(vw.getWorkshopOfficeFee().multiply(getGsForWorkingType(dto, workHours, vw)));
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
private BigDecimal calculateAuxiliaryDepartmentExpenses(List<VirtualWorkingEntity> virtualWorkings) {
|
||||
private BigDecimal calculateAuxiliaryDepartmentExpenses(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
|
||||
BigDecimal cost = BigDecimal.ZERO;
|
||||
for (VirtualWorkingEntity vw : virtualWorkings) {
|
||||
cost = cost.add(vw.getAssistantFee().multiply(getGsForWorkingType(vw.getName())));
|
||||
for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
|
||||
cost = cost.add(vw.getAssistantFee().multiply(getGsForWorkingType(dto, workHours, vw)));
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
private BigDecimal calculateAuxiliaryDepartmentLaborCost(List<VirtualWorkingEntity> virtualWorkings) {
|
||||
private BigDecimal calculateAuxiliaryDepartmentLaborCost(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
|
||||
BigDecimal cost = BigDecimal.ZERO;
|
||||
for (VirtualWorkingEntity vw : virtualWorkings) {
|
||||
cost = cost.add(vw.getAssistantLaborFee().multiply(getGsForWorkingType(vw.getName())));
|
||||
for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
|
||||
cost = cost.add(vw.getAssistantLaborFee().multiply(getGsForWorkingType(dto, workHours, vw)));
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
private BigDecimal calculateWorkshopManagementLaborCost(List<VirtualWorkingEntity> virtualWorkings) {
|
||||
private BigDecimal calculateWorkshopManagementLaborCost(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
|
||||
BigDecimal cost = BigDecimal.ZERO;
|
||||
for (VirtualWorkingEntity vw : virtualWorkings) {
|
||||
cost = cost.add(vw.getWorkshopLaborFee().multiply(getGsForWorkingType(vw.getName())));
|
||||
for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
|
||||
cost = cost.add(vw.getWorkshopLaborFee().multiply(getGsForWorkingType(dto, workHours, vw)));
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
private BigDecimal calculateDepreciationCost(List<VirtualWorkingEntity> virtualWorkings) {
|
||||
private BigDecimal calculateDepreciationCost(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
|
||||
BigDecimal cost = BigDecimal.ZERO;
|
||||
for (VirtualWorkingEntity vw : virtualWorkings) {
|
||||
cost = cost.add(vw.getEquipmentDepreciationFee().multiply(getGsForWorkingType(vw.getName())));
|
||||
for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
|
||||
cost = cost.add(vw.getEquipmentDepreciationFee().multiply(getGsForWorkingType(dto, workHours, vw)));
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
private BigDecimal calculateHydropowerCost(List<VirtualWorkingEntity> virtualWorkings) {
|
||||
private BigDecimal calculateHydropowerCost(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
|
||||
BigDecimal cost = BigDecimal.ZERO;
|
||||
for (VirtualWorkingEntity vw : virtualWorkings) {
|
||||
cost = cost.add(vw.getConsumablesFee().multiply(getGsForWorkingType(vw.getName())));
|
||||
for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
|
||||
cost = cost.add(vw.getConsumablesFee().multiply(getGsForWorkingType(dto, workHours, vw)));
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
private BigDecimal getGsForWorkingType(String type) {
|
||||
//TODO 获取工时类型对应的工时
|
||||
return BigDecimal.ZERO;
|
||||
private BigDecimal getGsForWorkingType(EBomDTO dto, Map<String, BigDecimal> workHours, VirtualWorkingItemVO vw) {
|
||||
return workHours.getOrDefault(dto.getMaterialNo() + '-' + vw.getWorkingTypeName(), BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
private BigDecimal calculateWelfareExpenses(EBomDTO dto, VirtualWorkingManday manday) {
|
||||
return getTGS().multiply(Optional.ofNullable(manday.getBenefit()).orElse(BigDecimal.ZERO));
|
||||
private BigDecimal calculateWelfareExpenses(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
|
||||
return getTGS(dto, config, workHours).multiply(Optional.ofNullable(config.getManday().getBenefit()).orElse(BigDecimal.ZERO));
|
||||
}
|
||||
|
||||
private BigDecimal calculatePieceRateSalary(EBomDTO dto, VirtualWorkingManday manday) {
|
||||
return getTGS().multiply(Optional.ofNullable(manday.getHourlyWages()).orElse(BigDecimal.ZERO));
|
||||
private BigDecimal calculatePieceRateSalary(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
|
||||
return getTGS(dto, config, workHours).multiply(Optional.ofNullable(config.getManday().getHourlyWages()).orElse(BigDecimal.ZERO));
|
||||
}
|
||||
|
||||
private BigDecimal getTGS() {
|
||||
// TODO 获取总工时
|
||||
return BigDecimal.ZERO;
|
||||
private BigDecimal getTGS(EBomDTO dto, BomCostCalculateConfig config, Map<String, BigDecimal> workHours) {
|
||||
BigDecimal gs = BigDecimal.ZERO;
|
||||
for (VirtualWorkingItemVO vw : config.getVirtualWorkings()) {
|
||||
gs = gs.add(getGsForWorkingType(dto, workHours, vw));
|
||||
}
|
||||
return gs;
|
||||
}
|
||||
|
||||
private BigDecimal calculatePurchasedPartsCost(EBomDTO dto) {
|
||||
|
|
@ -255,13 +278,11 @@ public class BomCostCalculateService {
|
|||
|
||||
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 (StrUtil.isNotBlank(dto.getGroupName())) {
|
||||
SteelsCostConfigEntity steelsCostConfigEntity = steelsCostConfigService.getCost(dto.getGroupName());
|
||||
if (Objects.nonNull(steelsCostConfigEntity)) {
|
||||
price = Optional.ofNullable(steelsCostConfigEntity.getCost()).orElse(BigDecimal.ZERO);
|
||||
wastage = Optional.ofNullable(steelsCostConfigEntity.getWastage()).orElse(BigDecimal.ZERO);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ package com.nflg.product.technology.service;
|
|||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.nflg.product.technology.constant.TechnologyConfigEnum;
|
||||
import com.nflg.product.technology.pojo.entity.VirtualWorkingEntity;
|
||||
import com.nflg.product.technology.pojo.entity.WorkingTypeEntity;
|
||||
|
|
@ -63,15 +62,16 @@ public class CostConfigService {
|
|||
manday.setBenefit(technologyConfigService.getBenefit());
|
||||
vo.setManday(manday);
|
||||
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)) {
|
||||
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));
|
||||
}
|
||||
return vo;
|
||||
|
|
@ -88,7 +88,7 @@ public class CostConfigService {
|
|||
@Transactional
|
||||
public void saveWorkingTypes(List<WorkingTypeQuery> 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) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.nflg.product.technology.service;
|
||||
|
||||
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.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
|
@ -59,6 +60,9 @@ public class PaintCostConfigService extends ServiceImpl<PaintCostConfigMapper, P
|
|||
}
|
||||
|
||||
public PaintCostConfigEntity getCost(String name) {
|
||||
if (StrUtil.isBlank(name)) {
|
||||
return null;
|
||||
}
|
||||
return lambdaQuery().eq(PaintCostConfigEntity::getName, name).one();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,12 @@ import com.nflg.product.technology.mapper.master.ProcessRouteTaskProcessesMapper
|
|||
import com.nflg.product.technology.pojo.entity.ProcessRouteTaskProcessesEntity;
|
||||
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>
|
||||
* 工艺路线-工序 服务类
|
||||
|
|
@ -16,4 +22,7 @@ import org.springframework.stereotype.Service;
|
|||
@Service
|
||||
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<>());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,11 @@ package com.nflg.product.technology.service;
|
|||
|
||||
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.entity.EBomChildEntity;
|
||||
import com.nflg.product.technology.pojo.entity.EBomParentEntity;
|
||||
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.util.MapUtil;
|
||||
import com.nflg.product.technology.util.RandomUtil;
|
||||
|
|
@ -50,14 +48,11 @@ public class ProductCostAnalysisService {
|
|||
@Resource
|
||||
private TechnologyConfigService technologyConfigService;
|
||||
|
||||
@Resource
|
||||
private BomCostService bomCostService;
|
||||
|
||||
public List<BomCostSingleLayerVO> getBomCostSingleLayer(String materialNo) {
|
||||
BomCostCalculateConfig cnfig = new BomCostCalculateConfig();
|
||||
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<EBomCostCacheDTO> datas = bomCostCalculateService.calculate(materialNo);
|
||||
EBomParentEntity parent = ebomService.getParent(materialNo);
|
||||
return buildSingleLayerChildren(parent.getRowId(), datas);
|
||||
}
|
||||
|
|
@ -79,6 +74,8 @@ public class ProductCostAnalysisService {
|
|||
cvo.setMaterialDesc(cpm.getMaterialDesc());
|
||||
cvo.setMaterialCategoryName(cpm.getCategoryName());
|
||||
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);
|
||||
cvo.setVersion(Objects.isNull(parent) ? "A00" : parent.getCurrentVersion());
|
||||
|
|
@ -97,13 +94,7 @@ public class ProductCostAnalysisService {
|
|||
}
|
||||
|
||||
public BomCostMultilayerVO getBomCostMultilayer(String materialNo) {
|
||||
BomCostCalculateConfig cnfig = new BomCostCalculateConfig();
|
||||
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<EBomCostCacheDTO> datas = bomCostCalculateService.calculate(materialNo);
|
||||
List<EBomDTO> materials = materialMainService.getInfos(datas.stream().map(EBomCostCacheDTO::getMaterialNo).collect(Collectors.toSet()));
|
||||
EBomParentEntity parent = ebomService.getParent(materialNo);
|
||||
BomCostMultilayerVO vo = new BomCostMultilayerVO();
|
||||
|
|
@ -113,6 +104,8 @@ public class ProductCostAnalysisService {
|
|||
vo.setMaterialDesc(pm.getMaterialDesc());
|
||||
vo.setMaterialCategoryName(pm.getCategoryName());
|
||||
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);
|
||||
if (Objects.nonNull(cost)) {
|
||||
|
|
@ -124,8 +117,8 @@ public class ProductCostAnalysisService {
|
|||
vo.setTotalMaterialCost(cost.getMaterialCost());
|
||||
vo.setPaintCost(cost.getPaintCost());
|
||||
vo.setTotalPaintCost(cost.getPaintCost());
|
||||
vo.setStandardPieceRateSalary(cost.getPieceRateSalary());
|
||||
vo.setTotalStandardPieceRateSalary(cost.getPieceRateSalary());
|
||||
vo.setDirectManualProductionCost(cost.getDirectManualProductionCost());
|
||||
vo.setTotalDirectManualProductionCost(cost.getDirectManualProductionCost());
|
||||
vo.setAuxiliaryManufacturingCost(cost.getAuxiliaryManufacturingCost());
|
||||
vo.setTotalAuxiliaryManufacturingCost(cost.getAuxiliaryManufacturingCost());
|
||||
}
|
||||
|
|
@ -143,6 +136,8 @@ public class ProductCostAnalysisService {
|
|||
cvo.setMaterialDesc(cpm.getMaterialDesc());
|
||||
cvo.setMaterialCategoryName(cpm.getCategoryName());
|
||||
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);
|
||||
if (Objects.nonNull(ccost)) {
|
||||
|
|
@ -154,8 +149,8 @@ public class ProductCostAnalysisService {
|
|||
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.setDirectManualProductionCost(ccost.getDirectManualProductionCost().multiply(cvo.getTotalNum()));
|
||||
cvo.setTotalDirectManualProductionCost(ccost.getDirectManualProductionCost());
|
||||
cvo.setAuxiliaryManufacturingCost(ccost.getAuxiliaryManufacturingCost());
|
||||
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) {
|
||||
// TODO 待实现
|
||||
ProductCostVO vo = new ProductCostVO();
|
||||
|
|
@ -309,7 +290,8 @@ public class ProductCostAnalysisService {
|
|||
}
|
||||
|
||||
public void saveCost(String materialNo) {
|
||||
// TODO 待实现
|
||||
List<EBomCostCacheDTO> datas = bomCostCalculateService.calculate(materialNo);
|
||||
bomCostService.save(datas);
|
||||
}
|
||||
|
||||
public List<String> getCostVersion(@Valid @NotBlank String materialNo) {
|
||||
|
|
|
|||
|
|
@ -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.WorkingTypeEntity;
|
||||
import com.nflg.product.technology.pojo.query.VirtualWorking;
|
||||
import com.nflg.product.technology.pojo.vo.VirtualWorkingItemVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
|
@ -33,9 +34,6 @@ public class VirtualWorkingService extends ServiceImpl<VirtualWorkingMapper, Vir
|
|||
@Resource
|
||||
private WorkingTypeService workingTypeService;
|
||||
|
||||
@Resource
|
||||
private TechnologyConfigService technologyConfigService;
|
||||
|
||||
@Transactional()
|
||||
public void save(List<VirtualWorking> list) {
|
||||
if (CollectionUtil.isEmpty(list)) {
|
||||
|
|
@ -50,11 +48,11 @@ public class VirtualWorkingService extends ServiceImpl<VirtualWorkingMapper, Vir
|
|||
List<VirtualWorkingEntity> forAdd = new ArrayList<>();
|
||||
List<VirtualWorkingEntity> forUpdate = new ArrayList<>();
|
||||
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();
|
||||
if (Objects.isNull(vw.getId()) || 0 == vw.getId()) {
|
||||
entity = new VirtualWorkingEntity();
|
||||
entity.setName(vw.getName());
|
||||
entity.setWorkingTypeId(vw.getWorkingTypeId());
|
||||
entity.setCreateBy(SessionUtil.getRealName());
|
||||
entity.setCreateTime(LocalDateTime.now());
|
||||
forAdd.add(entity);
|
||||
|
|
@ -85,9 +83,13 @@ public class VirtualWorkingService extends ServiceImpl<VirtualWorkingMapper, Vir
|
|||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteNotInNames(@NotNull List<String> collect) {
|
||||
if (CollectionUtil.isNotEmpty(collect)) {
|
||||
baseMapper.delete(Wrappers.lambdaQuery(VirtualWorkingEntity.class).notIn(VirtualWorkingEntity::getName, collect));
|
||||
public void deleteNotInIds(@NotNull List<Integer> ids) {
|
||||
if (CollectionUtil.isNotEmpty(ids)) {
|
||||
baseMapper.delete(Wrappers.lambdaQuery(VirtualWorkingEntity.class).notIn(VirtualWorkingEntity::getWorkingTypeId, ids));
|
||||
}
|
||||
}
|
||||
|
||||
public List<VirtualWorkingItemVO> listDTO() {
|
||||
return baseMapper.listDTO();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import java.time.LocalDateTime;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
|
@ -28,12 +29,16 @@ public class WorkingTypeService extends ServiceImpl<WorkingTypeMapper, WorkingTy
|
|||
remove(new QueryWrapper<>());
|
||||
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.forEach(l -> {
|
||||
if (Objects.isNull(l.getId()) || 0 == l.getId()) {
|
||||
WorkingTypeEntity entity = new WorkingTypeEntity();
|
||||
entity.setName(l.getName());
|
||||
entity.setCode(l.getCode());
|
||||
entity.setCreateBy(SessionUtil.getRealName());
|
||||
entity.setCreateTime(LocalDateTime.now());
|
||||
forAdd.add(entity);
|
||||
|
|
|
|||
|
|
@ -140,4 +140,28 @@ public class StringUtil {
|
|||
if (StrUtil.isBlank(str)) return str;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -79,12 +79,15 @@
|
|||
</select>
|
||||
|
||||
<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'
|
||||
,a.material_unit AS 'materialUnit',CONVERT(a.material_weight, DECIMAL(12,4)) AS 'unitWeight'
|
||||
,a.material_category_code AS 'materialCategoryCode',a.last_purchase_price AS 'lastPurchasePrice'
|
||||
,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
|
||||
select a.row_id AS 'materialRowId',a.material_no AS 'materialNo',a.drawing_no AS 'drawingNo'
|
||||
,a.material_desc AS 'materialDesc',a.material_unit AS 'materialUnit'
|
||||
,CONVERT(a.material_weight, DECIMAL(12,4)) AS 'unitWeight',a.material_category_code AS
|
||||
'materialCategoryCode',a.last_purchase_price AS 'lastPurchasePrice'
|
||||
,b.rel_category_code AS 'relCategoryCode',b.category_name AS 'categoryName'
|
||||
,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
|
||||
<foreach collection="materialNos" item="item" open="(" close=")" separator=",">
|
||||
#{item}
|
||||
|
|
|
|||
|
|
@ -2,4 +2,21 @@
|
|||
<!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">
|
||||
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -2,4 +2,9 @@
|
|||
<!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">
|
||||
|
||||
<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>
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue