86 lines
2.4 KiB
Go
86 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"gorm.io/driver/mysql"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
const (
|
|
DbDSN = "root:bindbox2025kdy@tcp(150.158.78.154:3306)/dev_game?charset=utf8mb4&parseTime=True&loc=Local"
|
|
)
|
|
|
|
func main() {
|
|
db, err := gorm.Open(mysql.Open(DbDSN), &gorm.Config{})
|
|
if err != nil {
|
|
log.Fatalf("DB connection failed: %v", err)
|
|
}
|
|
|
|
fmt.Println("--- Activity-Based Coupon Data Repair Auditor (Cloud DB) ---")
|
|
|
|
var records []struct {
|
|
ID int64
|
|
UserID int64
|
|
CouponID int64
|
|
BalanceAmount int64
|
|
Status int32
|
|
ValidEnd string
|
|
OriginalValue int64
|
|
DiscountType int32
|
|
}
|
|
|
|
// Fetch all coupons joined with system data
|
|
db.Raw(`
|
|
SELECT uc.id, uc.user_id, uc.coupon_id, uc.balance_amount, uc.status, uc.valid_end, sc.discount_value as original_value, sc.discount_type
|
|
FROM user_coupons uc
|
|
JOIN system_coupons sc ON uc.coupon_id = sc.id
|
|
`).Scan(&records)
|
|
|
|
for _, r := range records {
|
|
// Calculate total usage from order_coupons
|
|
var orderUsage int64
|
|
db.Raw("SELECT SUM(applied_amount) FROM order_coupons WHERE user_coupon_id = ?", r.ID).Scan(&orderUsage)
|
|
|
|
// Calculate total usage from ledger
|
|
var ledgerUsage int64
|
|
db.Raw("SELECT ABS(SUM(change_amount)) FROM user_coupon_ledger WHERE user_coupon_id = ? AND action = 'apply'", r.ID).Scan(&ledgerUsage)
|
|
|
|
// Max usage between sources
|
|
finalUsage := orderUsage
|
|
if ledgerUsage > finalUsage {
|
|
finalUsage = ledgerUsage
|
|
}
|
|
|
|
expectedBalance := r.OriginalValue - finalUsage
|
|
if expectedBalance < 0 {
|
|
expectedBalance = 0
|
|
}
|
|
|
|
// Determine Correct Status
|
|
// 1: Unused (or Partially Used but still valid)
|
|
// 2: Used (Exhausted)
|
|
// 3: Expired (Unused/Partially Used and time past)
|
|
|
|
expectedStatus := r.Status
|
|
if expectedBalance == 0 {
|
|
expectedStatus = 2
|
|
} else {
|
|
// Logic for expired vs unused would go here if needed,
|
|
// but we prioritize "Used" if balance is 0.
|
|
// Currently if balance > 0 and Status is 2, it's definitely an error.
|
|
if r.Status == 2 {
|
|
expectedStatus = 1 // Revert to unused/partial if balance > 0
|
|
}
|
|
}
|
|
|
|
if expectedBalance != r.BalanceAmount || expectedStatus != r.Status {
|
|
fmt.Printf("-- Coupon %d (User %d): Bal %d->%d, Status %v->%v, Usage %d/%d\n",
|
|
r.ID, r.UserID, r.BalanceAmount, expectedBalance, r.Status, expectedStatus, finalUsage, r.OriginalValue)
|
|
fmt.Printf("UPDATE user_coupons SET balance_amount = %d, status = %v, updated_at = NOW() WHERE id = %d;\n",
|
|
expectedBalance, expectedStatus, r.ID)
|
|
}
|
|
}
|
|
}
|