fix: exclude cancelled orders from performance stats
Some checks failed
Build and Push Backend / docker (push) Failing after 4s
Some checks failed
Build and Push Backend / docker (push) Failing after 4s
This commit is contained in:
@@ -241,7 +241,6 @@ public class PlayOrderInfoServiceImpl extends ServiceImpl<PlayOrderInfoMapper, P
|
||||
public List<PlayOrderInfoEntity> listByEndTime(String clerkId, LocalDateTime endTime) {
|
||||
MPJLambdaWrapper<PlayOrderInfoEntity> lambdaQueryWrapper = new MPJLambdaWrapper<>();
|
||||
lambdaQueryWrapper.eq(PlayOrderInfoEntity::getAcceptBy, clerkId);
|
||||
lambdaQueryWrapper.eq(PlayOrderInfoEntity::getOrderStatus, OrderStatus.COMPLETED.getCode());
|
||||
lambdaQueryWrapper.lt(PlayOrderInfoEntity::getOrderEndTime, endTime);
|
||||
lambdaQueryWrapper.eq(PlayOrderInfoEntity::getOrderSettlementState, "0");
|
||||
return this.baseMapper.selectList(lambdaQueryWrapper);
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.starry.admin.modules.clerk.module.entity.PlayClerkLevelInfoEntity;
|
||||
import com.starry.admin.modules.clerk.module.entity.PlayClerkUserInfoEntity;
|
||||
import com.starry.admin.modules.clerk.service.IPlayClerkLevelInfoService;
|
||||
import com.starry.admin.modules.clerk.service.IPlayClerkUserInfoService;
|
||||
import com.starry.admin.modules.order.module.constant.OrderConstant;
|
||||
import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity;
|
||||
import com.starry.admin.modules.order.service.IPlayOrderInfoService;
|
||||
import com.starry.admin.modules.personnel.module.entity.PlayPersonnelGroupInfoEntity;
|
||||
@@ -209,6 +210,7 @@ public class PlayClerkPerformanceController {
|
||||
int orderContinueNumber = 0;
|
||||
int orderRefundNumber = 0;
|
||||
int ordersExpiredNumber = 0;
|
||||
int completedOrders = 0;
|
||||
BigDecimal orderMoney = BigDecimal.ZERO;
|
||||
BigDecimal finalAmount = BigDecimal.ZERO;
|
||||
BigDecimal orderFirstAmount = BigDecimal.ZERO;
|
||||
@@ -217,6 +219,10 @@ public class PlayClerkPerformanceController {
|
||||
BigDecimal orderRefundAmount = BigDecimal.ZERO;
|
||||
BigDecimal estimatedRevenue = BigDecimal.ZERO;
|
||||
for (PlayOrderInfoEntity orderInfoEntity : orderInfoEntities) {
|
||||
if (!isCompletedOrder(orderInfoEntity)) {
|
||||
continue;
|
||||
}
|
||||
completedOrders++;
|
||||
customIds.add(orderInfoEntity.getPurchaserBy());
|
||||
finalAmount = finalAmount.add(orderInfoEntity.getFinalAmount());
|
||||
orderMoney = orderMoney.add(orderInfoEntity.getOrderMoney());
|
||||
@@ -238,7 +244,7 @@ public class PlayClerkPerformanceController {
|
||||
}
|
||||
}
|
||||
PlayClerkPerformanceInfoReturnVo returnVo = new PlayClerkPerformanceInfoReturnVo();
|
||||
returnVo.setOrderNumber(orderInfoEntities.size());
|
||||
returnVo.setOrderNumber(completedOrders);
|
||||
returnVo.setOrderContinueNumber(orderContinueNumber);
|
||||
returnVo.setOrderRefundNumber(orderRefundNumber);
|
||||
returnVo.setOrdersExpiredNumber(ordersExpiredNumber);
|
||||
@@ -281,6 +287,7 @@ public class PlayClerkPerformanceController {
|
||||
int orderContinueNumber = 0;
|
||||
int orderRefundNumber = 0;
|
||||
int ordersExpiredNumber = 0;
|
||||
int completedOrders = 0;
|
||||
BigDecimal orderMoney = BigDecimal.ZERO;
|
||||
BigDecimal finalAmount = BigDecimal.ZERO;
|
||||
BigDecimal orderFirstAmount = BigDecimal.ZERO;
|
||||
@@ -289,6 +296,10 @@ public class PlayClerkPerformanceController {
|
||||
BigDecimal orderRefundAmount = BigDecimal.ZERO;
|
||||
BigDecimal estimatedRevenue = BigDecimal.ZERO;
|
||||
for (PlayOrderInfoEntity orderInfoEntity : itemOrderInfo) {
|
||||
if (!isCompletedOrder(orderInfoEntity)) {
|
||||
continue;
|
||||
}
|
||||
completedOrders++;
|
||||
customIds.add(orderInfoEntity.getPurchaserBy());
|
||||
finalAmount = finalAmount.add(orderInfoEntity.getFinalAmount());
|
||||
orderMoney = orderMoney.add(orderInfoEntity.getOrderMoney());
|
||||
@@ -311,7 +322,7 @@ public class PlayClerkPerformanceController {
|
||||
}
|
||||
PlayClerkPerformanceInfoReturnVo returnVo = new PlayClerkPerformanceInfoReturnVo();
|
||||
returnVo.setPerformanceDate(performanceDate);
|
||||
returnVo.setOrderNumber(itemOrderInfo.size());
|
||||
returnVo.setOrderNumber(completedOrders);
|
||||
returnVo.setOrderContinueNumber(orderContinueNumber);
|
||||
returnVo.setOrderRefundNumber(orderRefundNumber);
|
||||
returnVo.setOrdersExpiredNumber(ordersExpiredNumber);
|
||||
@@ -326,4 +337,9 @@ public class PlayClerkPerformanceController {
|
||||
return returnVo;
|
||||
}
|
||||
|
||||
private boolean isCompletedOrder(PlayOrderInfoEntity orderInfoEntity) {
|
||||
return orderInfoEntity != null
|
||||
&& OrderConstant.OrderStatus.COMPLETED.getCode().equals(orderInfoEntity.getOrderStatus());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
int orderContinueNumber = 0;
|
||||
int orderRefundNumber = 0;
|
||||
int ordersExpiredNumber = 0;
|
||||
int completedOrderCount = 0;
|
||||
BigDecimal finalAmount = BigDecimal.ZERO;
|
||||
BigDecimal orderFirstAmount = BigDecimal.ZERO;
|
||||
BigDecimal orderTotalAmount = BigDecimal.ZERO;
|
||||
@@ -84,6 +85,10 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
BigDecimal orderRefundAmount = BigDecimal.ZERO;
|
||||
|
||||
for (PlayOrderInfoEntity orderInfoEntity : orderInfoEntities) {
|
||||
if (!isCompletedOrder(orderInfoEntity)) {
|
||||
continue;
|
||||
}
|
||||
completedOrderCount++;
|
||||
customIds.add(orderInfoEntity.getPurchaserBy());
|
||||
finalAmount = finalAmount.add(defaultZero(orderInfoEntity.getFinalAmount()));
|
||||
if (OrderConstant.YesNoFlag.YES.getCode().equals(orderInfoEntity.getFirstOrder())) {
|
||||
@@ -121,7 +126,7 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
returnVo.setGroupName(infoEntity.getGroupName());
|
||||
}
|
||||
}
|
||||
returnVo.setOrderNumber(orderInfoEntities.size());
|
||||
returnVo.setOrderNumber(completedOrderCount);
|
||||
returnVo.setOrderContinueNumber(orderContinueNumber);
|
||||
returnVo.setOrderRefundNumber(orderRefundNumber);
|
||||
returnVo.setOrdersExpiredNumber(ordersExpiredNumber);
|
||||
@@ -223,7 +228,10 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
|
||||
private List<ClerkPerformanceTrendPointVo> buildTrend(List<PlayOrderInfoEntity> orders, DateRange range,
|
||||
int trendDays) {
|
||||
if (CollectionUtil.isEmpty(orders)) {
|
||||
List<PlayOrderInfoEntity> completedOrders = orders.stream()
|
||||
.filter(this::isCompletedOrder)
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtil.isEmpty(completedOrders)) {
|
||||
return buildEmptyTrend(range, trendDays);
|
||||
}
|
||||
LocalDate end = range.endDate;
|
||||
@@ -231,7 +239,7 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
if (start.isBefore(range.startDate)) {
|
||||
start = range.startDate;
|
||||
}
|
||||
Map<LocalDate, List<PlayOrderInfoEntity>> grouped = orders.stream()
|
||||
Map<LocalDate, List<PlayOrderInfoEntity>> grouped = completedOrders.stream()
|
||||
.filter(order -> order.getPurchaserTime() != null)
|
||||
.collect(Collectors.groupingBy(order -> order.getPurchaserTime().toLocalDate()));
|
||||
List<ClerkPerformanceTrendPointVo> points = new ArrayList<>();
|
||||
@@ -421,6 +429,7 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
List<String> orderIds = orders.stream()
|
||||
.filter(this::isCompletedOrder)
|
||||
.map(PlayOrderInfoEntity::getId)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.collect(Collectors.toList());
|
||||
@@ -453,7 +462,12 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
int refundCount = 0;
|
||||
int expiredCount = 0;
|
||||
Map<String, Integer> userOrderMap = new HashMap<>();
|
||||
int orderCount = 0;
|
||||
for (PlayOrderInfoEntity order : orders) {
|
||||
if (!isCompletedOrder(order)) {
|
||||
continue;
|
||||
}
|
||||
orderCount++;
|
||||
BigDecimal finalAmount = defaultZero(order.getFinalAmount());
|
||||
gmv = gmv.add(finalAmount);
|
||||
userOrderMap.merge(order.getPurchaserBy(), 1, Integer::sum);
|
||||
@@ -475,7 +489,6 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
expiredCount++;
|
||||
}
|
||||
}
|
||||
int orderCount = orders.size();
|
||||
int userCount = userOrderMap.size();
|
||||
int continuedUserCount = (int) userOrderMap.values().stream().filter(cnt -> cnt > 1).count();
|
||||
BigDecimal estimatedRevenue = calculateEarningsAmount(clerk.getId(), orders, startTime, endTime);
|
||||
@@ -568,6 +581,10 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
return value == null ? BigDecimal.ZERO : value;
|
||||
}
|
||||
|
||||
private boolean isCompletedOrder(PlayOrderInfoEntity order) {
|
||||
return order != null && OrderConstant.OrderStatus.COMPLETED.getCode().equals(order.getOrderStatus());
|
||||
}
|
||||
|
||||
private static final class DateRange {
|
||||
private final String startTime;
|
||||
private final String endTime;
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.starry.admin.modules.clerk.module.entity.PlayClerkLevelInfoEntity;
|
||||
import com.starry.admin.modules.clerk.module.entity.PlayClerkUserInfoEntity;
|
||||
import com.starry.admin.modules.clerk.service.IPlayClerkLevelInfoService;
|
||||
import com.starry.admin.modules.clerk.service.IPlayClerkUserInfoService;
|
||||
import com.starry.admin.modules.order.module.constant.OrderConstant;
|
||||
import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity;
|
||||
import com.starry.admin.modules.order.service.IPlayOrderInfoService;
|
||||
import com.starry.admin.modules.personnel.module.entity.PlayPersonnelGroupInfoEntity;
|
||||
@@ -21,6 +22,7 @@ import com.starry.admin.modules.statistics.module.vo.ClerkPerformanceOverviewQue
|
||||
import com.starry.admin.modules.statistics.module.vo.ClerkPerformanceOverviewResponseVo;
|
||||
import com.starry.admin.modules.statistics.module.vo.ClerkPerformanceOverviewSummaryVo;
|
||||
import com.starry.admin.modules.statistics.module.vo.ClerkPerformanceSnapshotVo;
|
||||
import com.starry.admin.modules.statistics.module.vo.PlayClerkPerformanceInfoReturnVo;
|
||||
import com.starry.admin.modules.statistics.service.impl.PlayClerkPerformanceServiceImpl;
|
||||
import com.starry.admin.modules.withdraw.mapper.EarningsLineMapper;
|
||||
import java.math.BigDecimal;
|
||||
@@ -231,6 +233,121 @@ class PlayClerkPerformanceServiceImplTest {
|
||||
assertEquals("2024-08-02 23:59:59", endCaptor.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("queryOverview ignores non-completed orders when computing summary/GMV")
|
||||
void queryOverviewSkipsNonCompletedOrders() {
|
||||
ClerkPerformanceOverviewQueryVo vo = new ClerkPerformanceOverviewQueryVo();
|
||||
vo.setIncludeSummary(true);
|
||||
vo.setIncludeRankings(true);
|
||||
vo.setEndOrderTime(Arrays.asList("2024-08-01 00:00:00", "2024-08-10 23:59:59"));
|
||||
|
||||
PlayClerkUserInfoEntity clerk = buildClerk("c10", "Neo", "g10", "l10");
|
||||
when(playPersonnelGroupInfoService.getValidClerkIdList(any(), any()))
|
||||
.thenReturn(Collections.singletonList("c10"));
|
||||
when(clerkUserInfoService.list((Wrapper<PlayClerkUserInfoEntity>) any()))
|
||||
.thenReturn(Collections.singletonList(clerk));
|
||||
when(playClerkLevelInfoService.selectAll()).thenReturn(Collections.singletonList(level("l10", "至尊")));
|
||||
when(playPersonnelGroupInfoService.selectAll()).thenReturn(Collections.singletonList(group("g10", "十组")));
|
||||
|
||||
PlayOrderInfoEntity o1 = order("c10", "user1", "1", "0", "0", new BigDecimal("100.00"),
|
||||
new BigDecimal("60.00"), LocalDateTime.of(2024, Month.AUGUST, 1, 10, 0));
|
||||
PlayOrderInfoEntity o2 = order("c10", "user2", "0", "0", "0", new BigDecimal("80.00"),
|
||||
new BigDecimal("40.00"), LocalDateTime.of(2024, Month.AUGUST, 2, 11, 0));
|
||||
PlayOrderInfoEntity o3 = withRefund(
|
||||
order("c10", "user3", "0", "0", "1", new BigDecimal("60.00"), new BigDecimal("35.00"),
|
||||
LocalDateTime.of(2024, Month.AUGUST, 3, 9, 30)),
|
||||
new BigDecimal("15.00"));
|
||||
PlayOrderInfoEntity o4 = order("c10", "user4", "0", "2", "0", new BigDecimal("40.00"),
|
||||
new BigDecimal("20.00"), LocalDateTime.of(2024, Month.AUGUST, 4, 16, 45));
|
||||
PlayOrderInfoEntity o5 = order("c10", "user5", "1", "0", "0", new BigDecimal("20.00"),
|
||||
new BigDecimal("10.00"), LocalDateTime.of(2024, Month.AUGUST, 5, 13, 15));
|
||||
PlayOrderInfoEntity o6 = withStatus(
|
||||
order("c10", "user6", "0", "0", "0", new BigDecimal("70.00"), new BigDecimal("30.00"),
|
||||
LocalDateTime.of(2024, Month.AUGUST, 6, 14, 0)),
|
||||
OrderConstant.OrderStatus.CANCELLED.getCode());
|
||||
PlayOrderInfoEntity o7 = withStatus(
|
||||
order("c10", "user7", "0", "0", "0", new BigDecimal("50.00"), new BigDecimal("25.00"),
|
||||
LocalDateTime.of(2024, Month.AUGUST, 6, 18, 20)),
|
||||
OrderConstant.OrderStatus.IN_PROGRESS.getCode());
|
||||
PlayOrderInfoEntity o8 = withStatus(
|
||||
order("c10", "user8", "0", "0", "0", new BigDecimal("45.00"), new BigDecimal("22.00"),
|
||||
LocalDateTime.of(2024, Month.AUGUST, 7, 15, 5)),
|
||||
OrderConstant.OrderStatus.ACCEPTED.getCode());
|
||||
PlayOrderInfoEntity o9 = withStatus(
|
||||
order("c10", "user9", "0", "0", "0", new BigDecimal("30.00"), new BigDecimal("15.00"),
|
||||
LocalDateTime.of(2024, Month.AUGUST, 8, 17, 40)),
|
||||
OrderConstant.OrderStatus.PENDING.getCode());
|
||||
PlayOrderInfoEntity o10 = withStatus(
|
||||
order("c10", "user10", "1", "0", "0", new BigDecimal("25.00"), new BigDecimal("12.00"),
|
||||
LocalDateTime.of(2024, Month.AUGUST, 9, 19, 10)),
|
||||
OrderConstant.OrderStatus.CANCELLED.getCode());
|
||||
|
||||
List<PlayOrderInfoEntity> mixedOrders =
|
||||
Arrays.asList(o1, o2, o3, o4, o5, o6, o7, o8, o9, o10);
|
||||
when(playOrderInfoService.clerkSelectOrderInfoList(eq("c10"), anyString(), anyString()))
|
||||
.thenReturn(mixedOrders);
|
||||
when(earningsLineMapper.sumAmountByClerkAndOrderIds(eq("c10"), anyCollection(), anyString(), anyString()))
|
||||
.thenReturn(new BigDecimal("210.00"));
|
||||
|
||||
setAuthentication();
|
||||
ClerkPerformanceOverviewResponseVo response;
|
||||
try {
|
||||
response = service.queryOverview(vo);
|
||||
} finally {
|
||||
clearAuthentication();
|
||||
}
|
||||
|
||||
assertEquals(1, response.getRankings().size());
|
||||
ClerkPerformanceSnapshotVo snapshot = response.getRankings().get(0);
|
||||
assertEquals(5, snapshot.getOrderCount());
|
||||
assertEquals(new BigDecimal("300.00"), snapshot.getGmv());
|
||||
assertEquals(new BigDecimal("40.00"), snapshot.getRewardAmount());
|
||||
assertEquals(new BigDecimal("15.00"), snapshot.getRefundAmount());
|
||||
assertEquals(new BigDecimal("210.00"), snapshot.getEstimatedRevenue());
|
||||
|
||||
ClerkPerformanceOverviewSummaryVo summary = response.getSummary();
|
||||
assertEquals(5, summary.getTotalOrderCount());
|
||||
assertEquals(new BigDecimal("300.00"), summary.getTotalGmv());
|
||||
assertEquals(1, summary.getTotalRefundOrderCount());
|
||||
|
||||
ArgumentCaptor<Collection<String>> idCaptor = ArgumentCaptor.forClass(Collection.class);
|
||||
verify(earningsLineMapper).sumAmountByClerkAndOrderIds(eq("c10"), idCaptor.capture(),
|
||||
anyString(), anyString());
|
||||
assertEquals(5, idCaptor.getValue().size());
|
||||
assertTrue(idCaptor.getValue().containsAll(
|
||||
Arrays.asList(o1.getId(), o2.getId(), o3.getId(), o4.getId(), o5.getId())));
|
||||
}
|
||||
@Test
|
||||
@DisplayName("getClerkPerformanceInfo should ignore non-completed orders when aggregating GMV")
|
||||
void getClerkPerformanceInfoSkipsNonCompletedOrders() {
|
||||
PlayClerkUserInfoEntity clerk = buildClerk("c9", "Nine", "gX", "lX");
|
||||
List<PlayClerkLevelInfoEntity> levels = Collections.singletonList(level("lX", "钻石"));
|
||||
List<PlayPersonnelGroupInfoEntity> groups = Collections.singletonList(group("gX", "特战组"));
|
||||
|
||||
PlayOrderInfoEntity completed = order("c9", "userA", "1", "0", "0", new BigDecimal("120.00"),
|
||||
new BigDecimal("60.00"), LocalDateTime.of(2024, Month.AUGUST, 1, 10, 0));
|
||||
PlayOrderInfoEntity cancelled = withStatus(
|
||||
order("c9", "userB", "0", "0", "0", new BigDecimal("200.00"), new BigDecimal("100.00"),
|
||||
LocalDateTime.of(2024, Month.AUGUST, 1, 12, 0)),
|
||||
OrderConstant.OrderStatus.CANCELLED.getCode());
|
||||
|
||||
when(earningsLineMapper.sumAmountByClerkAndOrderIds(eq("c9"), anyCollection(), anyString(), anyString()))
|
||||
.thenReturn(new BigDecimal("60.00"));
|
||||
|
||||
PlayClerkPerformanceInfoReturnVo result = service.getClerkPerformanceInfo(clerk,
|
||||
Arrays.asList(completed, cancelled), levels, groups, "2024-08-01 00:00:00", "2024-08-02 23:59:59");
|
||||
|
||||
assertEquals(new BigDecimal("120.00"), result.getFinalAmount());
|
||||
assertEquals(1, result.getOrderNumber());
|
||||
assertEquals(1, result.getCustomNumber());
|
||||
|
||||
ArgumentCaptor<Collection<String>> idCaptor = ArgumentCaptor.forClass(Collection.class);
|
||||
verify(earningsLineMapper).sumAmountByClerkAndOrderIds(eq("c9"), idCaptor.capture(),
|
||||
eq("2024-08-01 00:00:00"), eq("2024-08-02 23:59:59"));
|
||||
assertEquals(1, idCaptor.getValue().size());
|
||||
assertTrue(idCaptor.getValue().contains(completed.getId()));
|
||||
}
|
||||
|
||||
private PlayClerkUserInfoEntity buildClerk(String id, String name, String groupId, String levelId) {
|
||||
PlayClerkUserInfoEntity entity = new PlayClerkUserInfoEntity();
|
||||
entity.setId(id);
|
||||
@@ -270,6 +387,7 @@ class PlayClerkPerformanceServiceImplTest {
|
||||
order.setOrdersExpiredState("1".equals(refundType) ? "1" : "0");
|
||||
order.setPurchaserTime(purchaserTime);
|
||||
order.setId(clerkId + "-" + purchaser + "-" + purchaserTime.toString());
|
||||
order.setOrderStatus(OrderConstant.OrderStatus.COMPLETED.getCode());
|
||||
return order;
|
||||
}
|
||||
|
||||
@@ -288,4 +406,9 @@ class PlayClerkPerformanceServiceImplTest {
|
||||
order.setRefundAmount(refundAmount);
|
||||
return order;
|
||||
}
|
||||
|
||||
private PlayOrderInfoEntity withStatus(PlayOrderInfoEntity order, String status) {
|
||||
order.setOrderStatus(status);
|
||||
return order;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user