Browse Source

2026-03-13

报价的工艺页签,机器成本和人工成本也拆开,分生产和调机
master
fengyuan_yang 1 month ago
parent
commit
b10c892d91
  1. 12
      src/main/java/com/spring/modules/quote/entity/QuoteDetailRouting.java
  2. 91
      src/main/java/com/spring/modules/quote/service/impl/QuoteDetailRoutingServiceImpl.java

12
src/main/java/com/spring/modules/quote/entity/QuoteDetailRouting.java

@ -119,12 +119,24 @@ public class QuoteDetailRouting {
@TableField(exist = false)
private BigDecimal totalLaborCost;
@TableField(exist = false)
private BigDecimal totalLaborRunCost; // 人工成本-生产
@TableField(exist = false)
private BigDecimal totalLaborSetupCost; // 人工成本-调机
@TableField(exist = false)
private BigDecimal totalManCost;
@TableField(exist = false)
private BigDecimal totalMachCost;
@TableField(exist = false)
private BigDecimal totalMachRunCost; // 机器成本-生产
@TableField(exist = false)
private BigDecimal totalMachSetupCost; // 机器成本-调机
@TableField(exist = false)
private BigDecimal totalCost;
}

91
src/main/java/com/spring/modules/quote/service/impl/QuoteDetailRoutingServiceImpl.java

