fix(admin): correct Google paid sync count
This commit is contained in:
parent
b5f85ec5c5
commit
14604861ea
@ -37,9 +37,12 @@ type LegacyGooglePaidStats struct {
|
||||
EstNetUSDMinor int64
|
||||
}
|
||||
|
||||
// LegacyGooglePaidStatsByBillTime 按账单创建时间段聚合已同步实付:税/费/净收按实付占比折算到账单美金口径。
|
||||
// LegacyGooglePaidStatsByBillTime 按账单创建时间段聚合实付同步覆盖度。
|
||||
// synced_at_ms 是 Orders API 请求已成功落库的事实;Google 作为 Merchant of Record 时可能不返回
|
||||
// developerRevenueInBuyerCurrency,此时 paid_net_micro=0 只表示缺少费用明细,不能把已同步订单重新算成未同步。
|
||||
// 税/费/净收仍只对实付和净收都有效的订单按比例折算,避免用缺失字段伪造费用数据。
|
||||
func (s *Store) LegacyGooglePaidStatsByBillTime(appCode string, startAtMS int64, endAtMS int64) (LegacyGooglePaidStats, error) {
|
||||
where := "app_code = ? AND paid_amount_micro > 0 AND paid_net_micro > 0"
|
||||
where := "app_code = ?"
|
||||
args := []any{strings.ToLower(strings.TrimSpace(appCode))}
|
||||
if startAtMS > 0 {
|
||||
where += " AND bill_created_at_ms >= ?"
|
||||
@ -51,11 +54,14 @@ func (s *Store) LegacyGooglePaidStatsByBillTime(appCode string, startAtMS int64,
|
||||
}
|
||||
var stats LegacyGooglePaidStats
|
||||
row := s.db.Raw(`
|
||||
SELECT COUNT(*),
|
||||
COALESCE(SUM(bill_usd_minor), 0),
|
||||
COALESCE(SUM(ROUND(bill_usd_minor * GREATEST(paid_amount_micro - paid_net_micro - paid_tax_micro, 0) / paid_amount_micro)), 0),
|
||||
COALESCE(SUM(ROUND(bill_usd_minor * paid_tax_micro / paid_amount_micro)), 0),
|
||||
COALESCE(SUM(ROUND(bill_usd_minor * paid_net_micro / paid_amount_micro)), 0)
|
||||
SELECT COALESCE(SUM(CASE WHEN synced_at_ms > 0 THEN 1 ELSE 0 END), 0),
|
||||
COALESCE(SUM(CASE WHEN paid_amount_micro > 0 AND paid_net_micro > 0 THEN bill_usd_minor ELSE 0 END), 0),
|
||||
COALESCE(SUM(CASE WHEN paid_amount_micro > 0 AND paid_net_micro > 0
|
||||
THEN ROUND(bill_usd_minor * GREATEST(paid_amount_micro - paid_net_micro - paid_tax_micro, 0) / paid_amount_micro) ELSE 0 END), 0),
|
||||
COALESCE(SUM(CASE WHEN paid_amount_micro > 0 AND paid_net_micro > 0
|
||||
THEN ROUND(bill_usd_minor * paid_tax_micro / paid_amount_micro) ELSE 0 END), 0),
|
||||
COALESCE(SUM(CASE WHEN paid_amount_micro > 0 AND paid_net_micro > 0
|
||||
THEN ROUND(bill_usd_minor * paid_net_micro / paid_amount_micro) ELSE 0 END), 0)
|
||||
FROM admin_legacy_google_paid_details
|
||||
WHERE `+where, args...).Row()
|
||||
if err := row.Scan(&stats.SyncedCount, &stats.CoveredUSDMinor, &stats.EstFeeUSDMinor, &stats.EstTaxUSDMinor, &stats.EstNetUSDMinor); err != nil {
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
)
|
||||
|
||||
func TestLegacyGooglePaidStatsCountsSyncedRowsWithoutNetRevenue(t *testing.T) {
|
||||
store, mock, closeStore := newRepositorySQLMock(t)
|
||||
defer closeStore()
|
||||
|
||||
// 108 笔 Orders API 结果都已落库,但只有 2 笔带开发者净收。同步覆盖度必须仍为 108,
|
||||
// 金额估算则继续只覆盖净收有效的 2 笔,这正是 Google Merchant of Record 订单的线上边界。
|
||||
mock.ExpectQuery(`(?s)SELECT.*SUM\(CASE WHEN synced_at_ms > 0 THEN 1 ELSE 0 END\).*CASE WHEN paid_amount_micro > 0 AND paid_net_micro > 0.*WHERE app_code = \? AND bill_created_at_ms >= \? AND bill_created_at_ms < \?`).
|
||||
WithArgs("yumi", int64(1783872000000), int64(1783958400000)).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"synced_count", "covered_usd_minor", "fee_usd_minor", "tax_usd_minor", "net_usd_minor"}).
|
||||
AddRow(108, 4200, 630, 210, 3360))
|
||||
|
||||
stats, err := store.LegacyGooglePaidStatsByBillTime(" YUMI ", 1783872000000, 1783958400000)
|
||||
if err != nil {
|
||||
t.Fatalf("load legacy google paid stats failed: %v", err)
|
||||
}
|
||||
if stats.SyncedCount != 108 {
|
||||
t.Fatalf("synced count must use synced_at_ms instead of net revenue: %+v", stats)
|
||||
}
|
||||
if stats.CoveredUSDMinor != 4200 || stats.EstFeeUSDMinor != 630 || stats.EstTaxUSDMinor != 210 || stats.EstNetUSDMinor != 3360 {
|
||||
t.Fatalf("settlement estimates mismatch: %+v", stats)
|
||||
}
|
||||
if err := mock.ExpectationsWereMet(); err != nil {
|
||||
t.Fatalf("sql expectations mismatch: %v", err)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user