From cabc283673742a804102e2bd789ffa1f60fc64f4 Mon Sep 17 00:00:00 2001 From: H3ALY Date: Fri, 28 Mar 2025 13:04:53 +0000 Subject: [PATCH] madness continues --- handlers/admin/manualtriggers.go | 2 +- handlers/ticket_handler.go | 20 +++++++++-- helpers/ballslice.go | 2 ++ helpers/match.go | 16 +++++++++ helpers/template.go | 3 +- matcher/engine.go | 32 ++++++++++++++++++ models/ticket.go | 5 +-- services/draws/drawlookup.go | 19 ++++++++--- services/tickets/ticketmatching.go | 12 +++++-- static/css/site.css | 41 +++++++++++++++++++++-- templates/account/tickets/my_tickets.html | 27 ++++++++++----- templates/layout.html | 2 +- 12 files changed, 156 insertions(+), 25 deletions(-) create mode 100644 helpers/match.go diff --git a/handlers/admin/manualtriggers.go b/handlers/admin/manualtriggers.go index 6b24a88..8ad3836 100644 --- a/handlers/admin/manualtriggers.go +++ b/handlers/admin/manualtriggers.go @@ -6,7 +6,7 @@ import ( "net/http" "strconv" "synlotto-website/helpers" - "synlotto-website/services" + services "synlotto-website/services/tickets" ) func AdminTriggersHandler(db *sql.DB) http.HandlerFunc { diff --git a/handlers/ticket_handler.go b/handlers/ticket_handler.go index ff5120b..6c335eb 100644 --- a/handlers/ticket_handler.go +++ b/handlers/ticket_handler.go @@ -11,6 +11,7 @@ import ( "strconv" "synlotto-website/helpers" "synlotto-website/models" + draws "synlotto-website/services/draws" "time" "github.com/gorilla/csrf" @@ -312,8 +313,13 @@ func GetMyTickets(db *sql.DB) http.HandlerFunc { continue } - t.Ball1, t.Ball2, t.Ball3 = int(b1.Int64), int(b2.Int64), int(b3.Int64) - t.Ball4, t.Ball5, t.Ball6 = int(b4.Int64), int(b5.Int64), int(b6.Int64) + // Build primary number + bonus fields + t.Ball1 = int(b1.Int64) + t.Ball2 = int(b2.Int64) + t.Ball3 = int(b3.Int64) + t.Ball4 = int(b4.Int64) + t.Ball5 = int(b5.Int64) + t.Ball6 = int(b6.Int64) t.Bonus1 = helpers.IntPtrIfValid(bo1) t.Bonus2 = helpers.IntPtrIfValid(bo2) @@ -330,9 +336,19 @@ func GetMyTickets(db *sql.DB) http.HandlerFunc { t.IsWinner = isWinner.Bool } + // Build balls slices (for template use) t.Balls = helpers.BuildBallsSlice(t) t.BonusBalls = helpers.BuildBonusSlice(t) + // 🎯 Get the actual draw info (used to show which numbers matched) + draw := draws.GetDrawResultForTicket(db, t.GameType, t.DrawDate) + t.MatchedDraw = draw + + // ✅ DEBUG + log.Printf("✅ Ticket #%d", t.Id) + log.Printf("Balls: %v", t.Balls) + log.Printf("DrawResult: %+v", draw) + tickets = append(tickets, t) } diff --git a/helpers/ballslice.go b/helpers/ballslice.go index 7c4b54c..a69454f 100644 --- a/helpers/ballslice.go +++ b/helpers/ballslice.go @@ -7,6 +7,7 @@ func BuildBallsSlice(t models.Ticket) []int { if t.GameType == "Lotto" && t.Ball6 > 0 { balls = append(balls, t.Ball6) } + return balls } @@ -18,5 +19,6 @@ func BuildBonusSlice(t models.Ticket) []int { if t.Bonus2 != nil { bonuses = append(bonuses, *t.Bonus2) } + return bonuses } diff --git a/helpers/match.go b/helpers/match.go new file mode 100644 index 0000000..980d218 --- /dev/null +++ b/helpers/match.go @@ -0,0 +1,16 @@ +package helpers + +func CountMatches(a, b []int) int { + m := make(map[int]bool) + for _, n := range b { + m[n] = true + } + match := 0 + for _, n := range a { + if m[n] { + match++ + } + } + + return match +} diff --git a/helpers/template.go b/helpers/template.go index 243933a..262c743 100644 --- a/helpers/template.go +++ b/helpers/template.go @@ -69,5 +69,6 @@ func InSlice(n int, list []int) bool { return true } } - return false + + return true } diff --git a/matcher/engine.go b/matcher/engine.go index e69de29..145d671 100644 --- a/matcher/engine.go +++ b/matcher/engine.go @@ -0,0 +1,32 @@ +package matcher + +import ( + "synlotto-website/helpers" + "synlotto-website/models" +) + +func MatchTicketToDraw(ticket models.MatchTicket, draw models.DrawResult, rules []models.PrizeRule) models.MatchResult { + mainMatches := helpers.CountMatches(ticket.Balls, draw.Balls) + bonusMatches := helpers.CountMatches(ticket.BonusBalls, draw.BonusBalls) + + prizeTier := getPrizeTier(ticket.GameType, mainMatches, bonusMatches, rules) + isWinner := prizeTier != "" + + return models.MatchResult{ + MatchedDrawID: draw.DrawID, + MatchedMain: mainMatches, + MatchedBonus: bonusMatches, + PrizeTier: prizeTier, + IsWinner: isWinner, + } +} + +func getPrizeTier(game string, main, bonus int, rules []models.PrizeRule) string { + for _, rule := range rules { + if rule.Game == game && rule.MainMatches == main && rule.BonusMatches == bonus { + return rule.Tier + } + } + + return "" +} diff --git a/models/ticket.go b/models/ticket.go index 46ed80d..9ea6346 100644 --- a/models/ticket.go +++ b/models/ticket.go @@ -22,6 +22,7 @@ type Ticket struct { IsWinner bool // Used only for display these are not stored in the DB, they mirror MatchTicket structure but are populated on read. - Balls []int - BonusBalls []int + Balls []int + BonusBalls []int + MatchedDraw DrawResult } diff --git a/services/draws/drawlookup.go b/services/draws/drawlookup.go index ac66fde..a70f8db 100644 --- a/services/draws/drawlookup.go +++ b/services/draws/drawlookup.go @@ -8,22 +8,31 @@ import ( func GetDrawResultForTicket(db *sql.DB, game string, drawDate string) models.DrawResult { var result models.DrawResult + + if game != "Thunderball" { + log.Printf("Draw lookup for unsupported game type: %s", game) + return result + } + query := ` - SELECT id, ball1, ball2, ball3, ball4, ball5, bonus1 + SELECT id, ball1, ball2, ball3, ball4, ball5, thunderball FROM results_thunderball WHERE draw_date = ? ` - var b1, b2, b3, b4, b5, bonus sql.NullInt64 - err := db.QueryRow(query, drawDate).Scan(&result.DrawID, &b1, &b2, &b3, &b4, &b5, &bonus) + + var b1, b2, b3, b4, b5, tb sql.NullInt64 + err := db.QueryRow(query, drawDate).Scan(&result.DrawID, &b1, &b2, &b3, &b4, &b5, &tb) if err != nil { log.Printf("No draw found for %s %s: %v", game, drawDate, err) return result } + result.GameType = game result.DrawDate = drawDate result.Balls = []int{int(b1.Int64), int(b2.Int64), int(b3.Int64), int(b4.Int64), int(b5.Int64)} - if bonus.Valid { - result.BonusBalls = []int{int(bonus.Int64)} + if tb.Valid { + result.BonusBalls = []int{int(tb.Int64)} } + return result } diff --git a/services/tickets/ticketmatching.go b/services/tickets/ticketmatching.go index 4ee7ed8..4c8d119 100644 --- a/services/tickets/ticketmatching.go +++ b/services/tickets/ticketmatching.go @@ -7,6 +7,7 @@ import ( "synlotto-website/helpers" "synlotto-website/models" "synlotto-website/rules" + draws "synlotto-website/services/draws" ) func RunTicketMatching(db *sql.DB, triggeredBy string) (models.MatchRunStats, error) { @@ -24,6 +25,9 @@ func RunTicketMatching(db *sql.DB, triggeredBy string) (models.MatchRunStats, er } defer rows.Close() + // Buffer results to avoid writing while iterating + var pending []models.Ticket + for rows.Next() { var t models.Ticket var b1, b2, b3, b4, b5, b6, bo1, bo2 sql.NullInt64 @@ -45,6 +49,10 @@ func RunTicketMatching(db *sql.DB, triggeredBy string) (models.MatchRunStats, er t.Bonus1 = helpers.IntPtrIfValid(bo1) t.Bonus2 = helpers.IntPtrIfValid(bo2) + pending = append(pending, t) + } + + for _, t := range pending { matchTicket := models.MatchTicket{ ID: t.Id, GameType: t.GameType, @@ -53,14 +61,14 @@ func RunTicketMatching(db *sql.DB, triggeredBy string) (models.MatchRunStats, er BonusBalls: helpers.BuildBonusSlice(t), } - draw := GetDrawResultForTicket(db, t.GameType, t.DrawDate) + draw := draws.GetDrawResultForTicket(db, t.GameType, t.DrawDate) result := handlers.MatchTicketToDraw(matchTicket, draw, rules.ThunderballPrizeRules) if result.MatchedDrawID == 0 { continue } - _, err = db.Exec(` + _, err := db.Exec(` UPDATE my_tickets SET matched_main = ?, matched_bonus = ?, prize_tier = ?, is_winner = ? WHERE id = ? diff --git a/static/css/site.css b/static/css/site.css index 3436477..eb5d446 100644 --- a/static/css/site.css +++ b/static/css/site.css @@ -10,6 +10,7 @@ margin-right: 6px; font-weight: bold; text-align: center; + will-change: transform; } .ball-container { @@ -45,16 +46,50 @@ } .ball.bonus { - background-color: #d8b4fe; /* Light purple */ + background-color: #d8b4fe; } .ball.matched { - background-color: #4ade80; /* Green */ + background-color: #4ade80 !important; animation: pulse 1s ease-in-out infinite; + color: white !important; + border: 2px solid red !important; } + .ball.game-thunderball { + background-color: #1e3a8a; /* Dark blue */ + color: white; + border: 2px solid white; + border-radius: 12px; /* Remove side rounding */ + } + + /* Lotto main balls – Orange */ + .ball.game-lotto { + background-color: #f97316; /* Bright orange */ + color: white; + border: none; + border-radius: 12px; + } + + /* Optional: Euromillions, Set For Life – define as needed */ + .ball.game-euromillions { + background-color: #2563eb; /* Royal blue */ + color: white; + border-radius: 50%; + } + + .ball.game-setforlife { + background-color: #6b7280; /* Slate gray */ + color: white; + border-radius: 50%; + } @keyframes pulse { 0% { transform: scale(1); } - 50% { transform: scale(1.1); } + 50% { transform: scale(1.15); } 100% { transform: scale(1); } + } + + .pulse { + animation: pulse 0.8s ease-in-out infinite; + transform-origin: center; } \ No newline at end of file diff --git a/templates/account/tickets/my_tickets.html b/templates/account/tickets/my_tickets.html index 91f97de..7a04acd 100644 --- a/templates/account/tickets/my_tickets.html +++ b/templates/account/tickets/my_tickets.html @@ -24,14 +24,16 @@ {{ .DrawDate }}
- {{ range .Balls }} -
{{ . }}
+ {{ range $i, $ball := .Balls }} +
{{ $ball }}
{{ end }}
- -
- MatchedMain: {{ .MatchedMain }} | MatchedBonus: {{ .MatchedBonus }} + {{ if or (gt .MatchedMain 0) (gt .MatchedBonus 0) }} +
+ {{ .MatchedMain }} match{{ if ne .MatchedMain 1 }}es{{ end }} + {{ if gt .MatchedBonus 0 }}, {{ .MatchedBonus }} bonus{{ end }}
+ {{ end }} {{ if eq .GameType "Lotto" }} @@ -39,12 +41,21 @@ {{ else if gt (intVal .Bonus2) 0 }}
{{ if gt (intVal .Bonus1) 0 }} -
{{ intVal .Bonus1 }}
+ {{ $b1 := intVal .Bonus1 }} +
+ {{ $b1 }} +
{{ end }} -
{{ intVal .Bonus2 }}
+ {{ $b2 := intVal .Bonus2 }} +
+ {{ $b2 }} +
{{ else if gt (intVal .Bonus1) 0 }} -
{{ intVal .Bonus1 }}
+ {{ $b := intVal .Bonus1 }} +
+ {{ $b }} +
{{ else }} – {{ end }} diff --git a/templates/layout.html b/templates/layout.html index df53c4d..2e7f27d 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -1,7 +1,7 @@ {{ define "layout" }} - +