From 839e7d190219d1273047549db3bbb7a3c316987d Mon Sep 17 00:00:00 2001 From: FUJIWARA Shunichiro Date: Wed, 29 Jun 2022 09:59:33 +0900 Subject: [PATCH 1/2] =?UTF-8?q?billing=E3=81=AB=E5=86=85=E8=A8=B3=E3=82=92?= =?UTF-8?q?=E8=A8=98=E8=BC=89=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 課金は2種類(複雑になるので50円のはなくした) スコア登録した人数、閲覧だけした人数とそれぞれの金額もreportに載せる --- webapp/go/isuports.go | 50 ++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/webapp/go/isuports.go b/webapp/go/isuports.go index 1a3da270..37aec4b6 100644 --- a/webapp/go/isuports.go +++ b/webapp/go/isuports.go @@ -529,10 +529,13 @@ func validateTenantName(name string) error { } type BillingReport struct { - CompetitionID string `json:"competition_id"` - CompetitionTitle string `json:"competition_title"` - PlayerCount int64 `json:"player_count"` - BillingYen int64 `json:"billing_yen"` + CompetitionID string `json:"competition_id"` + CompetitionTitle string `json:"competition_title"` + PlayerCount int64 `json:"player_count"` // スコアを登録した参加者数 + VisitorCount int64 `json:"visitor_count"` // ランキングを閲覧だけした(スコアを登録していない)参加者数 + BillingPlayerYen int64 `json:"billing_player_yen"` // 請求金額 スコアを登録した参加者分 + BillingVisitorYen int64 `json:"billing_visitor_yen"` // 請求金額 ランキングを閲覧だけした(スコアを登録していない)参加者分 + BillingYen int64 `json:"billing_yen"` // 合計請求金額 } type VisitHistoryRow struct { @@ -555,6 +558,7 @@ func billingReportByCompetition(ctx context.Context, tenantDB dbOrTx, tenantID i return nil, fmt.Errorf("error retrieveCompetition: %w", err) } + // ランキングにアクセスした参加者のIDを取得する vhs := []VisitHistorySummaryRow{} if err := adminDB.SelectContext( ctx, @@ -565,14 +569,13 @@ func billingReportByCompetition(ctx context.Context, tenantDB dbOrTx, tenantID i ); err != nil && err != sql.ErrNoRows { return nil, fmt.Errorf("error Select visit_history: tenantID=%d, competitionID=%s, %w", tenantID, comp.ID, err) } - billingMap := map[string]int64{} + billingMap := map[string]string{} for _, vh := range vhs { // competition.finished_atよりもあとの場合は、終了後に訪問したとみなして大会開催内アクセス済みとみなさない if comp.FinishedAt.Valid && comp.FinishedAt.Int64 < vh.MinCreatedAt { continue } - // scoreに登録されていないplayerでアクセスした人 * 10 - billingMap[vh.PlayerID] = 10 + billingMap[vh.PlayerID] = "visitor" } // player_scoreを読んでいるときに更新が走ると不整合が起こるのでロックを取得する @@ -581,6 +584,8 @@ func billingReportByCompetition(ctx context.Context, tenantDB dbOrTx, tenantID i return nil, fmt.Errorf("error flockByTenantID: %w", err) } defer fl.Close() + + // スコアを登録した参加者のIDを取得する scoredPlayerIDs := []string{} if err := tenantDB.SelectContext( ctx, @@ -592,26 +597,31 @@ func billingReportByCompetition(ctx context.Context, tenantDB dbOrTx, tenantID i } for _, pid := range scoredPlayerIDs { if _, ok := billingMap[pid]; ok { - // scoreに登録されているplayerでアクセスした人 * 100 - billingMap[pid] = 100 - } else { - // scoreに登録されているplayerでアクセスしていない人 * 50 - billingMap[pid] = 50 + // スコアが登録されている参加者 + billingMap[pid] = "player" } } - var billingYen int64 - // 大会が終了している場合は課金を計算する(開催中の場合は常に 0) + // 大会が終了している場合のみ請求金額が確定するので計算する + var playerCount, visitorCount int64 if comp.FinishedAt.Valid { - for _, v := range billingMap { - billingYen += v + for _, category := range billingMap { + switch category { + case "player": + playerCount++ + case "visitor": + visitorCount++ + } } } return &BillingReport{ - CompetitionID: comp.ID, - CompetitionTitle: comp.Title, - PlayerCount: int64(len(scoredPlayerIDs)), - BillingYen: billingYen, + CompetitionID: comp.ID, + CompetitionTitle: comp.Title, + PlayerCount: playerCount, + VisitorCount: visitorCount, + BillingPlayerYen: 100 * playerCount, // スコアを登録した参加者は100円 + BillingVisitorYen: 10 * visitorCount, // ランキングを閲覧だけした(スコアを登録していない)参加者は10円 + BillingYen: 100*playerCount + 10*visitorCount, }, nil } From 384e1288814012f18b8ba03c807ec4620c8d13b0 Mon Sep 17 00:00:00 2001 From: FUJIWARA Shunichiro Date: Wed, 29 Jun 2022 10:13:35 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=E8=AB=8B=E6=B1=82=E3=81=AE=E8=A8=88?= =?UTF-8?q?=E7=AE=97=E6=96=B9=E6=B3=95=E3=81=8C=E5=A4=89=E3=82=8F=E3=81=A3?= =?UTF-8?q?=E3=81=9F=E3=81=AE=E3=81=A7=E6=A4=9C=E8=A8=BC=E3=82=82=E5=AF=BE?= =?UTF-8?q?=E5=BF=9C=E3=81=97=E3=81=A6=E5=A4=89=E3=81=88=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bench/scenario_validation.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/bench/scenario_validation.go b/bench/scenario_validation.go index 874bddfb..4f9d6d39 100644 --- a/bench/scenario_validation.go +++ b/bench/scenario_validation.go @@ -455,11 +455,22 @@ func (sc *Scenario) ValidationScenario(ctx context.Context, step *isucandar.Benc return fmt.Errorf("対象の大会のIDが違います (want: %s, got: %s)", competitionID, r.Data.Reports[0].CompetitionID) } // score登録者 rankingアクセスあり: 100 yen x 1 player - // score登録者 rankingアクセスなし: 50 yen x (playerNum - 2) player // score未登録者 rankingアクセスあり: 10 yen x 1 player - billingYen := int64((100 * 1) + (50 * (playerNum - 2)) + (10 * 1)) + if r.Data.Reports[0].PlayerCount != 1 { + return fmt.Errorf("大会の参加者数が違います competitionID: %s (want: %d, got: %d)", competitionID, 1, r.Data.Reports[0].PlayerCount) + } + if r.Data.Reports[0].VisitorCount != 1 { + return fmt.Errorf("大会の閲覧者数が違います competitionID: %s (want: %d, got: %d)", competitionID, 1, r.Data.Reports[0].VisitorCount) + } + if r.Data.Reports[0].BillingPlayerYen != 100 { + return fmt.Errorf("大会の請求金額内訳(参加者分)が違います competitionID: %s (want: %d, got: %d)", competitionID, 100, r.Data.Reports[0].BillingPlayerYen) + } + if r.Data.Reports[0].BillingVisitorYen != 10 { + return fmt.Errorf("大会の請求金額内訳(閲覧者)が違います competitionID: %s (want: %d, got: %d)", competitionID, 10, r.Data.Reports[0].BillingVisitorYen) + } + billingYen := int64((100 * 1) + (10 * 1)) if billingYen != r.Data.Reports[0].BillingYen { - return fmt.Errorf("大会の請求金額が違います competitionID: %s (want: %d, got: %d)", competitionID, billingYen, r.Data.Reports[0].BillingYen) + return fmt.Errorf("大会の請求金額合計が違います competitionID: %s (want: %d, got: %d)", competitionID, billingYen, r.Data.Reports[0].BillingYen) } return nil