Commit 42bbd60c9f0daa7818b825a1180c0d0e243f46bc

Authored by 谢茂盛
1 parent d5f54f24

fix: 支持两种利润率计算

sql/table.sql
... ... @@ -47,6 +47,7 @@ CREATE TABLE `order_profit_analysis` (
47 47 `packet_total_price` DOUBLE DEFAULT 0 COMMENT '包装费用合计¥',
48 48 `packet_currency` varchar(32) DEFAULT NULL COMMENT '包装费货币',
49 49 `exchange_rate` DOUBLE DEFAULT 0 COMMENT '汇率',
  50 + `profit_type` DOUBLE DEFAULT 0 COMMENT '公式类型',
50 51 `profit_rate` DOUBLE DEFAULT 0 COMMENT '利润率',
51 52 `order_status` INT NOT NULL COMMENT '订单状态',
52 53 `enable_flag` INT NOT NULL COMMENT '是否可用 10-可用 20-删除',
... ...
src/main/java/com/order/erp/common/utils/ProfitUtils.java
1 1 package com.order.erp.common.utils;
2 2  
  3 +import com.order.erp.common.constant.Constant;
  4 +import com.order.erp.common.exception.BusinessException;
3 5 import com.order.erp.domain.vo.order.ProfitCalculateVO;
4 6  
5 7 import java.math.BigDecimal;
... ... @@ -14,12 +16,46 @@ public class ProfitUtils {
14 16  
15 17 /**
16 18 * 计算利润率
17   - * 1 - (生产科总价/汇率 + 包装费用总价)/客单总价
18 19 *
19 20 * @param calculateVO
20 21 * @return
21 22 */
22 23 public static double calculateProfitRate(ProfitCalculateVO calculateVO) {
  24 + if (calculateVO.getProfitType() == Constant.ZERO) {
  25 + return calculateProfitRate1(calculateVO);
  26 + } else if (calculateVO.getProfitType() == Constant.ONE) {
  27 + return calculateProfitRate2(calculateVO);
  28 + }
  29 + throw new BusinessException("利润公式不存在!");
  30 + }
  31 +
  32 + /**
  33 + * 计算利润率 公式1
  34 + * 1 - (生产科总价/汇率 + 包装费用总价)/客单总价
  35 + *
  36 + * @param calculateVO
  37 + * @return
  38 + */
  39 + public static double calculateProfitRate1(ProfitCalculateVO calculateVO) {
  40 + BigDecimal productionDepartmentTotalPrice = new BigDecimal(calculateVO.getProductionDepartmentTotalPrice());
  41 +
  42 + BigDecimal exchangeRate = new BigDecimal(calculateVO.getExchangeRate());
  43 +
  44 + BigDecimal packetTotalPrice = new BigDecimal(calculateVO.getPacketTotalPrice());
  45 +
  46 + BigDecimal customerTotalPrice = new BigDecimal(calculateVO.getCustomerTotalPrice());
  47 +
  48 + return new BigDecimal(1).subtract((productionDepartmentTotalPrice.divide(exchangeRate, 4, BigDecimal.ROUND_HALF_UP).add(packetTotalPrice)).divide(customerTotalPrice, 4, BigDecimal.ROUND_HALF_UP)).doubleValue();
  49 + }
  50 +
  51 + /**
  52 + * 计算利润率 公式2
  53 + * 1 - (生产科总价/汇率/(客户总金额-包装费用总金额)
  54 + *
  55 + * @param calculateVO
  56 + * @return
  57 + */
  58 + public static double calculateProfitRate2(ProfitCalculateVO calculateVO) {
23 59 BigDecimal productionDepartmentTotalPrice = new BigDecimal(calculateVO.getProductionDepartmentTotalPrice());
24 60  
25 61 BigDecimal exchangeRate = new BigDecimal(calculateVO.getExchangeRate());
... ... @@ -28,6 +64,12 @@ public class ProfitUtils {
28 64  
29 65 BigDecimal customerTotalPrice = new BigDecimal(calculateVO.getCustomerTotalPrice());
30 66  
31   - return new BigDecimal(1).subtract((productionDepartmentTotalPrice.divide(exchangeRate,4,BigDecimal.ROUND_HALF_UP).add(packetTotalPrice)).divide(customerTotalPrice,4,BigDecimal.ROUND_HALF_UP)).doubleValue();
  67 + BigDecimal v = customerTotalPrice.subtract(packetTotalPrice);
  68 +
  69 + if (v.intValue() <= 0) {
  70 + throw new BusinessException("客户金额小于包装费用");
  71 + }
  72 +
  73 + return new BigDecimal(1).subtract((productionDepartmentTotalPrice.divide(exchangeRate, 4, BigDecimal.ROUND_HALF_UP).divide(v))).doubleValue();
32 74 }
33 75 }
... ...
src/main/java/com/order/erp/controller/OrderProfitController.java
1 1 package com.order.erp.controller;
2 2  
3 3 import com.order.erp.common.constant.ServerResult;
4   -import com.order.erp.domain.dto.order.OrderProfitAnalysisDO;
5 4 import com.order.erp.domain.vo.OrderProfitAnalysisVo;
  5 +import com.order.erp.domain.vo.order.OrderProfitAnalysisVO;
6 6 import com.order.erp.service.order.OrderProfitAnalysisService;
7 7 import org.springframework.validation.annotation.Validated;
8 8 import org.springframework.web.bind.annotation.PostMapping;
... ... @@ -11,9 +11,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
11 11 import org.springframework.web.bind.annotation.RestController;
12 12  
13 13 import javax.annotation.Resource;
14   -import javax.validation.Valid;
15   -import java.util.List;
16   -import java.util.Map;
17 14  
18 15 /**
19 16 * @author zhongnanhuang
... ... @@ -30,15 +27,7 @@ public class OrderProfitController {
30 27 OrderProfitAnalysisService orderProfitAnalysisService;
31 28  
32 29 @PostMapping("/analysis")
33   - public ServerResult analysis(@RequestBody @Validated OrderProfitAnalysisVo orderProfitAnalysisVo){
34   - List<Long> orderIds = orderProfitAnalysisVo.getOrderIds();
35   -
36   - OrderProfitAnalysisDO orderProfitAnalysisDO = orderProfitAnalysisService.analysisByOrderIds(orderIds);
37   -
38   - if (orderProfitAnalysisDO==null){
39   - return ServerResult.fail("找不到订单信息");
40   - }
41   -
42   - return ServerResult.success(orderProfitAnalysisDO);
  30 + public ServerResult<OrderProfitAnalysisVO> analysis(@RequestBody @Validated OrderProfitAnalysisVo orderProfitAnalysisVo) {
  31 + return orderProfitAnalysisService.analysisByOrderIds(orderProfitAnalysisVo);
43 32 }
44 33 }
... ...
src/main/java/com/order/erp/domain/DictionaryEnum.java
... ... @@ -13,7 +13,7 @@ import lombok.Getter;
13 13 @AllArgsConstructor
14 14 public enum DictionaryEnum {
15 15  
16   - EXCHANGE_RATE("exchange_rate", "汇率"),
  16 + EXCHANGE_RATE("exchangeRate", "汇率"),
17 17 ;
18 18 private String code;
19 19  
... ...
src/main/java/com/order/erp/domain/dto/order/OrderProfitAnalysisDO.java
... ... @@ -84,5 +84,10 @@ public class OrderProfitAnalysisDO extends BaseDO implements Serializable {
84 84 */
85 85 private Integer orderStatus;
86 86  
  87 + /**
  88 + * 默认 0 公式1,1 公式2
  89 + */
  90 + private int profitType;
  91 +
87 92  
88 93 }
... ...
src/main/java/com/order/erp/domain/vo/OrderProfitAnalysisVo.java
... ... @@ -5,6 +5,7 @@ import lombok.Data;
5 5 import lombok.NoArgsConstructor;
6 6 import lombok.ToString;
7 7  
  8 +import javax.validation.constraints.NotNull;
8 9 import javax.validation.constraints.Size;
9 10 import java.io.Serializable;
10 11 import java.util.List;
... ... @@ -21,6 +22,17 @@ import java.util.List;
21 22 @NoArgsConstructor
22 23 @ToString
23 24 public class OrderProfitAnalysisVo implements Serializable {
24   - @Size(min = 1,message = "订单不能为空")
  25 + @Size(min = 1, message = "订单不能为空")
25 26 private List<Long> orderIds;
  27 +
  28 + /**
  29 + * 默认 0 公式1,1 公式2
  30 + */
  31 + private int profitType;
  32 +
  33 + /**
  34 + * 汇率
  35 + */
  36 + @NotNull(message = "请选择当天汇率进行计算")
  37 + private Double exchangeRate;
26 38 }
... ...
src/main/java/com/order/erp/domain/vo/order/OrderProfitAnalysisFieldVO.java
... ... @@ -72,5 +72,10 @@ public class OrderProfitAnalysisFieldVO implements Serializable {
72 72 */
73 73 private String orderStatus;
74 74  
  75 + /**
  76 + * 默认 0 公式1,1 公式2
  77 + */
  78 + private int profitType;
  79 +
75 80  
76 81 }
... ...
src/main/java/com/order/erp/domain/vo/order/OrderProfitAnalysisVO.java
... ... @@ -81,5 +81,10 @@ public class OrderProfitAnalysisVO implements Serializable {
81 81 */
82 82 private Integer orderStatus;
83 83  
  84 + /**
  85 + * 默认 0 公式1,1 公式2
  86 + */
  87 + private int profitType;
  88 +
84 89  
85 90 }
... ...
src/main/java/com/order/erp/domain/vo/order/ProfitCalculateVO.java
... ... @@ -36,5 +36,10 @@ public class ProfitCalculateVO implements Serializable {
36 36 */
37 37 private Double exchangeRate;
38 38  
  39 + /**
  40 + * 默认 0 公式1,1 公式2
  41 + */
  42 + private int profitType;
  43 +
39 44  
40 45 }
... ...
src/main/java/com/order/erp/service/order/OrderProfitAnalysisService.java
... ... @@ -3,6 +3,7 @@ package com.order.erp.service.order;
3 3 import com.baomidou.mybatisplus.extension.service.IService;
4 4 import com.order.erp.common.constant.ServerResult;
5 5 import com.order.erp.domain.dto.order.OrderProfitAnalysisDO;
  6 +import com.order.erp.domain.vo.OrderProfitAnalysisVo;
6 7 import com.order.erp.domain.vo.order.OrderProfitAnalysisQueryVO;
7 8 import com.order.erp.domain.vo.order.OrderProfitAnalysisVO;
8 9  
... ... @@ -60,7 +61,7 @@ public interface OrderProfitAnalysisService extends IService&lt;OrderProfitAnalysis
60 61  
61 62 boolean deleteByOrderIds(List<Long> orderIds);
62 63  
63   - OrderProfitAnalysisDO analysisByOrderIds(List<Long> orderIds);
  64 + ServerResult<OrderProfitAnalysisVO> analysisByOrderIds(OrderProfitAnalysisVo orderProfitAnalysisVo);
64 65  
65 66 long countByOrderStatus(Integer status);
66 67  
... ...
src/main/java/com/order/erp/service/order/impl/OrderBaseInfoServiceImpl.java
... ... @@ -550,6 +550,7 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
550 550 && Objects.nonNull(profitAnalysisVO.getPacketTotalPrice())
551 551 && Objects.nonNull(profitAnalysisVO.getProductionDepartmentTotalPrice())) {
552 552 profitRate = ProfitUtils.calculateProfitRate(ProfitCalculateVO.builder()
  553 + .profitType(profitAnalysisVO.getProfitType())
553 554 .customerTotalPrice(profitAnalysisVO.getCustomerTotalPrice())
554 555 .exchangeRate(profitAnalysisVO.getExchangeRate())
555 556 .packetTotalPrice(profitAnalysisVO.getPacketTotalPrice())
... ... @@ -557,6 +558,7 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
557 558 }
558 559 return OrderProfitAnalysisFieldVO.builder()
559 560 .orderId(profitAnalysisVO.getOrderId())
  561 + .profitType(profitAnalysisVO.getProfitType())
560 562 .customerPrice(Objects.nonNull(profitAnalysisVO.getCustomerPrice()) ? profitAnalysisVO.getCustomerPrice().toString() : null)
561 563 .customerTotalPrice(Objects.nonNull(profitAnalysisVO.getCustomerTotalPrice()) ? profitAnalysisVO.getCustomerTotalPrice().toString() : null)
562 564 .customerCurrency(profitAnalysisVO.getCustomerCurrency())
... ...
src/main/java/com/order/erp/service/order/impl/OrderFieldLockApplyServiceImpl.java
... ... @@ -448,6 +448,7 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
448 448 profitAnalysisDO.setProductionDepartmentPrice(Objects.nonNull(profitAnalysisFieldVO.getProductionDepartmentPrice()) ? Double.valueOf(profitAnalysisFieldVO.getProductionDepartmentPrice()) : null);
449 449 profitAnalysisDO.setProductionDepartmentTotalPrice(Objects.nonNull(profitAnalysisFieldVO.getProductionDepartmentTotalPrice()) ? Double.valueOf(profitAnalysisFieldVO.getProductionDepartmentTotalPrice()) : null);
450 450 profitAnalysisDO.setProfitRate(Objects.nonNull(profitAnalysisFieldVO.getProfitRate()) ? Double.valueOf(profitAnalysisFieldVO.getProfitRate()) : null);
  451 + profitAnalysisDO.setProfitType(profitAnalysisFieldVO.getProfitType());
451 452 profitAnalysisService.updateById(profitAnalysisDO);
452 453 }
453 454 orderBaseInfoDO.setOrderStatus(OrderStatusEnum.PROFIT_AUDIT_PASS.getStatus());
... ... @@ -481,6 +482,7 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
481 482 private OrderProfitAnalysisDO profitField2profitDo(OrderProfitAnalysisFieldVO profitAnalysisFieldVO) {
482 483 return OrderProfitAnalysisDO.builder()
483 484 .orderId(profitAnalysisFieldVO.getOrderId())
  485 + .profitType(profitAnalysisFieldVO.getProfitType())
484 486 .customerPrice(Objects.nonNull(profitAnalysisFieldVO.getCustomerPrice()) ? Double.valueOf(profitAnalysisFieldVO.getCustomerPrice()) : null)
485 487 .customerTotalPrice(Objects.nonNull(profitAnalysisFieldVO.getCustomerTotalPrice()) ? Double.valueOf(profitAnalysisFieldVO.getCustomerTotalPrice()) : null)
486 488 .exchangeRate(Objects.nonNull(profitAnalysisFieldVO.getExchangeRate()) ? Double.valueOf(profitAnalysisFieldVO.getExchangeRate()) : null)
... ...
src/main/java/com/order/erp/service/order/impl/OrderProfitAnalysisServiceImpl.java
... ... @@ -2,15 +2,17 @@ package com.order.erp.service.order.impl;
2 2  
3 3 import cn.hutool.core.bean.BeanUtil;
4 4 import cn.hutool.core.collection.CollUtil;
5   -import com.baomidou.mybatisplus.core.conditions.Wrapper;
6 5 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
7   -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
8 6 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  7 +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
9 8 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
10 9 import com.order.erp.common.constant.Constant;
11 10 import com.order.erp.common.constant.ServerResult;
  11 +import com.order.erp.common.exception.BusinessException;
12 12 import com.order.erp.common.utils.ProfitUtils;
  13 +import com.order.erp.domain.dto.BaseDO;
13 14 import com.order.erp.domain.dto.order.OrderProfitAnalysisDO;
  15 +import com.order.erp.domain.vo.OrderProfitAnalysisVo;
14 16 import com.order.erp.domain.vo.order.OrderProfitAnalysisQueryVO;
15 17 import com.order.erp.domain.vo.order.OrderProfitAnalysisVO;
16 18 import com.order.erp.domain.vo.order.ProfitCalculateVO;
... ... @@ -21,7 +23,6 @@ import org.springframework.beans.BeanUtils;
21 23 import org.springframework.stereotype.Service;
22 24  
23 25 import java.math.BigDecimal;
24   -import java.util.Arrays;
25 26 import java.util.List;
26 27 import java.util.Objects;
27 28  
... ... @@ -35,7 +36,6 @@ import java.util.Objects;
35 36 @Service
36 37 public class OrderProfitAnalysisServiceImpl extends ServiceImpl<OrderProfitAnalysisMapper, OrderProfitAnalysisDO> implements OrderProfitAnalysisService {
37 38  
38   -
39 39 /**
40 40 * 通过ID查询单条数据
41 41 * <p>
... ... @@ -131,6 +131,7 @@ public class OrderProfitAnalysisServiceImpl extends ServiceImpl&lt;OrderProfitAnaly
131 131  
132 132 /**
133 133 * 通过订单id逻辑删除
  134 + *
134 135 * @param orderId
135 136 * @return
136 137 */
... ... @@ -151,47 +152,45 @@ public class OrderProfitAnalysisServiceImpl extends ServiceImpl&lt;OrderProfitAnaly
151 152 }
152 153  
153 154 @Override
154   - public OrderProfitAnalysisDO analysisByOrderIds(List<Long> orderIds) {
  155 + public ServerResult<OrderProfitAnalysisVO> analysisByOrderIds(OrderProfitAnalysisVo profitAnalysisVo) {
155 156 //查询订单id的利润分析数据
156   - QueryWrapper queryWrapper = new QueryWrapper<OrderProfitAnalysisVO>().in("order_id", orderIds);
157   - List<OrderProfitAnalysisDO> orderProfits = list(queryWrapper);
158   -
  157 + List<OrderProfitAnalysisDO> orderProfits = list(new LambdaQueryWrapper<OrderProfitAnalysisDO>()
  158 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  159 + .in(OrderProfitAnalysisDO::getOrderId, profitAnalysisVo.getOrderIds()));
159 160  
160   - if (orderProfits==null||orderProfits.isEmpty()){
161   - return null;
  161 + if (CollectionUtils.isEmpty(orderProfits)) {
  162 + throw new BusinessException("选中的订单信息不存在");
162 163 }
163 164  
164   - BigDecimal packetTotalPrice = new BigDecimal("0");
165   - BigDecimal customerTotalPrice = new BigDecimal("0");
166   - BigDecimal productionDepartmentTotalPrice = new BigDecimal("0");
167   - double profits = 0;
168   - //分别计算每个orderProfit的利润率,通过ProfitUtils的calculateProfitRate方法计算
  165 + BigDecimal packetTotalPrice = new BigDecimal(Constant.ZERO_STRING);
  166 + BigDecimal customerTotalPrice = new BigDecimal(Constant.ZERO_STRING);
  167 + BigDecimal productionDepartmentTotalPrice = new BigDecimal(Constant.ZERO_STRING);
169 168 for (OrderProfitAnalysisDO orderProfit : orderProfits) {
170 169 ProfitCalculateVO profitCalculateVO = new ProfitCalculateVO();
171   - BeanUtils.copyProperties(orderProfit,profitCalculateVO);
172   - double profit = ProfitUtils.calculateProfitRate(profitCalculateVO);
173   -
  170 + BeanUtils.copyProperties(orderProfit, profitCalculateVO);
174 171 packetTotalPrice = packetTotalPrice.add(new BigDecimal(orderProfit.getPacketTotalPrice()));
175 172 customerTotalPrice = customerTotalPrice.add(new BigDecimal(orderProfit.getCustomerTotalPrice()));
176 173 productionDepartmentTotalPrice = productionDepartmentTotalPrice.add(new BigDecimal(orderProfit.getProductionDepartmentTotalPrice()));
177   - profits+=profit;
178 174 }
179 175  
180   - profits = (profits / orderProfits.size());
181   -
182   - OrderProfitAnalysisDO orderProfitAnalysisDO = new OrderProfitAnalysisDO();
183   - orderProfitAnalysisDO.setPacketTotalPrice(packetTotalPrice.doubleValue());
184   - orderProfitAnalysisDO.setCustomerTotalPrice(customerTotalPrice.doubleValue());
185   - orderProfitAnalysisDO.setProductionDepartmentTotalPrice(productionDepartmentTotalPrice.doubleValue());
186   - orderProfitAnalysisDO.setProfitRate(profits);
187   -
188   - return orderProfitAnalysisDO;
  176 + OrderProfitAnalysisVO profitAnalysisVO = new OrderProfitAnalysisVO();
  177 + profitAnalysisVO.setPacketTotalPrice(packetTotalPrice.doubleValue());
  178 + profitAnalysisVO.setCustomerTotalPrice(customerTotalPrice.doubleValue());
  179 + profitAnalysisVO.setProductionDepartmentTotalPrice(productionDepartmentTotalPrice.doubleValue());
  180 + profitAnalysisVO.setProfitRate(ProfitUtils.calculateProfitRate(ProfitCalculateVO.builder()
  181 + .profitType(profitAnalysisVo.getProfitType())
  182 + .exchangeRate(profitAnalysisVo.getExchangeRate())
  183 + .productionDepartmentTotalPrice(productionDepartmentTotalPrice.doubleValue())
  184 + .packetTotalPrice(packetTotalPrice.doubleValue())
  185 + .customerTotalPrice(customerTotalPrice.doubleValue()).build()));
  186 +
  187 + return ServerResult.success(profitAnalysisVO);
189 188 }
190 189  
191 190 @Override
192 191 public long countByOrderStatus(Integer status) {
193   - return this.count(new LambdaQueryWrapper<OrderProfitAnalysisDO>().eq(OrderProfitAnalysisDO::getOrderStatus,status)
194   - .eq(OrderProfitAnalysisDO::getEnableFlag,Constant.ENABLE_TEN));
  192 + return this.count(new LambdaQueryWrapper<OrderProfitAnalysisDO>().eq(OrderProfitAnalysisDO::getOrderStatus, status)
  193 + .eq(OrderProfitAnalysisDO::getEnableFlag, Constant.ENABLE_TEN));
195 194 }
196 195  
197 196 @Override
... ...