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.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);
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -66,4 +66,11 @@ public class EBomDTO {
* 父物料编码
*/
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")
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 = "每小时辅助费用")

View File

@ -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;
}

View File

@ -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("年度总费用")

View File

@ -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;
}

View File

@ -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;
}

View File

@ -49,4 +49,9 @@ public class BomCostSingleLayerVO implements Serializable {
@ApiModelProperty("辅助制造成本")
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() {
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;
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;
}

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.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);

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.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) {

View File

@ -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();
}
}

View File

@ -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<>());
}
}

View File

@ -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) {

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.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();
}
}

View File

@ -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);

View File

@ -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);
}
}

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 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}

View File

@ -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>

View File

@ -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>

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));
}
}