@ -57,25 +57,32 @@ public class QuoteDetailRoutingServiceImpl extends ServiceImpl<QuoteDetailRoutin
List<Long> ids = quoteDetailBomTreeService.getAllChildIds(detail, quoteDetailRouting.getTreeId());
ids.add(quoteDetailRouting.getTreeId());
return baseMapper.queryQuoteDetailRoutingByTreeIds(ids).stream().map(o -> {
o.setTotalLaborCost(laborCost(o, detail.getQty()));
o.setTotalManCost(manufactureCost(o, detail.getQty()));
o.setTotalMachCost(machineCost(o, detail.getQty()));
o.setTotalCost(o.getTotalLaborCost().add(o.getTotalManCost()).add(o.getTotalMachCost()));
fillCosts(o, detail.getQty());
return o;
}).collect(Collectors.toList());
}
return baseMapper.queryQuoteDetailRouting(quoteDetailRouting).stream().map(o -> {
o.setTotalLaborCost(laborCost(o, detail.getQty()));
o.setTotalManCost(manufactureCost(o, detail.getQty()));
o.setTotalMachCost(machineCost(o, detail.getQty()));
o.setTotalCost(o.getTotalLaborCost().add(o.getTotalManCost()).add(o.getTotalMachCost()));
fillCosts(o, detail.getQty());
return o;
}).collect(Collectors.toList());
}
private void fillCosts(QuoteDetailRouting o, BigDecimal qty) {
BigDecimal[] laborParts = laborCostParts(o, qty);
o.setTotalLaborSetupCost(laborParts[0].setScale(6, RoundingMode.HALF_UP));
o.setTotalLaborRunCost(laborParts[1].setScale(6, RoundingMode.HALF_UP));
o.setTotalLaborCost(laborParts[0].add(laborParts[1]).setScale(6, RoundingMode.HALF_UP));
BigDecimal[] machParts = machineCostParts(o, qty);
o.setTotalMachSetupCost(machParts[0].setScale(6, RoundingMode.HALF_UP));
o.setTotalMachRunCost(machParts[1].setScale(6, RoundingMode.HALF_UP));
o.setTotalMachCost(machParts[0].add(machParts[1]).setScale(6, RoundingMode.HALF_UP));
o.setTotalManCost(manufactureCost(o, qty));
o.setTotalCost(o.getTotalLaborCost().add(o.getTotalManCost()).add(o.getTotalMachCost()));
}
private BigDecimal unitProcessingTime(QuoteDetailRouting routing, BigDecimal produceQty, BigDecimal moq) {
BigDecimal processingTime = BigDecimal.ZERO;
if ("小时".equals(routing.getRunTimeDesc())) {
@ -95,53 +102,46 @@ public class QuoteDetailRoutingServiceImpl extends ServiceImpl<QuoteDetailRoutin
return processingTime;
}
private BigDecimal laborCost(QuoteDetailRouting quoteDetailRouting, BigDecimal qty) {
/**
* 返回 [调机人工成本, 生产人工成本]
* 调机setupLaborClassCost × setupCrewSize × laborSetupTime / MOQ
* 生产laborClassCost × (laborCycleTime / (efficiencyFactor/100) / (1 - shrinkageFactor/100)) × crewSize
*/
private BigDecimal[] laborCostParts(QuoteDetailRouting quoteDetailRouting, BigDecimal qty) {
BigDecimal setupCost = BigDecimal.ZERO;
// 调机人员等级成本
BigDecimal setupLaborClassCost = quoteDetailRouting.getSetupLaborClassCost();
// 调机人员数量
BigDecimal setupCrewSize = quoteDetailRouting.getSetupCrewSize();
// 人员调机时间
BigDecimal laborSetupTime = quoteDetailRouting.getLaborSetupTime();
if (Objects.nonNull(setupLaborClassCost) && Objects.nonNull(setupCrewSize) && Objects.nonNull(laborSetupTime)) {
if (BigDecimal.ZERO.compareTo(setupLaborClassCost) != 0 && BigDecimal.ZERO.compareTo(setupCrewSize) != 0 && BigDecimal.ZERO.compareTo(laborSetupTime) != 0) {
// 调机人员等级成本*调机人员数量*人员调机时间/moq
setupCost = setupLaborClassCost.multiply(setupCrewSize).multiply(laborSetupTime).divide(qty, 16, RoundingMode.HALF_UP);
}
}
BigDecimal laborCost = BigDecimal.ZERO;
// 人员等级成本
BigDecimal laborClassCost = quoteDetailRouting.getLaborClassCost();
// 单位产出
BigDecimal laborCycleTime = BigDecimal.ZERO;
if (!(Objects.isNull(quoteDetailRouting.getLaborRunFactor()) || BigDecimal.ZERO.compareTo(quoteDetailRouting.getLaborRunFactor()) == 0)) {
laborCycleTime = unitProcessingTime(quoteDetailRouting, quoteDetailRouting.getLaborRunFactor(), qty);
}
// 效率
BigDecimal efficiencyFactor = quoteDetailRouting.getEfficiencyFactor();
// 人数
BigDecimal crewSize = quoteDetailRouting.getCrewSize();
// 损耗
BigDecimal shrinkageFactor = quoteDetailRouting.getShrinkageFactor();
//人员等级成本*单位产出/效率/1-损耗率*人数
// 调机人员等级成本*调机人员数量*人员调机时间/moq+人员等级成本/单位产出/效率/1-损耗率*人数
// 单位产出/效率/100
BigDecimal num1 = laborCycleTime.divide(efficiencyFactor.divide(BigDecimal.valueOf(100), 16, RoundingMode.HALF_UP), 16, RoundingMode.HALF_UP);
// 单位产出/效率/100/1-损耗率/100
BigDecimal num2 = BigDecimal.ZERO;
if (Objects.nonNull(shrinkageFactor)) {
num2 = num1.divide(BigDecimal.ONE.subtract(shrinkageFactor.divide(BigDecimal.valueOf(100), 16, RoundingMode.HALF_UP)), 16, RoundingMode.HALF_UP);
}
// 单位产出/效率/100/1-损耗率*人数
if (num2.compareTo(BigDecimal.ZERO) != 0) {
// BigDecimal num3 = num2;
// 人员等级成本/单位产出/效率/100/1-损耗率*人数
laborCost = laborClassCost.multiply(num2).multiply(crewSize);
}
return setupCost.add(laborCost).setScale(6, RoundingMode.HALF_UP);
return new BigDecimal[]{setupCost, laborCost};
}
private BigDecimal laborCost(QuoteDetailRouting quoteDetailRouting, BigDecimal qty) {
BigDecimal[] parts = laborCostParts(quoteDetailRouting, qty);
return parts[0].add(parts[1]).setScale(6, RoundingMode.HALF_UP);
}
private BigDecimal manufactureCost(QuoteDetailRouting quoteDetailRouting, BigDecimal qty) {
@ -165,35 +165,32 @@ public class QuoteDetailRoutingServiceImpl extends ServiceImpl<QuoteDetailRoutin
return setupCost;
}
private BigDecimal machineCost(QuoteDetailRouting quoteDetailRouting, BigDecimal qty) {
/**
* 返回 [调机机器成本, 生产机器成本]
* 调机workCenterCost × machSetupTime / MOQ
* 生产workCenterCost / (efficiencyFactor/100) × machCycleTime / (1 - shrinkageFactor/100)
*/
private BigDecimal[] machineCostParts(QuoteDetailRouting quoteDetailRouting, BigDecimal qty) {
BigDecimal setupCost = BigDecimal.ZERO;
BigDecimal runCost = BigDecimal.ZERO;
if (Objects.nonNull(quoteDetailRouting.getWorkCenterCost()) && quoteDetailRouting.getWorkCenterCost().compareTo(BigDecimal.ZERO) > 0) {
// 加工中心成本
BigDecimal workCenterCost = quoteDetailRouting.getWorkCenterCost();
// 调机时间
BigDecimal setupTime = quoteDetailRouting.getMachSetupTime();
// 加工中心成本*调机时间/moq
setupCost = workCenterCost.multiply(setupTime.divide(qty, 16, RoundingMode.HALF_UP));
BigDecimal manufactureCost = BigDecimal.ZERO;
// 单位产出
BigDecimal machCycleTime = unitProcessingTime(quoteDetailRouting, quoteDetailRouting.getMachRunFactor(), qty);
// 效率
BigDecimal efficiencyFactor = quoteDetailRouting.getEfficiencyFactor();
// 损耗率
BigDecimal shrinkageFactor = quoteDetailRouting.getShrinkageFactor();
// 加工中心成本*调机时间/moq+加工中心成本/效率/单位产出/(1-损耗率)
// 加工中心成本/效率/单位产出/(1-损耗率)
// 加工中心成本/效率/100
BigDecimal num1 = workCenterCost.divide(efficiencyFactor.divide(BigDecimal.valueOf(100), 16, RoundingMode.HALF_UP), 16, RoundingMode.HALF_UP);
// 加工中心成本/效率/100/单位产出
BigDecimal num2 = num1.multiply(machCycleTime);
// 加工中心成本/效率/100/单位产出/1-损耗率/100
manufactureCost = num2.divide(BigDecimal.ONE.subtract(shrinkageFactor.divide(BigDecimal.valueOf(100), 16, RoundingMode.HALF_UP)), 16, RoundingMode.HALF_UP);
setupCost = setupCost.add(manufactureCost);
runCost = num2.divide(BigDecimal.ONE.subtract(shrinkageFactor.divide(BigDecimal.valueOf(100), 16, RoundingMode.HALF_UP)), 16, RoundingMode.HALF_UP);
}
return setupCost.setScale(6, RoundingMode.HALF_UP);
return new BigDecimal[]{setupCost, runCost};
}
private BigDecimal machineCost(QuoteDetailRouting quoteDetailRouting, BigDecimal qty) {
BigDecimal[] parts = machineCostParts(quoteDetailRouting, qty);
return parts[0].add(parts[1]).setScale(6, RoundingMode.HALF_UP);
}
@Override

Loading…
Cancel
Save