diff --git a/db/query/events.sql b/db/query/events.sql index ba80192..c5ec974 100644 --- a/db/query/events.sql +++ b/db/query/events.sql @@ -276,6 +276,9 @@ WHERE e.id = $1 AND is_live = false AND status = 'upcoming' LIMIT 1; +-- name: GetSportAndLeagueIDs :one +SELECT sport_id, league_id FROM events +WHERE id = $1; -- name: UpdateMatchResult :exec UPDATE events SET score = $1, @@ -291,4 +294,4 @@ SET is_monitored = $1 WHERE id = $2; -- name: DeleteEvent :exec DELETE FROM events -WHERE id = $1; \ No newline at end of file +WHERE id = $1; diff --git a/db/query/raffle.sql b/db/query/raffle.sql index fecb50d..55f302c 100644 --- a/db/query/raffle.sql +++ b/db/query/raffle.sql @@ -64,3 +64,10 @@ WHERE id = $1; INSERT INTO raffle_sport_filters (raffle_id, sport_id, league_id) VALUES ($1, $2, $3) RETURNING *; + +-- name: CheckValidSportRaffleFilter :one +SELECT COUNT(*) > 0 AS exists +FROM raffle_sport_filters +WHERE raffle_id = $1 + AND sport_id = $2 + AND league_id = $3; diff --git a/gen/db/events.sql.go b/gen/db/events.sql.go index 73f929a..9c9afe7 100644 --- a/gen/db/events.sql.go +++ b/gen/db/events.sql.go @@ -505,6 +505,23 @@ func (q *Queries) GetPaginatedUpcomingEvents(ctx context.Context, arg GetPaginat return items, nil } +const GetSportAndLeagueIDs = `-- name: GetSportAndLeagueIDs :one +SELECT sport_id, league_id FROM events +WHERE id = $1 +` + +type GetSportAndLeagueIDsRow struct { + SportID int32 `json:"sport_id"` + LeagueID int64 `json:"league_id"` +} + +func (q *Queries) GetSportAndLeagueIDs(ctx context.Context, id string) (GetSportAndLeagueIDsRow, error) { + row := q.db.QueryRow(ctx, GetSportAndLeagueIDs, id) + var i GetSportAndLeagueIDsRow + err := row.Scan(&i.SportID, &i.LeagueID) + return i, err +} + const GetTotalCompanyEvents = `-- name: GetTotalCompanyEvents :one SELECT COUNT(*) FROM events e diff --git a/gen/db/raffle.sql.go b/gen/db/raffle.sql.go index 8aa8b34..a4888f9 100644 --- a/gen/db/raffle.sql.go +++ b/gen/db/raffle.sql.go @@ -35,6 +35,27 @@ func (q *Queries) AddSportRaffleFilter(ctx context.Context, arg AddSportRaffleFi return i, err } +const CheckValidSportRaffleFilter = `-- name: CheckValidSportRaffleFilter :one +SELECT COUNT(*) > 0 AS exists +FROM raffle_sport_filters +WHERE raffle_id = $1 + AND sport_id = $2 + AND league_id = $3 +` + +type CheckValidSportRaffleFilterParams struct { + RaffleID int32 `json:"raffle_id"` + SportID int64 `json:"sport_id"` + LeagueID int64 `json:"league_id"` +} + +func (q *Queries) CheckValidSportRaffleFilter(ctx context.Context, arg CheckValidSportRaffleFilterParams) (bool, error) { + row := q.db.QueryRow(ctx, CheckValidSportRaffleFilter, arg.RaffleID, arg.SportID, arg.LeagueID) + var exists bool + err := row.Scan(&exists) + return exists, err +} + const CreateRaffle = `-- name: CreateRaffle :one INSERT INTO raffles (company_id, name, expires_at, type) VALUES ($1, $2, $3, $4) diff --git a/internal/repository/event.go b/internal/repository/event.go index 9602796..8b4e87e 100644 --- a/internal/repository/event.go +++ b/internal/repository/event.go @@ -290,3 +290,13 @@ func (s *Store) DeleteEvent(ctx context.Context, eventID string) error { } return nil } + +func (s *Store) GetSportAndLeagueIDs(ctx context.Context, eventID string) ([]int64, error) { + sportAndLeagueIDs, err := s.queries.GetSportAndLeagueIDs(ctx, eventID) + if err != nil { + return nil, err + } + + res := []int64{int64(sportAndLeagueIDs.SportID), sportAndLeagueIDs.LeagueID} + return res, err +} diff --git a/internal/repository/raffel.go b/internal/repository/raffel.go index 02631f9..6e37013 100644 --- a/internal/repository/raffel.go +++ b/internal/repository/raffel.go @@ -178,3 +178,16 @@ func (s *Store) AddSportRaffleFilter(ctx context.Context, raffleID int32, sportI }) return err } + +func (s *Store) CheckValidSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) (bool, error) { + res, err := s.queries.CheckValidSportRaffleFilter(ctx, dbgen.CheckValidSportRaffleFilterParams{ + RaffleID: raffleID, + SportID: sportID, + LeagueID: leagueID, + }) + if err != nil { + return false, err + } + + return res, nil +} diff --git a/internal/services/event/port.go b/internal/services/event/port.go index e02be83..74305f9 100644 --- a/internal/services/event/port.go +++ b/internal/services/event/port.go @@ -19,6 +19,7 @@ type Service interface { IsEventMonitored(ctx context.Context, eventID string) (bool, error) UpdateEventMonitored(ctx context.Context, eventID string, IsMonitored bool) error GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error) - GetEventWithSettingByID(ctx context.Context, ID string, companyID int64) (domain.EventWithSettings, error) + GetEventWithSettingByID(ctx context.Context, ID string, companyID int64) (domain.EventWithSettings, error) UpdateEventSettings(ctx context.Context, event domain.CreateEventSettings) error + GetSportAndLeagueIDs(ctx context.Context, eventID string) ([]int64, error) } diff --git a/internal/services/event/service.go b/internal/services/event/service.go index 13f9897..76755c1 100644 --- a/internal/services/event/service.go +++ b/internal/services/event/service.go @@ -223,7 +223,7 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur var pageLimit int var sportIDs []int - + // Restricting the page to 1 on development, which drastically reduces the amount of events that is fetched if s.cfg.Env == "development" { pageLimit = 1 @@ -507,6 +507,11 @@ func (s *service) GetEventsWithSettings(ctx context.Context, companyID int64, fi func (s *service) GetEventWithSettingByID(ctx context.Context, ID string, companyID int64) (domain.EventWithSettings, error) { return s.store.GetEventWithSettingByID(ctx, ID, companyID) } + func (s *service) UpdateEventSettings(ctx context.Context, event domain.CreateEventSettings) error { return s.store.UpdateEventSettings(ctx, event) } + +func (s *service) GetSportAndLeagueIDs(ctx context.Context, eventID string) ([]int64, error) { + return s.store.GetSportAndLeagueIDs(ctx, eventID) +} diff --git a/internal/services/raffle/port.go b/internal/services/raffle/port.go index 198b844..39f5bfa 100644 --- a/internal/services/raffle/port.go +++ b/internal/services/raffle/port.go @@ -15,6 +15,7 @@ type RaffleStore interface { GetRaffleStanding(ctx context.Context, raffleID, limit int32) ([]domain.RaffleStanding, error) CreateRaffleWinner(ctx context.Context, raffleWinnerParams domain.RaffleWinnerParams) error SetRaffleComplete(ctx context.Context, raffleID int32) error + CheckValidSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) (bool, error) CreateRaffleTicket(ctx context.Context, raffleTicketParams domain.CreateRaffleTicket) (domain.RaffleTicket, error) GetUserRaffleTickets(ctx context.Context, userID int32) ([]domain.RaffleTicketRes, error) diff --git a/internal/services/raffle/service.go b/internal/services/raffle/service.go index 651534e..017d164 100644 --- a/internal/services/raffle/service.go +++ b/internal/services/raffle/service.go @@ -60,3 +60,7 @@ func (s *Service) SuspendRaffleTicket(ctx context.Context, raffleTicketID int32) func (s *Service) UnSuspendRaffleTicket(ctx context.Context, raffleID int32) error { return s.raffleStore.UnSuspendRaffleTicket(ctx, raffleID) } + +func (s *Service) CheckValidSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) (bool, error) { + return s.raffleStore.CheckValidSportRaffleFilter(ctx, raffleID, sportID, leagueID) +} diff --git a/internal/web_server/handlers/bet_handler.go b/internal/web_server/handlers/bet_handler.go index cfe6343..c090de3 100644 --- a/internal/web_server/handlers/bet_handler.go +++ b/internal/web_server/handlers/bet_handler.go @@ -249,12 +249,41 @@ func (h *Handler) CreateBetInternal(c *fiber.Ctx, req domain.CreateBetReq, userI ) } + sportAndLeagueIDs := [][]int64{} + for _, outcome := range req.Outcomes { + ids, err := h.eventSvc.GetSportAndLeagueIDs(c.Context(), fmt.Sprintf("%d", outcome.EventID)) + if err != nil { + continue + } + + sportAndLeagueIDs = append(sportAndLeagueIDs, ids) + } + + fmt.Println("sportAndLeagueIDs: ", sportAndLeagueIDs) + for _, raffle := range raffles { // TODO: only fetch pending raffles from db if raffle.Status == "completed" { continue } + // only require one sport and league combo to be valide to make the raffle ticket + foundValid := false + for _, sportAndLeagueID := range sportAndLeagueIDs { + res, err := h.raffleSvc.CheckValidSportRaffleFilter(c.Context(), raffle.ID, sportAndLeagueID[0], sportAndLeagueID[1]) + if err != nil { + continue + } + + fmt.Println(sportAndLeagueID, res) + + foundValid = foundValid || res + } + + if !foundValid { + continue + } + raffleTicket := domain.CreateRaffleTicket{ RaffleID: raffle.ID, UserID: int32(userID),