| New file |
| | |
| | | package com.talentcard.server.service; |
| | | |
| | | import static org.assertj.core.api.Assertions.assertThat; |
| | | |
| | | import java.sql.Timestamp; |
| | | import java.time.LocalDateTime; |
| | | import java.util.Map; |
| | | |
| | | import org.junit.jupiter.api.BeforeEach; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.test.context.SpringBootTest; |
| | | import org.springframework.jdbc.core.JdbcTemplate; |
| | | import org.springframework.test.context.ActiveProfiles; |
| | | |
| | | /** |
| | | * 商户首页统计卡片的取数口径。 |
| | | * |
| | | * <p>「交易总额」是商户首页最显眼的数字,口径必须是**已支付且已核销**的订单实付金额: |
| | | * 未核销的订单钱还扣在通道的延迟户里,核销后才分账给商户,把它算进交易总额等于告诉商户 |
| | | * 他已经收到了还没到手的钱。 |
| | | * |
| | | * <p>另一个必守的性质是**退款受理后首页立刻回落**。人才端的退款受理成功只把订单置为「退款中」, |
| | | * 通道的最终结果要等对账任务或下一次读订单才收敛(最长十分钟),中间这段时间订单还是 |
| | | * {@code order_status = 1}。所以统计口径不能依赖订单状态收敛,必须靠「是否核销」把这类订单挡在外面。 |
| | | */ |
| | | @SpringBootTest |
| | | @ActiveProfiles("test") |
| | | class MerchantSettlementStatisticsServiceTests { |
| | | |
| | | @Autowired |
| | | private JdbcTemplate jdbc; |
| | | |
| | | @Autowired |
| | | private MerchantSettlementStatisticsService service; |
| | | |
| | | private Long merchantId; |
| | | private Long talentId; |
| | | |
| | | @BeforeEach |
| | | void prepareMerchant() { |
| | | String suffix = String.valueOf(System.nanoTime()); |
| | | jdbc.update("insert into merchant(merchant_name, status, can_login_merchant_app, deleted) values (?, 1, 1, 0)", |
| | | "首页统计测试商户 " + suffix); |
| | | merchantId = jdbc.queryForObject("select max(id) from merchant", Long.class); |
| | | jdbc.update("insert into talent_user(openid, name, mobile, status, deleted) values (?, ?, ?, 1, 0)", |
| | | "dashboard-test-" + suffix, "首页统计测试人才", "13800000000"); |
| | | talentId = jdbc.queryForObject("select max(id) from talent_user", Long.class); |
| | | } |
| | | |
| | | @Test |
| | | void countsOnlyVerifiedOrdersInDashboardTransactionAmount() { |
| | | long verifiedPayAmount = 1000L; |
| | | // 已支付且已核销:钱已经确认分账给商户,计入。 |
| | | insertOrder("VER", 1, 1, 0, verifiedPayAmount); |
| | | // 已支付但未核销:钱还在延迟户,未核销就不算。 |
| | | insertOrder("UNV", 1, 0, 0, 2000L); |
| | | // 已支付、未核销、退款受理中:人才端刚点了退款,通道结果还没收敛,首页必须立刻回落。 |
| | | insertOrder("REF", 1, 0, 1, 4000L); |
| | | |
| | | Map<String, Object> cards = service.dashboardCards(merchantId); |
| | | |
| | | assertThat(((Number) cards.get("transactionAmountCents")).longValue()).isEqualTo(verifiedPayAmount); |
| | | } |
| | | |
| | | private void insertOrder(String marker, int orderStatus, int verifyStatus, int refundStatus, long payAmount) { |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | jdbc.update(""" |
| | | insert into benefit_order(order_no, order_type, merchant_id, talent_id, product_name_snapshot, |
| | | order_amount, pay_amount, subsidy_amount, order_status, verify_status, |
| | | refund_status, created_at, updated_at, deleted) |
| | | values (?, 'GROUP_BUY', ?, ?, ?, ?, ?, 0, ?, ?, ?, ?, ?, 0) |
| | | """, |
| | | "DASHBOARD-" + marker + "-" + System.nanoTime(), merchantId, talentId, "首页统计测试商品", |
| | | payAmount, payAmount, orderStatus, verifyStatus, refundStatus, |
| | | Timestamp.valueOf(now), Timestamp.valueOf(now)); |
| | | } |
| | | } |