raffle service implementation

This commit is contained in:
Asher Samuel 2025-09-03 16:06:01 +03:00
parent 89e3d7de78
commit d78a100f27
50 changed files with 382 additions and 134 deletions

View File

@ -45,6 +45,7 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/messenger" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/messenger"
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notification" notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notification"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/raffle"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation"
referralservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/referal" referralservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/referal"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/report" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/report"
@ -150,6 +151,7 @@ func main() {
recommendationRepo := repository.NewRecommendationRepository(store) recommendationRepo := repository.NewRecommendationRepository(store)
referalSvc := referralservice.New(referalRepo, *walletSvc, store, cfg, logger) referalSvc := referralservice.New(referalRepo, *walletSvc, store, cfg, logger)
raffleSvc := raffle.NewService(store)
virtualGameSvc := virtualgameservice.New(vitualGameRepo, *walletSvc, store, cfg, logger) virtualGameSvc := virtualgameservice.New(vitualGameRepo, *walletSvc, store, cfg, logger)
aleaService := alea.NewAleaPlayService(vitualGameRepo, *walletSvc, cfg, logger) aleaService := alea.NewAleaPlayService(vitualGameRepo, *walletSvc, cfg, logger)
veliCLient := veli.NewClient(cfg, walletSvc) veliCLient := veli.NewClient(cfg, walletSvc)
@ -274,6 +276,7 @@ func main() {
eventSvc, eventSvc,
leagueSvc, leagueSvc,
referalSvc, referalSvc,
raffleSvc,
bonusSvc, bonusSvc,
virtualGameSvc, virtualGameSvc,
aleaService, aleaService,

View File

@ -6,12 +6,10 @@ RETURNING *;
-- name: GetRafflesOfCompany :many -- name: GetRafflesOfCompany :many
SELECT * FROM raffles WHERE company_id = $1; SELECT * FROM raffles WHERE company_id = $1;
-- name: UpdateRaffle :exec -- name: DeleteRaffle :one
UPDATE raffles DELETE FROM raffles
SET name = $1, WHERE id = $1
expires_at = $2, RETURNING *;
status = $3
WHERE id = $4;
-- name: UpdateRaffleTicketStatus :exec -- name: UpdateRaffleTicketStatus :exec
UPDATE raffle_tickets UPDATE raffle_tickets

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: auth.sql // source: auth.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: bet.sql // source: bet.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: bet_stat.sql // source: bet_stat.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: bonus.sql // source: bonus.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: branch.sql // source: branch.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: cashier.sql // source: cashier.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: company.sql // source: company.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: copyfrom.go // source: copyfrom.go
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: direct_deposit.sql // source: direct_deposit.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: disabled_odds.sql // source: disabled_odds.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: event_history.sql // source: event_history.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: events.sql // source: events.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: events_stat.sql // source: events_stat.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: flags.sql // source: flags.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: institutions.sql // source: institutions.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: issue_reporting.sql // source: issue_reporting.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: leagues.sql // source: leagues.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: location.sql // source: location.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: monitor.sql // source: monitor.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: notification.sql // source: notification.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: odd_history.sql // source: odd_history.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: odds.sql // source: odds.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: otp.sql // source: otp.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: raffle.sql // source: raffle.sql
package dbgen package dbgen
@ -67,6 +67,27 @@ func (q *Queries) CreateRaffleTicket(ctx context.Context, arg CreateRaffleTicket
return i, err return i, err
} }
const DeleteRaffle = `-- name: DeleteRaffle :one
DELETE FROM raffles
WHERE id = $1
RETURNING id, company_id, name, created_at, expires_at, type, status
`
func (q *Queries) DeleteRaffle(ctx context.Context, id int32) (Raffle, error) {
row := q.db.QueryRow(ctx, DeleteRaffle, id)
var i Raffle
err := row.Scan(
&i.ID,
&i.CompanyID,
&i.Name,
&i.CreatedAt,
&i.ExpiresAt,
&i.Type,
&i.Status,
)
return i, err
}
const GetRafflesOfCompany = `-- name: GetRafflesOfCompany :many const GetRafflesOfCompany = `-- name: GetRafflesOfCompany :many
SELECT id, company_id, name, created_at, expires_at, type, status FROM raffles WHERE company_id = $1 SELECT id, company_id, name, created_at, expires_at, type, status FROM raffles WHERE company_id = $1
` `
@ -148,31 +169,6 @@ func (q *Queries) GetUserRaffleTickets(ctx context.Context, userID int32) ([]Get
return items, nil return items, nil
} }
const UpdateRaffle = `-- name: UpdateRaffle :exec
UPDATE raffles
SET name = $1,
expires_at = $2,
status = $3
WHERE id = $4
`
type UpdateRaffleParams struct {
Name string `json:"name"`
ExpiresAt pgtype.Timestamp `json:"expires_at"`
Status string `json:"status"`
ID int32 `json:"id"`
}
func (q *Queries) UpdateRaffle(ctx context.Context, arg UpdateRaffleParams) error {
_, err := q.db.Exec(ctx, UpdateRaffle,
arg.Name,
arg.ExpiresAt,
arg.Status,
arg.ID,
)
return err
}
const UpdateRaffleTicketStatus = `-- name: UpdateRaffleTicketStatus :exec const UpdateRaffleTicketStatus = `-- name: UpdateRaffleTicketStatus :exec
UPDATE raffle_tickets UPDATE raffle_tickets
SET is_active = $1 SET is_active = $1

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: referal.sql // source: referal.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: report.sql // source: report.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: result.sql // source: result.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: result_log.sql // source: result_log.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: settings.sql // source: settings.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: shop_transactions.sql // source: shop_transactions.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: ticket.sql // source: ticket.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: transfer.sql // source: transfer.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: user.sql // source: user.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: virtual_games.sql // source: virtual_games.sql
package dbgen package dbgen

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.29.0 // sqlc v1.30.0
// source: wallet.sql // source: wallet.sql
package dbgen package dbgen

