Commit 42bbd60c9f0daa7818b825a1180c0d0e243f46bc
1 parent
d5f54f24
fix: 支持两种利润率计算
Showing
13 changed files
with
117 additions
and
49 deletions
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
src/main/java/com/order/erp/domain/dto/order/OrderProfitAnalysisDO.java
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
src/main/java/com/order/erp/domain/vo/order/OrderProfitAnalysisVO.java
src/main/java/com/order/erp/domain/vo/order/ProfitCalculateVO.java
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<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<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<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<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<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<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<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 | ... | ... |