86 lines
2.6 KiB
Go
86 lines
2.6 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("--- Advanced Coupon Data Reconciliation (Cloud DB) ---")
|
|
|
|
var userCoupons []struct {
|
|
ID int64
|
|
UserID int64
|
|
SystemAmount int64
|
|
BalanceAmount int64
|
|
Status int32
|
|
ValidEnd string
|
|
}
|
|
|
|
// Join with system_coupons to get original amount
|
|
db.Raw(`
|
|
SELECT uc.id, uc.user_id, sc.discount_value as system_amount, uc.balance_amount, uc.status, uc.valid_end
|
|
FROM user_coupons uc
|
|
JOIN system_coupons sc ON uc.coupon_id = sc.id
|
|
`).Scan(&userCoupons)
|
|
|
|
fmt.Println("Generating repair SQL based on ledger and order association...")
|
|
|
|
for _, uc := range userCoupons {
|
|
// Calculate total deduction from ledger
|
|
var totalDeduction struct {
|
|
Sum int64
|
|
}
|
|
db.Raw("SELECT ABS(SUM(change_amount)) as sum FROM user_coupon_ledger WHERE user_coupon_id = ? AND action = 'apply'", uc.ID).Scan(&totalDeduction)
|
|
|
|
// Calculate total deduction from order_coupons (secondary verification)
|
|
var orderDeduction struct {
|
|
Sum int64
|
|
}
|
|
db.Raw("SELECT SUM(applied_amount) as sum FROM order_coupons WHERE user_coupon_id = ?", uc.ID).Scan(&orderDeduction)
|
|
|
|
// Choose the source of truth (ledger usually preferred)
|
|
actualUsed := totalDeduction.Sum
|
|
if orderDeduction.Sum > actualUsed {
|
|
actualUsed = orderDeduction.Sum
|
|
}
|
|
|
|
expectedBalance := uc.SystemAmount - actualUsed
|
|
if expectedBalance < 0 {
|
|
expectedBalance = 0
|
|
}
|
|
|
|
expectedStatus := uc.Status
|
|
if expectedBalance == 0 {
|
|
expectedStatus = 2 // Fully Used
|
|
} else if expectedBalance > 0 {
|
|
// Check if it should be expired or unused
|
|
// We won't downgrade Expired (3) back to Unused (1) unless balance > 0 and time is not up.
|
|
// However, usually if balance > 0 and Status is 2, it's a bug.
|
|
}
|
|
|
|
// Check for status 3 that shouldn't be
|
|
// (Currently the user says they see status 3 but it's used?)
|
|
// If balance == 0, status must be 2.
|
|
|
|
if expectedBalance != uc.BalanceAmount || expectedStatus != uc.Status {
|
|
fmt.Printf("-- Coupon %d (User %d): Bal %d->%d, Status %v->%v (Used: %d, Orig: %d)\n",
|
|
uc.ID, uc.UserID, uc.BalanceAmount, expectedBalance, uc.Status, expectedStatus, actualUsed, uc.SystemAmount)
|
|
fmt.Printf("UPDATE user_coupons SET balance_amount = %d, status = %v WHERE id = %d;\n",
|
|
expectedBalance, expectedStatus, uc.ID)
|
|
}
|
|
}
|
|
}
|