View File

@ -29,8 +29,20 @@ type RaffleTicketRes struct {
} }
type CreateRaffle struct { type CreateRaffle struct {
CompanyID int32 CompanyID int32 `json:"company_id" validate:"required"`
Name string Name string `json:"name" validate:"required"`
ExpiresAt time.Time ExpiresAt *time.Time `json:"expires_at" validate:"required"`
Type string Type string `json:"type" validate:"required"`
}
type CreateRaffleTicket struct {
RaffleID int32 `json:"raffle_id" validate:"required"`
UserID int32 `json:"user_id" validate:"required"`
}
// aside from ID, atleast one of the fields should be required
type UpdateRaffleParams struct {
ID int32 `json:"id" validate:"required"`
Name string `json:"name" validate:"required_without_all=ExpiresAt"`
ExpiresAt *time.Time `json:"expires_at" validate:"required_without_all=Name"`
} }

View File

@ -45,7 +45,7 @@ func convertCreateRaffle(raffle domain.CreateRaffle) dbgen.CreateRaffleParams {
CompanyID: raffle.CompanyID, CompanyID: raffle.CompanyID,
Name: raffle.Name, Name: raffle.Name,
ExpiresAt: pgtype.Timestamp{ ExpiresAt: pgtype.Timestamp{
Time: raffle.ExpiresAt, Time: *raffle.ExpiresAt,
Valid: true, Valid: true,
}, },
Type: raffle.Type, Type: raffle.Type,
@ -61,6 +61,15 @@ func (s *Store) CreateRaffle(ctx context.Context, raffle domain.CreateRaffle) (d
return convertRaffleOutcome(raffleRes), nil return convertRaffleOutcome(raffleRes), nil
} }
func (s *Store) DeleteRaffle(ctx context.Context, raffleID int32) (domain.Raffle, error) {
raffleRes, err := s.queries.DeleteRaffle(ctx, raffleID)
if err != nil {
return domain.Raffle{}, err
}
return convertRaffleOutcome(raffleRes), nil
}
func (s *Store) GetRafflesOfCompany(ctx context.Context, companyID int32) ([]dbgen.Raffle, error) { func (s *Store) GetRafflesOfCompany(ctx context.Context, companyID int32) ([]dbgen.Raffle, error) {
raffles, err := s.queries.GetRafflesOfCompany(ctx, companyID) raffles, err := s.queries.GetRafflesOfCompany(ctx, companyID)
if err != nil { if err != nil {
@ -70,36 +79,10 @@ func (s *Store) GetRafflesOfCompany(ctx context.Context, companyID int32) ([]dbg
return raffles, nil return raffles, nil
} }
func (s *Store) UpdateRaffle(ctx context.Context, raffleParams dbgen.UpdateRaffleParams) error { func (s *Store) CreateRaffleTicket(ctx context.Context, raffleTicketParams domain.CreateRaffleTicket) (domain.RaffleTicket, error) {
return s.queries.UpdateRaffle(ctx, raffleParams)
}
func (s *Store) SuspendRaffleTicket(ctx context.Context, raffleID int32) error {
return s.queries.UpdateRaffleTicketStatus(ctx, dbgen.UpdateRaffleTicketStatusParams{
ID: raffleID,
IsActive: pgtype.Bool{
Bool: false,
Valid: true,
},
})
}
func (s *Store) UnSuspendRaffleTicket(ctx context.Context, raffleID int32) error {
return s.queries.UpdateRaffleTicketStatus(ctx, dbgen.UpdateRaffleTicketStatusParams{
ID: raffleID,
IsActive: pgtype.Bool{
Bool: true,
Valid: true,
},
})
}
// TODO: could also add -> suspend a specific user's raffle tickets
func (s *Store) CreateRaffleTicket(ctx context.Context, raffleID, userID int32) (domain.RaffleTicket, error) {
raffleTicket, err := s.queries.CreateRaffleTicket(ctx, dbgen.CreateRaffleTicketParams{ raffleTicket, err := s.queries.CreateRaffleTicket(ctx, dbgen.CreateRaffleTicketParams{
RaffleID: raffleID, RaffleID: raffleTicketParams.RaffleID,
UserID: userID, UserID: raffleTicketParams.UserID,
}) })
if err != nil { if err != nil {
return domain.RaffleTicket{}, err return domain.RaffleTicket{}, err
@ -121,3 +104,25 @@ func (s *Store) GetUserRaffleTickets(ctx context.Context, userID int32) ([]domai
return res, nil return res, nil
} }
func (s *Store) SuspendRaffleTicket(ctx context.Context, raffleTicketID int32) error {
return s.queries.UpdateRaffleTicketStatus(ctx, dbgen.UpdateRaffleTicketStatusParams{
ID: raffleTicketID,
IsActive: pgtype.Bool{
Bool: false,
Valid: true,
},
})
}
func (s *Store) UnSuspendRaffleTicket(ctx context.Context, raffleID int32) error {
return s.queries.UpdateRaffleTicketStatus(ctx, dbgen.UpdateRaffleTicketStatusParams{
ID: raffleID,
IsActive: pgtype.Bool{
Bool: true,
Valid: true,
},
})
}
// TODO: could also add -> suspend a specific user's raffle tickets

View File

@ -168,6 +168,6 @@ func (s *Store) DeleteCompanySetting(ctx context.Context, companyID int64, key s
Key: key, Key: key,
}) })
} }
func (s *Store) DeleteAllCompanySetting(ctx context.Context, companyID int64,) error { func (s *Store) DeleteAllCompanySetting(ctx context.Context, companyID int64) error {
return s.queries.DeleteAllCompanySetting(ctx, companyID) return s.queries.DeleteAllCompanySetting(ctx, companyID)
} }

View File

@ -9,10 +9,10 @@ import (
type RaffleStore interface { type RaffleStore interface {
CreateRaffle(ctx context.Context, raffle domain.CreateRaffle) (domain.Raffle, error) CreateRaffle(ctx context.Context, raffle domain.CreateRaffle) (domain.Raffle, error)
DeleteRaffle(ctx context.Context, raffleID int32) (domain.Raffle, error)
GetRafflesOfCompany(ctx context.Context, companyID int32) ([]dbgen.Raffle, error) GetRafflesOfCompany(ctx context.Context, companyID int32) ([]dbgen.Raffle, error)
UpdateRaffle(ctx context.Context, raffleParams dbgen.UpdateRaffleParams) error CreateRaffleTicket(ctx context.Context, raffleTicketParams domain.CreateRaffleTicket) (domain.RaffleTicket, error)
SuspendRaffleTicket(ctx context.Context, raffleID int32) error
UnSuspendRaffleTicket(ctx context.Context, raffleID int32) error
CreateRaffleTicket(ctx context.Context, raffleID, userID int32) (domain.RaffleTicket, error)
GetUserRaffleTickets(ctx context.Context, userID int32) ([]domain.RaffleTicketRes, error) GetUserRaffleTickets(ctx context.Context, userID int32) ([]domain.RaffleTicketRes, error)
SuspendRaffleTicket(ctx context.Context, raffleTicketID int32) error
UnSuspendRaffleTicket(ctx context.Context, raffleID int32) error
} }

View File

@ -21,25 +21,26 @@ func (s *Service) CreateRaffle(ctx context.Context, raffle domain.CreateRaffle)
return s.raffleStore.CreateRaffle(ctx, raffle) return s.raffleStore.CreateRaffle(ctx, raffle)
} }
func (s *Service) DeleteRaffle(ctx context.Context, raffleID int32) (domain.Raffle, error) {
return s.raffleStore.DeleteRaffle(ctx, raffleID)
}
func (s *Service) GetRafflesOfCompany(ctx context.Context, companyID int32) ([]dbgen.Raffle, error) { func (s *Service) GetRafflesOfCompany(ctx context.Context, companyID int32) ([]dbgen.Raffle, error) {
return s.GetRafflesOfCompany(ctx, companyID) return s.raffleStore.GetRafflesOfCompany(ctx, companyID)
}
func (s *Service) UpdateRaffle(ctx context.Context, raffleParams dbgen.UpdateRaffleParams) error {
return s.raffleStore.UpdateRaffle(ctx, raffleParams)
} }
func (s *Service) SuspendRaffleTicket(ctx context.Context, raffleID int32) error { func (s *Service) CreateRaffleTicket(ctx context.Context, raffleTicketParams domain.CreateRaffleTicket) (domain.RaffleTicket, error) {
return s.raffleStore.SuspendRaffleTicket(ctx, raffleID) return s.raffleStore.CreateRaffleTicket(ctx, raffleTicketParams)
}
func (s *Service) UnSuspendRaffleTicket(ctx context.Context, raffleID int32) error {
return s.raffleStore.UnSuspendRaffleTicket(ctx, raffleID)
}
func (s *Service) CreateRaffleTicket(ctx context.Context, raffleID, userID int32) (domain.RaffleTicket, error) {
return s.raffleStore.CreateRaffleTicket(ctx, raffleID, userID)
} }
func (s *Service) GetUserRaffleTickets(ctx context.Context, userID int32) ([]domain.RaffleTicketRes, error) { func (s *Service) GetUserRaffleTickets(ctx context.Context, userID int32) ([]domain.RaffleTicketRes, error) {
return s.raffleStore.GetUserRaffleTickets(ctx, userID) return s.raffleStore.GetUserRaffleTickets(ctx, userID)
} }
func (s *Service) SuspendRaffleTicket(ctx context.Context, raffleTicketID int32) error {
return s.raffleStore.SuspendRaffleTicket(ctx, raffleTicketID)
}
func (s *Service) UnSuspendRaffleTicket(ctx context.Context, raffleID int32) error {
return s.raffleStore.UnSuspendRaffleTicket(ctx, raffleID)
}

