diff --git a/src/main/java/com/spring/modules/quote/service/impl/QuoteDetailServiceImpl.java b/src/main/java/com/spring/modules/quote/service/impl/QuoteDetailServiceImpl.java index 3382bbb7..1c904d41 100644 --- a/src/main/java/com/spring/modules/quote/service/impl/QuoteDetailServiceImpl.java +++ b/src/main/java/com/spring/modules/quote/service/impl/QuoteDetailServiceImpl.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.spring.common.exception.XJException; import com.spring.modules.oss.entity.SysOssEntity; import com.spring.modules.oss.service.SysOssService; import com.spring.modules.part.entity.PartInformationEntity; @@ -434,11 +435,13 @@ public class QuoteDetailServiceImpl extends ServiceImpl deliverQuantity = attributeList.stream().filter(a -> "SHIPPING-DELIVER-QUANTITY".equals(a.getItemNo())).findAny(); //运输其他成本 Optional otherShipCost = attributeList.stream().filter(a -> "SHIPPING-OTHER-COST".equals(a.getItemNo())).findAny(); + // 运输成本/交付数量 if (shipCost.isPresent() && deliverQuantity.isPresent()) { if (Objects.nonNull(shipCost.get().getNumValue()) && (Objects.nonNull(deliverQuantity.get().getNumValue()) && deliverQuantity.get().getNumValue().compareTo(new BigDecimal(0)) >= 1)) { shippingCost = shipCost.get().getNumValue().divide(deliverQuantity.get().getNumValue()); } } + // 运输成本/交付数量+运输其他成本 if (otherShipCost.isPresent() && Objects.nonNull(otherShipCost.get().getNumValue())){ shippingCost = shippingCost.add(otherShipCost.get().getNumValue()); } @@ -578,43 +581,144 @@ public class QuoteDetailServiceImpl extends ServiceImpl map = queryQuoteDetailCost(detail); -// BigDecimal toolCost = (BigDecimal)map.get("toolCost"); -// BigDecimal packCost = (BigDecimal)map.get("packCost"); -// BigDecimal shippingCost = (BigDecimal)map.get("shippingCost"); -// BigDecimal otherCost = (BigDecimal)map.get("otherCost"); -// BigDecimal unitQuotePrice = (BigDecimal)map.get("unitQuotePrice"); -// BigDecimal actualQuotePrice = (BigDecimal)map.get("actualQuotePrice"); -// BigDecimal labourCost = (BigDecimal)map.get("labourCost"); -// BigDecimal machineCost = (BigDecimal)map.get("machineCost"); -// BigDecimal manufactureCost = (BigDecimal)map.get("manufactureCost"); -// BigDecimal testCost = (BigDecimal)map.get("testCost"); -// BigDecimal elseCost = (BigDecimal)map.get("elseCost"); + Map map = queryQuoteDetailCost(detail); + BigDecimal toolCost = (BigDecimal)map.get("toolCost"); + BigDecimal packCost = (BigDecimal)map.get("packCost"); + BigDecimal shippingCost = (BigDecimal)map.get("shippingCost"); + BigDecimal otherCost = (BigDecimal)map.get("otherCost"); + BigDecimal unitQuotePrice = (BigDecimal)map.get("unitQuotePrice"); + BigDecimal actualQuotePrice = (BigDecimal)map.get("actualQuotePrice"); + BigDecimal labourCost = (BigDecimal)map.get("labourCost"); + BigDecimal machineCost = (BigDecimal)map.get("machineCost"); + BigDecimal manufactureCost = (BigDecimal)map.get("manufactureCost"); + BigDecimal testCost = (BigDecimal)map.get("testCost"); + BigDecimal elseCost = (BigDecimal)map.get("elseCost"); // 赋值 -// detail.setPartCost(unitQuotePrice); -// detail.setAdjustPartCost(unitQuotePrice); -// detail.setBomUnYield(actualQuotePrice); -// detail.setAdjustBomUnYield(actualQuotePrice); -// detail.setLabourCost(labourCost); -// detail.setAdjustLabourCost(labourCost); -// detail.setMachineCost(manufactureCost); -// detail.setAdjustMachineCost(manufactureCost); -// detail.setFabricateCost(manufactureCost); -// detail.setAdjustFabricateCost(manufactureCost); -// detail.setToolCost(toolCost); -// detail.setAdjustToolCost(toolCost); -// detail.setTestCost(testCost); -// detail.setAdjustTestCost(testCost); -// detail.setElseCost(elseCost); -// detail.setAdjustElseCost(elseCost); -// detail.setPackCost(packCost); -// detail.setShippingCost(shippingCost); -// detail.setOtherCost(otherCost); -// -// // 修改 -// lambdaUpdate().eq(QuoteDetail::getId, detail.getId()).update(detail); + detail.setPartCost(Optional.ofNullable(unitQuotePrice).orElse(BigDecimal.ZERO)); + detail.setAdjustPartCost(Optional.ofNullable(unitQuotePrice).orElse(BigDecimal.ZERO)); + detail.setBomUnYield(Optional.ofNullable(actualQuotePrice).orElse(BigDecimal.ZERO)); + detail.setAdjustBomUnYield(Optional.ofNullable(actualQuotePrice).orElse(BigDecimal.ZERO)); + detail.setLabourCost(Optional.ofNullable(labourCost).orElse(BigDecimal.ZERO)); + detail.setAdjustLabourCost(Optional.ofNullable(labourCost).orElse(BigDecimal.ZERO)); + detail.setMachineCost( Optional.ofNullable(machineCost).orElse(BigDecimal.ZERO)); + detail.setAdjustMachineCost( Optional.ofNullable(machineCost).orElse(BigDecimal.ZERO)); + detail.setFabricateCost( Optional.ofNullable(manufactureCost).orElse(BigDecimal.ZERO)); + detail.setAdjustFabricateCost(Optional.ofNullable(manufactureCost).orElse(BigDecimal.ZERO)); + detail.setToolCost(Optional.ofNullable(toolCost).orElse(BigDecimal.ZERO)); + detail.setAdjustToolCost(Optional.ofNullable(toolCost).orElse(BigDecimal.ZERO)); + detail.setTestCost(Optional.ofNullable(testCost).orElse(BigDecimal.ZERO)); + detail.setAdjustTestCost(Optional.ofNullable(testCost).orElse(BigDecimal.ZERO)); + detail.setElseCost(Optional.ofNullable(elseCost).orElse(BigDecimal.ZERO)); + detail.setAdjustElseCost(Optional.ofNullable(elseCost).orElse(BigDecimal.ZERO)); + detail.setPackCost(Optional.ofNullable(packCost).orElse(BigDecimal.ZERO)); + detail.setShippingCost(Optional.ofNullable(shippingCost).orElse(BigDecimal.ZERO)); + detail.setOtherCost(Optional.ofNullable(otherCost).orElse(BigDecimal.ZERO)); + // 取本身 + detail.setManageCost(Optional.ofNullable(detail.getManageCost()).orElse(BigDecimal.ZERO)); + } + + private void calculateQuoteProfitAndCost(QuoteDetail detail) { + // 处理计算总成本 + BigDecimal totalCost = detail.getAdjustPartCost() + .add(detail.getAdjustMachineCost()) + .add(detail.getAdjustFabricateCost()) + .add(detail.getAdjustLabourCost()) + .add(detail.getManageCost()) + .add(detail.getAdjustElseCost()) + .add(detail.getAdjustToolCost()) + .add(detail.getAdjustTestCost()) + .add(detail.getPackCost()) + .add(detail.getShippingCost()); + // 处理额外添加其他成本 + List calculatedItems = Arrays.asList(Optional.ofNullable(detail.getCalculatedItems()).orElse("").split(",")); + BigDecimal totalPartCost = BigDecimal.ZERO; // 总物料成本 + BigDecimal totalElseCost = BigDecimal.ZERO; // 其他额外成本 + if (calculatedItems.contains("工具")){ + totalPartCost = totalPartCost.add(detail.getAdjustToolCost()); + }else { + totalElseCost = totalElseCost.add(detail.getAdjustToolCost()); + } + if (calculatedItems.contains("测试")){ + totalPartCost = totalPartCost.add(detail.getAdjustTestCost()); + }else { + totalElseCost = totalElseCost.add(detail.getAdjustTestCost()); + } + if (calculatedItems.contains("其他")){ + totalPartCost = totalPartCost.add(detail.getAdjustElseCost()); + }else { + totalElseCost = totalElseCost.add(detail.getAdjustElseCost()); + } + if (calculatedItems.contains("包装")){ + totalPartCost = totalPartCost.add(detail.getPackCost()); + }else { + totalElseCost = totalElseCost.add(detail.getPackCost()); + } + if (calculatedItems.contains("运输")){ + totalPartCost = totalPartCost.add(detail.getShippingCost()); + }else { + totalElseCost = totalElseCost.add(detail.getShippingCost()); + } + + // 利润 + // 复制无法确认使用那种 利润方式直接采用VA + BigDecimal quoteProfitRate = Optional.ofNullable(detail.getQuoteProfitRate()).orElse(BigDecimal.ZERO); + // 公式包含Tool +测试+其他+包装+运输 + BigDecimal otherCost = detail.getToolCost().add(detail.getTestCost()).add(detail.getElseCost()).add(detail.getPackCost()).add(detail.getShippingCost()); + // 其他成本 + 材料成本 + 机器成本 + 人工成本 + BigDecimal ttlCost = otherCost.add(detail.getAdjustPartCost()).add(detail.getAdjustMachineCost()).add(detail.getLabourCost()); + // price被除数 + BigDecimal val = BigDecimal.ONE; + try { + // (1-VA/100) + val = BigDecimal.ONE.subtract(quoteProfitRate.divide(new BigDecimal("100"), 16, RoundingMode.HALF_UP)); + }catch (Exception e){ + throw new XJException("除数为0错误,VA为100;Price¥(ex VAT) = (物料成本+工具成本+运输成本+包装成本)/(1-VA/100)"); + } + //price = (物料成本+工具成本+运输成本+包装成本)/(1-value)+其他额外成本 + BigDecimal quoteTaxTotalPrice = detail.getAdjustPartCost().add(otherCost).divide(val,16, RoundingMode.HALF_UP).add(totalElseCost); + // contribution = 1-(物料成本+人工成本+工具成本+运输成本+包装成本)/(price-额外其他成本) + BigDecimal quoteProfitAmount = BigDecimal.ONE.subtract(detail.getAdjustPartCost().add(detail.getAdjustLabourCost()).add(otherCost).divide(quoteTaxTotalPrice.subtract(totalElseCost),16, RoundingMode.HALF_UP)).multiply(new BigDecimal("100")); + // margin = (price-额外其他成本-总成本)/(price-额外其他成本) + BigDecimal quoteTaxRate = quoteTaxTotalPrice.subtract(totalElseCost).subtract(ttlCost).divide(quoteTaxTotalPrice.subtract(totalElseCost),16, RoundingMode.HALF_UP); + quoteTaxRate = quoteTaxRate.multiply(new BigDecimal("100")); + + // 未税单价 + BigDecimal unitPrice = Optional.of(quoteTaxTotalPrice).orElse(BigDecimal.ZERO); + // 含税单价(未税单价+(未税单价*(税率+其他税率)/100)) + BigDecimal taxRate = Optional.ofNullable(detail.getTaxRate()).orElse(BigDecimal.ZERO); + BigDecimal exchangeRate1 = Optional.ofNullable(detail.getExchangeRate1()).orElse(BigDecimal.ZERO); + BigDecimal taxUnitPrice = unitPrice.add(unitPrice.multiply(taxRate.add(exchangeRate1.divide(new BigDecimal("100"), 16, RoundingMode.HALF_UP)))); + + // 外汇后的含税单价 + BigDecimal currencyTotalCost2 = BigDecimal.ZERO; + if (Objects.nonNull(detail.getExchangeRate2()) && detail.getExchangeRate2().compareTo(BigDecimal.ZERO) > 0) { + currencyTotalCost2 = taxUnitPrice.divide(detail.getExchangeRate2(),16, RoundingMode.HALF_UP); + } + // 赋值成本 + detail.setTotalCost(totalCost); + detail.setQuoteTaxTotalPrice(quoteTaxTotalPrice); + detail.setQuoteProfitAmount(quoteProfitAmount); + detail.setQuoteTaxRate(quoteTaxRate); + detail.setUnitPrice(unitPrice); + detail.setTaxUnitPrice(taxUnitPrice); + detail.setQuoteCurrencyTotalCost2(currencyTotalCost2); } @Override