Browse Source

app平均客单价计算公式统一更改(平均客单价 = 经营收入 / 下单客户数(不包含退款))

liyuan 2 months ago
parent
commit
1c819b2e8b

+ 4 - 0
blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/dto/SaleDetailDto.java

@@ -19,6 +19,10 @@ import java.math.BigDecimal;
 @ContentRowHeight(18)
 public class SaleDetailDto {
 
+	/**
+	 * 客户Id
+	 */
+	private Long customerId;
 
 	/**
 	 * 客户名称

+ 1 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/order/mapper/OrderItemsMapper.xml

@@ -325,6 +325,7 @@
     </select>
     <select id="saleDetailList" resultType="org.springblade.salesPart.dto.SaleDetailDto">
         SELECT
+        po.customer_id AS customerId,
         po.customer_name AS customerName,
         bu.real_name AS salerName,
         poi.pid AS pid,

+ 4 - 2
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/order/service/impl/OrderServiceImpl.java

@@ -4929,11 +4929,13 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, PjOrder> implemen
 			.setScale(0, RoundingMode.HALF_UP).abs();
 
 
-		long xsCount = saleDetailDtoList.stream().filter(e -> !OrderStatusEnum.COMPLETED.value.equals(e.getStatus()) && e.getBsType().equals("销售")).count();
+		// long xsCount = saleDetailDtoList.stream().filter(e -> !OrderStatusEnum.COMPLETED.value.equals(e.getStatus()) && !OrderStatusEnum.CANCELLED.value.equals(e.getStatus()) && e.getBsType().equals("销售")).count();
+		long customerCount = saleDetailDtoList.stream().filter(e -> !OrderStatusEnum.COMPLETED.value.equals(e.getStatus()) && !OrderStatusEnum.CANCELLED.value.equals(e.getStatus()) && e.getBsType().equals("销售")).map(SaleDetailDto::getCustomerId).distinct().count();
 		appStatisticsVo.setIncome(subTotalMoneyActual.abs().subtract(subTotalMoneyReturns).subtract(subTotalMoneyCancel));
 		appStatisticsVo.setCost(costprieActual.abs().subtract(costprieReturns).subtract(costprieCancel));
 		appStatisticsVo.setProfit(profitActual.abs().subtract(profitReturns).subtract(profitCancel));
-		appStatisticsVo.setAverageAmount(appStatisticsVo.getIncome().divide(new BigDecimal(xsCount), MathContext.DECIMAL32).setScale(2, RoundingMode.HALF_UP));
+		// appStatisticsVo.setAverageAmount(appStatisticsVo.getIncome().divide(new BigDecimal(xsCount), MathContext.DECIMAL32).setScale(2, RoundingMode.HALF_UP));
+		appStatisticsVo.setAverageAmount( appStatisticsVo.getIncome().divide(new BigDecimal(customerCount), MathContext.DECIMAL32).setScale(2, RoundingMode.HALF_UP));
 		appStatisticsVo.setExpenditure(expenditure == null ? BigDecimal.ZERO : expenditure.setScale(0, RoundingMode.DOWN));
 		return R.data(appStatisticsVo);
 	}

+ 129 - 4
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/statistics/service/impl/StatisticsServiceImpl.java

@@ -41,12 +41,14 @@ import org.springblade.salesPart.funding.entity.PjpfBalanceReset;
 import org.springblade.salesPart.funding.entity.PjpfFunding;
 import org.springblade.salesPart.funding.service.IPjpfBalanceResetService;
 import org.springblade.salesPart.funding.service.IPjpfFundingService;
+import org.springblade.salesPart.order.mapper.OrderMapper;
 import org.springblade.salesPart.order.service.IOrderItemsService;
 import org.springblade.salesPart.order.service.IOrderService;
 import org.springblade.salesPart.ship.service.IShipItemsService;
 import org.springblade.salesPart.ship.service.IShipService;
 import org.springblade.salesPart.statistics.service.IStatisticsService;
 import org.springblade.salesPart.tireMallStatistics.service.ITireMallStatisticsService;
+import org.springblade.salesPart.vo.AppStatisticsVo;
 import org.springblade.salesPart.vo.StatisticsVo;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
@@ -84,7 +86,7 @@ public class StatisticsServiceImpl implements IStatisticsService {
 
 	private final IPjpfBalanceResetService pjpfBalanceResetService;
 
-	private final ITireMallStatisticsService tireMallStatisticsService;
+	private final OrderMapper orderMapper;
 
 	@Override
 	public R<Map<String, Object>> amountStatistics() {
@@ -629,8 +631,131 @@ public class StatisticsServiceImpl implements IStatisticsService {
 
 	@Override
 	public R salesVolumesStatistics(String statusDate, String endDate) {
-		Map<String, Object> map = new HashMap<>();
-		List<PjOrder> pjOrderList = orderService.list(new LambdaQueryWrapper<PjOrder>()
+		AppStatisticsVo appStatisticsVo = new AppStatisticsVo();
+		BladeUser user = AuthUtil.getUser();
+		String userRoles = AuthUtil.getUserRole();
+		appStatisticsVo.valueIsZero();
+		SaleDetail saleDetailDto = new SaleDetail();
+		saleDetailDto.setTenantId(user.getTenantId());
+		saleDetailDto.setSalesCompanyId(user.getDeptId());
+		saleDetailDto.setBusinesDateStart(statusDate);
+		saleDetailDto.setBusinesDateEnd(endDate);
+		saleDetailDto.setIsContain("0");
+		saleDetailDto.setBsType("XS,TKXS");
+		if (!userRoles.contains("admin") && !userRoles.contains("老板") && userRoles.contains("业务员")) {
+			saleDetailDto.setSalerName(String.valueOf(user.getUserId()));
+		}
+		StatisticsVo statisticsVo = new StatisticsVo();
+		statisticsVo.valueIsZero();
+		List<SaleDetailDto> saleDetailDtoList = orderItemsService.saleDetailList(saleDetailDto);
+		if (org.springframework.util.CollectionUtils.isEmpty(saleDetailDtoList)) {
+			return R.data(appStatisticsVo);
+		}
+		List<PjOrder> pjOrderList = orderMapper.selectList(new LambdaQueryWrapper<PjOrder>()
+			.eq(PjOrder::getTenantId, user.getTenantId())
+			.eq(PjOrder::getIsDeleted, 0)
+			.in(PjOrder::getOrdNo, saleDetailDtoList.stream().map(SaleDetailDto::getOrdNo).distinct().collect(Collectors.toList()))
+		);
+		if (org.springframework.util.CollectionUtils.isEmpty(pjOrderList)) {
+			return R.data(appStatisticsVo);
+		}
+		List<PjOrderItems> pjOrderItemsList = orderItemsService.list(new LambdaQueryWrapper<PjOrderItems>()
+			.eq(PjOrderItems::getIsDeleted, 0)
+			.eq(PjOrderItems::getTenantId, AuthUtil.getTenantId())
+			.in(PjOrderItems::getPid, pjOrderList.stream().map(PjOrder::getId).collect(Collectors.toList())));
+		if (org.springframework.util.CollectionUtils.isEmpty(pjOrderItemsList)) {
+			return R.data(appStatisticsVo);
+		}
+		for (PjOrder item : pjOrderList) {
+			List<SaleDetailDto> saleDetailDtoList1 = saleDetailDtoList.stream().filter(e -> e.getOrdNo().equals(item.getOrdNo())).collect(Collectors.toList());
+			if (org.springframework.util.CollectionUtils.isEmpty(saleDetailDtoList1)) {
+				continue;
+			}
+			BigDecimal returnsAmount = pjOrderItemsList.stream().filter(e -> e.getPid().equals(item.getId())
+					&& !"线下退款".equals(e.getRefundType())).map(PjOrderItems::getReturnsAmount)
+				.reduce(BigDecimal.ZERO, BigDecimal::add);
+			BigDecimal amount = item.getPaymentAmountTl().subtract(returnsAmount);
+			amount = amount.abs();
+			for (SaleDetailDto items : saleDetailDtoList1) {
+				PjOrderItems orderItems = pjOrderItemsList.stream().filter(e -> e.getId().equals(items.getItemId())).findFirst().orElse(null);
+				if (orderItems != null) {
+					items.setItemRemarks(orderItems.getRemarks());
+					items.setGoodsNum(orderItems.getGoodsNum());
+					items.setPrice(orderItems.getPrice());
+					items.setSubTotalMoney(orderItems.getGoodsNum().multiply(orderItems.getPrice()));
+					items.setSubTotalMoney(items.getSubTotalMoney().add(item.getFreight()));
+					items.setProfit(items.getSubTotalMoney().subtract(items.getCostprie()));
+					items.setReturnsNumber(orderItems.getReturnsNumber());
+					items.setReturnsAmount(orderItems.getReturnsAmount());
+					items.setOutGoodsTotalShipNum(orderItems.getOutGoodsTotalShipNum());
+					items.setOutGoodsTotalShipAmount(orderItems.getOutGoodsTotalShipAmount());
+					items.setPrimaryGoodsTotalNum(orderItems.getPrimaryGoodsTotalNum());
+					items.setPrimaryGoodsTotalMoney(orderItems.getPrimaryGoodsTotalAmount());
+					items.setCostpriePrice(orderItems.getCostpriePrice());
+				}
+				if (OrderStatusEnum.CANCELLED.value.equals(items.getStatus())) {
+					// 已取消的
+					items.setBalanceAmount(FinalMap.ZERO_POINT_ZERO);
+					items.setSurplusNum(items.getGoodsNum().subtract(items.getOutGoodsTotalShipNum()));
+					items.setSurplusAmount(items.getSubTotalMoney().subtract(items.getOutGoodsTotalShipAmount()));
+					continue;
+				}
+				if (BsTypeEnum.REFUND_SALE.info.equals(item.getBsType()) || BsTypeEnum.REFUND_PROCUREMENT.info.equals(item.getBsType())) {
+					if (amount.compareTo(items.getSubTotalMoney().abs()) >= 0) {
+						items.setBalanceAmount(FinalMap.ZERO_POINT_ZERO);
+						amount = amount.subtract(items.getSubTotalMoney().abs());
+					} else {
+						items.setBalanceAmount(FinalMap.ZERO_POINT_ZERO.subtract(items.getSubTotalMoney().abs().subtract(amount)));
+						amount = FinalMap.ZERO_POINT_ZERO;
+					}
+					items.setGoodsNum(FinalMap.ZERO_POINT_ZERO.subtract(items.getReturnsNumber()));
+					items.setSubTotalMoney(FinalMap.ZERO_POINT_ZERO.subtract(items.getReturnsAmount()).subtract(item.getFreight()));
+					items.setFreight(FinalMap.ZERO_POINT_ZERO.subtract(items.getFreight()));
+					BigDecimal costPrice = items.getReturnsNumber().multiply(items.getCostpriePrice());
+					BigDecimal profit = items.getSubTotalMoney().abs().subtract(costPrice);
+					items.setProfit(FinalMap.ZERO_POINT_ZERO.subtract(profit));
+					items.setCostprie(FinalMap.ZERO_POINT_ZERO.subtract(costPrice));
+					items.setSurplusNum(items.getGoodsNum().subtract(items.getOutGoodsTotalShipNum()));
+					items.setSurplusAmount(items.getSubTotalMoney().subtract(items.getOutGoodsTotalShipAmount()));
+					continue;
+				}
+				if (amount.compareTo(items.getSubTotalMoney()) >= 0) {
+					items.setBalanceAmount(FinalMap.ZERO_POINT_ZERO);
+					amount = amount.subtract(items.getSubTotalMoney());
+				} else {
+					items.setBalanceAmount(items.getSubTotalMoney().subtract(amount));
+					amount = FinalMap.ZERO_POINT_ZERO;
+				}
+				items.setSurplusNum(items.getGoodsNum().subtract(items.getOutGoodsTotalShipNum()));
+				items.setSurplusAmount(items.getSubTotalMoney().subtract(items.getOutGoodsTotalShipAmount()));
+			}
+		}
+
+		// 实际数量
+		BigDecimal goodsNumActual = saleDetailDtoList.stream().filter(e -> !OrderStatusEnum.CANCELLED.value.equals(e.getStatus()) && !OrderStatusEnum.COMPLETED.value.equals(e.getStatus()))
+			.map(SaleDetailDto::getGoodsNum).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add)
+			.setScale(0, RoundingMode.HALF_UP);
+		// 实际金额
+		BigDecimal subTotalMoneyActual = saleDetailDtoList.stream().filter(e -> !OrderStatusEnum.CANCELLED.value.equals(e.getStatus()) && !OrderStatusEnum.COMPLETED.value.equals(e.getStatus()))
+			.map(SaleDetailDto::getSubTotalMoney).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add)
+			.setScale(0, RoundingMode.HALF_UP);
+		// 退货金额
+		BigDecimal subTotalMoneyReturns = saleDetailDtoList.stream().filter(e -> OrderStatusEnum.COMPLETED.value.equals(e.getStatus()))
+			.map(SaleDetailDto::getSubTotalMoney).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add)
+			.setScale(0, RoundingMode.HALF_UP).abs();
+		// 已取消的金额 --subTotalMoneyCancel
+		BigDecimal subTotalMoneyCancel = saleDetailDtoList.stream().filter(e -> OrderStatusEnum.CANCELLED.value.equals(e.getStatus()))
+			.map(SaleDetailDto::getSubTotalMoney).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add)
+			.setScale(0, RoundingMode.HALF_UP).abs();
+		long customerCount = saleDetailDtoList.stream().filter(e -> !OrderStatusEnum.COMPLETED.value.equals(e.getStatus()) && !OrderStatusEnum.CANCELLED.value.equals(e.getStatus()) && e.getBsType().equals("销售")).map(SaleDetailDto::getCustomerId).filter(Objects::nonNull).distinct().count();
+		BigDecimal realAmount = subTotalMoneyActual.subtract(subTotalMoneyReturns).subtract(subTotalMoneyCancel);
+		Map<String, Object> map = new HashMap<>(3);
+		map.put("income", goodsNumActual);
+		map.put("averageAmount", realAmount.divide(new BigDecimal(customerCount), 2, RoundingMode.HALF_UP));
+		map.put("corpsNumber", customerCount);
+
+
+/*		List<PjOrder> pjOrderList = orderService.list(new LambdaQueryWrapper<PjOrder>()
 			.eq(PjOrder::getTenantId, AuthUtil.getTenantId())
 			.eq(PjOrder::getSalesCompanyId, AuthUtil.getDeptId())
 			.eq(PjOrder::getIsDeleted, 0)
@@ -680,7 +805,7 @@ public class StatisticsServiceImpl implements IStatisticsService {
 		income = income.subtract(returnsIncome);
 		map.put("income", income);
 		map.put("averageAmount", averageAmount);
-		map.put("corpsNumber", corpsNumber);
+		map.put("corpsNumber", corpsNumber);*/
 		return R.data(map);
 	}