View File

@ -18,6 +18,7 @@ import (
issuereporting "github.com/SamuelTariku/FortuneBet-Backend/internal/services/issue_reporting" issuereporting "github.com/SamuelTariku/FortuneBet-Backend/internal/services/issue_reporting"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/league" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/league"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/raffle"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation"
referralservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/referal" referralservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/referal"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/report" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/report"
@ -57,6 +58,7 @@ type App struct {
logger *slog.Logger logger *slog.Logger
NotidicationStore *notificationservice.Service NotidicationStore *notificationservice.Service
referralSvc referralservice.ReferralStore referralSvc referralservice.ReferralStore
raffleSvc raffle.RaffleStore
bonusSvc *bonus.Service bonusSvc *bonus.Service
port int port int
settingSvc *settings.Service settingSvc *settings.Service
@ -108,6 +110,7 @@ func NewApp(
eventSvc event.Service, eventSvc event.Service,
leagueSvc league.Service, leagueSvc league.Service,
referralSvc referralservice.ReferralStore, referralSvc referralservice.ReferralStore,
raffleSvc raffle.RaffleStore,
bonusSvc *bonus.Service, bonusSvc *bonus.Service,
virtualGameSvc virtualgameservice.VirtualGameService, virtualGameSvc virtualgameservice.VirtualGameService,
aleaVirtualGameService alea.AleaVirtualGameService, aleaVirtualGameService alea.AleaVirtualGameService,
@ -158,6 +161,7 @@ func NewApp(
companySvc: companySvc, companySvc: companySvc,
NotidicationStore: notidicationStore, NotidicationStore: notidicationStore,
referralSvc: referralSvc, referralSvc: referralSvc,
raffleSvc: raffleSvc,
bonusSvc: bonusSvc, bonusSvc: bonusSvc,
Logger: logger, Logger: logger,
prematchSvc: prematchSvc, prematchSvc: prematchSvc,

View File

@ -254,8 +254,6 @@ func SetupReportandVirtualGameCronJobs(
log.Printf("Cron jobs started. Reports will be saved to: %s", outputDir) log.Printf("Cron jobs started. Reports will be saved to: %s", outputDir)
} }
func ProcessBetCashback(ctx context.Context, betService *betSvc.Service) { func ProcessBetCashback(ctx context.Context, betService *betSvc.Service) {
c := cron.New(cron.WithSeconds()) c := cron.New(cron.WithSeconds())

View File

@ -224,6 +224,8 @@ func (h *Handler) CreateBetInternal(c *fiber.Ctx, req domain.CreateBetReq, userI
return domain.CreateBetRes{}, err return domain.CreateBetRes{}, err
} }
// create raffle ticket here
return res, nil return res, nil
} }

View File

@ -18,6 +18,7 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/league" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/league"
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notification" notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notification"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/raffle"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation"
referralservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/referal" referralservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/referal"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/report" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/report"
@ -49,6 +50,7 @@ type Handler struct {
notificationSvc *notificationservice.Service notificationSvc *notificationservice.Service
userSvc *user.Service userSvc *user.Service
referralSvc referralservice.ReferralStore referralSvc referralservice.ReferralStore
raffleSvc raffle.RaffleStore
bonusSvc *bonus.Service bonusSvc *bonus.Service
reportSvc report.ReportStore reportSvc report.ReportStore
chapaSvc *chapa.Service chapaSvc *chapa.Service
@ -88,6 +90,7 @@ func New(
chapaSvc *chapa.Service, chapaSvc *chapa.Service,
walletSvc *wallet.Service, walletSvc *wallet.Service,
referralSvc referralservice.ReferralStore, referralSvc referralservice.ReferralStore,
raffleSvc raffle.RaffleStore,
bonusSvc *bonus.Service, bonusSvc *bonus.Service,
virtualGameSvc virtualgameservice.VirtualGameService, virtualGameSvc virtualgameservice.VirtualGameService,
aleaVirtualGameSvc alea.AleaVirtualGameService, aleaVirtualGameSvc alea.AleaVirtualGameService,
@ -122,6 +125,7 @@ func New(
chapaSvc: chapaSvc, chapaSvc: chapaSvc,
walletSvc: walletSvc, walletSvc: walletSvc,
referralSvc: referralSvc, referralSvc: referralSvc,
raffleSvc: raffleSvc,
bonusSvc: bonusSvc, bonusSvc: bonusSvc,
validator: validator, validator: validator,
userSvc: userSvc, userSvc: userSvc,

View File

@ -0,0 +1,216 @@
package handlers
import (
"fmt"
"strconv"
"time"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
)
func (h *Handler) CreateRaffle(c *fiber.Ctx) error {
var req domain.CreateRaffle
if err := c.BodyParser(&req); err != nil {
h.mongoLoggerSvc.Info("Failed to parse raffle request",
zap.Int("status_code", fiber.StatusBadRequest),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusBadRequest, "Invalid request body")
}
if valErrs, ok := h.validator.Validate(c, req); !ok {
var errMsg string
for field, msg := range valErrs {
errMsg += fmt.Sprintf("%s: %s; ", field, msg)
}
h.mongoLoggerSvc.Info("Failed to validate settings",
zap.String("errMsg", errMsg),
zap.Int("status_code", fiber.StatusBadRequest),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusBadRequest, errMsg)
}
raffle, err := h.raffleSvc.CreateRaffle(c.Context(), req)
if err != nil {
h.mongoLoggerSvc.Error("Failed to create raffle",
zap.Int("status_code", fiber.StatusInternalServerError),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create raffle")
}
return response.WriteJSON(c, fiber.StatusOK, "Raffle created successfully", raffle, nil)
}
func (h *Handler) DeleteRaffle(c *fiber.Ctx) error {
stringRaffleID := c.Params("id")
raffleID, err := strconv.Atoi(stringRaffleID)
if err != nil {
h.mongoLoggerSvc.Info("failed to parse raffle id",
zap.String("stringRaffleID", stringRaffleID),
zap.Int("status_code", fiber.StatusBadRequest),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusBadRequest, "Invalid raffle id")
}
raffle, err := h.raffleSvc.DeleteRaffle(c.Context(), int32(raffleID))
if err != nil {
fmt.Println("raffle delete error: ", err)
h.mongoLoggerSvc.Error("Failed to delete raffle",
zap.Int("status_code", fiber.StatusInternalServerError),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to delete raffle")
}
return response.WriteJSON(c, fiber.StatusOK, "Raffle deleted successfully", raffle, nil)
}
func (h *Handler) GetRafflesOfCompany(c *fiber.Ctx) error {
stringCompanyID := c.Params("id")
companyID, err := strconv.Atoi(stringCompanyID)
if err != nil || companyID == 0 {
h.mongoLoggerSvc.Info("failed to parse company id",
zap.String("stringCompanyID", stringCompanyID),
zap.Int("status_code", fiber.StatusBadRequest),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusBadRequest, "Invalid company ID")
}
companyRaffles, err := h.raffleSvc.GetRafflesOfCompany(c.Context(), int32(companyID))
if err != nil {
h.mongoLoggerSvc.Error("Failed to fetch company raffle",
zap.Int("status_code", fiber.StatusInternalServerError),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch company raffle")
}
return response.WriteJSON(c, fiber.StatusOK, "Company Raffles fetched successfully", companyRaffles, nil)
}
func (h *Handler) CreateRaffleTicket(c *fiber.Ctx) error {
var req domain.CreateRaffleTicket
if err := c.BodyParser(&req); err != nil {
h.mongoLoggerSvc.Info("Failed to parse raffle ticket request",
zap.Int("status_code", fiber.StatusBadRequest),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusBadRequest, "Invalid request body")
}
if valErrs, ok := h.validator.Validate(c, req); !ok {
var errMsg string
for field, msg := range valErrs {
errMsg += fmt.Sprintf("%s: %s; ", field, msg)
}
h.mongoLoggerSvc.Info("Failed to validate settings",
zap.String("errMsg", errMsg),
zap.Int("status_code", fiber.StatusBadRequest),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusBadRequest, errMsg)
}
raffleTicket, err := h.raffleSvc.CreateRaffleTicket(c.Context(), req)
if err != nil {
h.mongoLoggerSvc.Error("Failed to create raffle ticket",
zap.Int("status_code", fiber.StatusInternalServerError),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create raffle ticket")
}
return response.WriteJSON(c, fiber.StatusOK, "Raffle created successfully", raffleTicket, nil)
}
func (h *Handler) GetUserRaffleTickets(c *fiber.Ctx) error {
stringUserID := c.Params("id")
userID, err := strconv.Atoi(stringUserID)
if err != nil {
h.mongoLoggerSvc.Info("failed to parse company id",
zap.String("stringUserID", stringUserID),
zap.Int("status_code", fiber.StatusBadRequest),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusBadRequest, "Invalid user ID")
}
raffleTickets, err := h.raffleSvc.GetUserRaffleTickets(c.Context(), int32(userID))
if err != nil {
h.mongoLoggerSvc.Error("Failed to fetch user raffle tickets",
zap.Int("status_code", fiber.StatusInternalServerError),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch user raffle tickets")
}
return response.WriteJSON(c, fiber.StatusOK, "User raffle tickets fetched successfully", raffleTickets, nil)
}
func (h *Handler) SuspendRaffleTicket(c *fiber.Ctx) error {
stringRaffleTicketID := c.Params("id")
raffleTicketID, err := strconv.Atoi(stringRaffleTicketID)
if err != nil {
h.mongoLoggerSvc.Info("failed to parse raffle ticket id",
zap.String("stringUserID", stringRaffleTicketID),
zap.Int("status_code", fiber.StatusBadRequest),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusBadRequest, "Invalid raffel ticket id")
}
if err := h.raffleSvc.SuspendRaffleTicket(c.Context(), int32(raffleTicketID)); err != nil {
h.mongoLoggerSvc.Error("Failed to suspend raffle ticket",
zap.Int("status_code", fiber.StatusInternalServerError),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to suspend raffle ticket")
}
return response.WriteJSON(c, fiber.StatusOK, "User raffle tickets suspended successfully", nil, nil)
}
func (h *Handler) UnSuspendRaffleTicket(c *fiber.Ctx) error {
stringRaffleTicketID := c.Params("id")
raffleTicketID, err := strconv.Atoi(stringRaffleTicketID)
if err != nil {
h.mongoLoggerSvc.Info("failed to parse raffle ticket id",
zap.String("stringUserID", stringRaffleTicketID),
zap.Int("status_code", fiber.StatusBadRequest),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusBadRequest, "Invalid raffel ticket id")
}
if err := h.raffleSvc.UnSuspendRaffleTicket(c.Context(), int32(raffleTicketID)); err != nil {
h.mongoLoggerSvc.Error("Failed to unsuspend raffle ticket",
zap.Int("status_code", fiber.StatusInternalServerError),
zap.Error(err),
zap.Time("timestamp", time.Now()),
)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to unsuspend raffle ticket")
}
return response.WriteJSON(c, fiber.StatusOK, "User raffle tickets unsuspended successfully", nil, nil)
}

View File

@ -34,6 +34,7 @@ func (a *App) initAppRoutes() {
a.chapaSvc, a.chapaSvc,
a.walletSvc, a.walletSvc,
a.referralSvc, a.referralSvc,
a.raffleSvc,
a.bonusSvc, a.bonusSvc,
a.virtualGameSvc, a.virtualGameSvc,
a.aleaVirtualGameService, a.aleaVirtualGameService,
@ -163,6 +164,15 @@ func (a *App) initAppRoutes() {
groupV1.Get("/referral/settings", a.authMiddleware, h.GetReferralSettings) groupV1.Get("/referral/settings", a.authMiddleware, h.GetReferralSettings)
groupV1.Patch("/referral/settings", a.authMiddleware, h.UpdateReferralSettings) groupV1.Patch("/referral/settings", a.authMiddleware, h.UpdateReferralSettings)
// Raffle Routes
a.fiber.Post("/raffle/create", a.authMiddleware, h.CreateRaffle)
a.fiber.Get("/raffle/delete/:id", a.authMiddleware, h.DeleteRaffle)
a.fiber.Get("/raffle/company/:id", a.authMiddleware, h.GetRafflesOfCompany)
a.fiber.Post("/raffle-ticket/create", a.authMiddleware, h.CreateRaffleTicket)
a.fiber.Get("/raffle-ticket/:id", a.authMiddleware, h.GetUserRaffleTickets)
a.fiber.Get("/raffle-ticket/suspend/:id", a.authMiddleware, h.SuspendRaffleTicket)
a.fiber.Get("/raffle-ticket/unsuspend/:id", a.authMiddleware, h.UnSuspendRaffleTicket)
// Bonus Routes // Bonus Routes
groupV1.Get("/bonus", a.authMiddleware, h.GetBonusMultiplier) groupV1.Get("/bonus", a.authMiddleware, h.GetBonusMultiplier)
groupV1.Post("/bonus/create", a.authMiddleware, h.CreateBonusMultiplier) groupV1.Post("/bonus/create", a.authMiddleware, h.CreateBonusMultiplier)
@ -254,7 +264,6 @@ func (a *App) initAppRoutes() {
tenant.Get("/ticket/:id", h.GetTicketByID) tenant.Get("/ticket/:id", h.GetTicketByID)
// Bet Routes // Bet Routes
tenantAuth.Post("/sport/bet", h.CreateBet)
tenantAuth.Post("/sport/bet/fastcode", h.CreateBetWithFastCode) tenantAuth.Post("/sport/bet/fastcode", h.CreateBetWithFastCode)
tenant.Get("/sport/bet/fastcode/:fast_code", h.GetBetByFastCode) tenant.Get("/sport/bet/fastcode/:fast_code", h.GetBetByFastCode)
tenantAuth.Get("/sport/bet", h.GetAllBet) tenantAuth.Get("/sport/bet", h.GetAllBet)