diff --git a/db/migrations/000001_fortune.up.sql b/db/migrations/000001_fortune.up.sql index 17b5e49..97562cb 100644 --- a/db/migrations/000001_fortune.up.sql +++ b/db/migrations/000001_fortune.up.sql @@ -47,6 +47,7 @@ CREATE TABLE IF NOT EXISTS bets ( status INT NOT NULL, full_name VARCHAR(255) NOT NULL, phone_number VARCHAR(255) NOT NULL, + company_id BIGINT, branch_id BIGINT, user_id BIGINT, cashed_out BOOLEAN DEFAULT FALSE NOT NULL, @@ -341,7 +342,8 @@ INSERT INTO users ( created_at, updated_at, suspended_at, - suspended + suspended, + company_id ) VALUES ( 'Test', @@ -355,7 +357,8 @@ VALUES ( CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, - FALSE + FALSE, + 1 ); INSERT INTO users ( first_name, diff --git a/db/query/bet.sql b/db/query/bet.sql index 7d3eab5..335cf56 100644 --- a/db/query/bet.sql +++ b/db/query/bet.sql @@ -8,9 +8,10 @@ INSERT INTO bets ( branch_id, user_id, is_shop_bet, - cashout_id + cashout_id, + company_id ) -VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING *; -- name: CreateBetOutcome :copyfrom INSERT INTO bet_outcomes ( @@ -45,7 +46,19 @@ VALUES ( ); -- name: GetAllBets :many SELECT * -FROM bet_with_outcomes; +FROM bet_with_outcomes +wHERE ( + branch_id = $1 + OR $1 IS NULL + ) + AND ( + company_id = $2 + OR $2 IS NULL + ) + AND ( + user_id = $3 + OR $3 IS NULL + ); -- name: GetBetByID :one SELECT * FROM bet_with_outcomes diff --git a/db/query/transactions.sql b/db/query/transactions.sql index 83e8787..e63d5a9 100644 --- a/db/query/transactions.sql +++ b/db/query/transactions.sql @@ -42,7 +42,19 @@ VALUES ( RETURNING *; -- name: GetAllTransactions :many SELECT * -FROM transactions; +FROM transactions +wHERE ( + branch_id = sqlc.narg('branch_id') + OR sqlc.narg('branch_id') IS NULL + ) + AND ( + company_id = sqlc.narg('company_id') + OR sqlc.narg('company_id') IS NULL + ) + AND ( + cashier_id = sqlc.narg('cashier_id') + OR sqlc.narg('cashier_id') IS NULL + ); -- name: GetTransactionByID :one SELECT * FROM transactions diff --git a/gen/db/bet.sql.go b/gen/db/bet.sql.go index 3857c40..40182ae 100644 --- a/gen/db/bet.sql.go +++ b/gen/db/bet.sql.go @@ -21,10 +21,11 @@ INSERT INTO bets ( branch_id, user_id, is_shop_bet, - cashout_id + cashout_id, + company_id ) -VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) -RETURNING id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) +RETURNING id, amount, total_odds, status, full_name, phone_number, company_id, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet ` type CreateBetParams struct { @@ -37,6 +38,7 @@ type CreateBetParams struct { UserID pgtype.Int8 `json:"user_id"` IsShopBet bool `json:"is_shop_bet"` CashoutID string `json:"cashout_id"` + CompanyID pgtype.Int8 `json:"company_id"` } func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, error) { @@ -50,6 +52,7 @@ func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, erro arg.UserID, arg.IsShopBet, arg.CashoutID, + arg.CompanyID, ) var i Bet err := row.Scan( @@ -59,6 +62,7 @@ func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, erro &i.Status, &i.FullName, &i.PhoneNumber, + &i.CompanyID, &i.BranchID, &i.UserID, &i.CashedOut, @@ -107,12 +111,30 @@ func (q *Queries) DeleteBetOutcome(ctx context.Context, betID int64) error { } const GetAllBets = `-- name: GetAllBets :many -SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes +SELECT id, amount, total_odds, status, full_name, phone_number, company_id, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes FROM bet_with_outcomes +wHERE ( + branch_id = $1 + OR $1 IS NULL + ) + AND ( + company_id = $2 + OR $2 IS NULL + ) + AND ( + user_id = $3 + OR $3 IS NULL + ) ` -func (q *Queries) GetAllBets(ctx context.Context) ([]BetWithOutcome, error) { - rows, err := q.db.Query(ctx, GetAllBets) +type GetAllBetsParams struct { + BranchID pgtype.Int8 `json:"branch_id"` + CompanyID pgtype.Int8 `json:"company_id"` + UserID pgtype.Int8 `json:"user_id"` +} + +func (q *Queries) GetAllBets(ctx context.Context, arg GetAllBetsParams) ([]BetWithOutcome, error) { + rows, err := q.db.Query(ctx, GetAllBets, arg.BranchID, arg.CompanyID, arg.UserID) if err != nil { return nil, err } @@ -127,6 +149,7 @@ func (q *Queries) GetAllBets(ctx context.Context) ([]BetWithOutcome, error) { &i.Status, &i.FullName, &i.PhoneNumber, + &i.CompanyID, &i.BranchID, &i.UserID, &i.CashedOut, @@ -147,7 +170,7 @@ func (q *Queries) GetAllBets(ctx context.Context) ([]BetWithOutcome, error) { } const GetBetByBranchID = `-- name: GetBetByBranchID :many -SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes +SELECT id, amount, total_odds, status, full_name, phone_number, company_id, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes FROM bet_with_outcomes WHERE branch_id = $1 ` @@ -168,6 +191,7 @@ func (q *Queries) GetBetByBranchID(ctx context.Context, branchID pgtype.Int8) ([ &i.Status, &i.FullName, &i.PhoneNumber, + &i.CompanyID, &i.BranchID, &i.UserID, &i.CashedOut, @@ -188,7 +212,7 @@ func (q *Queries) GetBetByBranchID(ctx context.Context, branchID pgtype.Int8) ([ } const GetBetByCashoutID = `-- name: GetBetByCashoutID :one -SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes +SELECT id, amount, total_odds, status, full_name, phone_number, company_id, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes FROM bet_with_outcomes WHERE cashout_id = $1 ` @@ -203,6 +227,7 @@ func (q *Queries) GetBetByCashoutID(ctx context.Context, cashoutID string) (BetW &i.Status, &i.FullName, &i.PhoneNumber, + &i.CompanyID, &i.BranchID, &i.UserID, &i.CashedOut, @@ -216,7 +241,7 @@ func (q *Queries) GetBetByCashoutID(ctx context.Context, cashoutID string) (BetW } const GetBetByID = `-- name: GetBetByID :one -SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes +SELECT id, amount, total_odds, status, full_name, phone_number, company_id, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes FROM bet_with_outcomes WHERE id = $1 ` @@ -231,6 +256,7 @@ func (q *Queries) GetBetByID(ctx context.Context, id int64) (BetWithOutcome, err &i.Status, &i.FullName, &i.PhoneNumber, + &i.CompanyID, &i.BranchID, &i.UserID, &i.CashedOut, @@ -244,7 +270,7 @@ func (q *Queries) GetBetByID(ctx context.Context, id int64) (BetWithOutcome, err } const GetBetByUserID = `-- name: GetBetByUserID :many -SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes +SELECT id, amount, total_odds, status, full_name, phone_number, company_id, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes FROM bet_with_outcomes WHERE user_id = $1 ` @@ -265,6 +291,7 @@ func (q *Queries) GetBetByUserID(ctx context.Context, userID pgtype.Int8) ([]Bet &i.Status, &i.FullName, &i.PhoneNumber, + &i.CompanyID, &i.BranchID, &i.UserID, &i.CashedOut, diff --git a/gen/db/models.go b/gen/db/models.go index 7c1695f..56f95f0 100644 --- a/gen/db/models.go +++ b/gen/db/models.go @@ -62,6 +62,7 @@ type Bet struct { Status int32 `json:"status"` FullName string `json:"full_name"` PhoneNumber string `json:"phone_number"` + CompanyID pgtype.Int8 `json:"company_id"` BranchID pgtype.Int8 `json:"branch_id"` UserID pgtype.Int8 `json:"user_id"` CashedOut bool `json:"cashed_out"` @@ -96,6 +97,7 @@ type BetWithOutcome struct { Status int32 `json:"status"` FullName string `json:"full_name"` PhoneNumber string `json:"phone_number"` + CompanyID pgtype.Int8 `json:"company_id"` BranchID pgtype.Int8 `json:"branch_id"` UserID pgtype.Int8 `json:"user_id"` CashedOut bool `json:"cashed_out"` @@ -382,6 +384,32 @@ type User struct { ReferredBy pgtype.Text `json:"referred_by"` } +type UserGameInteraction struct { + ID int64 `json:"id"` + UserID int64 `json:"user_id"` + GameID int64 `json:"game_id"` + InteractionType string `json:"interaction_type"` + Amount pgtype.Numeric `json:"amount"` + DurationSeconds pgtype.Int4 `json:"duration_seconds"` + CreatedAt pgtype.Timestamptz `json:"created_at"` +} + +type VirtualGame struct { + ID int64 `json:"id"` + Name string `json:"name"` + Provider string `json:"provider"` + Category string `json:"category"` + MinBet pgtype.Numeric `json:"min_bet"` + MaxBet pgtype.Numeric `json:"max_bet"` + Volatility string `json:"volatility"` + Rtp pgtype.Numeric `json:"rtp"` + IsFeatured pgtype.Bool `json:"is_featured"` + PopularityScore pgtype.Int4 `json:"popularity_score"` + ThumbnailUrl pgtype.Text `json:"thumbnail_url"` + CreatedAt pgtype.Timestamptz `json:"created_at"` + UpdatedAt pgtype.Timestamptz `json:"updated_at"` +} + type VirtualGameSession struct { ID int64 `json:"id"` UserID int64 `json:"user_id"` diff --git a/gen/db/transactions.sql.go b/gen/db/transactions.sql.go index d3a7418..c95c84d 100644 --- a/gen/db/transactions.sql.go +++ b/gen/db/transactions.sql.go @@ -130,10 +130,28 @@ func (q *Queries) CreateTransaction(ctx context.Context, arg CreateTransactionPa const GetAllTransactions = `-- name: GetAllTransactions :many SELECT id, amount, branch_id, company_id, cashier_id, cashier_name, bet_id, number_of_outcomes, type, payment_option, full_name, phone_number, bank_code, beneficiary_name, account_name, account_number, reference_number, verified, approved_by, approver_name, branch_location, branch_name, created_at, updated_at FROM transactions +wHERE ( + branch_id = $1 + OR $1 IS NULL + ) + AND ( + company_id = $2 + OR $2 IS NULL + ) + AND ( + cashier_id = $3 + OR $3 IS NULL + ) ` -func (q *Queries) GetAllTransactions(ctx context.Context) ([]Transaction, error) { - rows, err := q.db.Query(ctx, GetAllTransactions) +type GetAllTransactionsParams struct { + BranchID pgtype.Int8 `json:"branch_id"` + CompanyID pgtype.Int8 `json:"company_id"` + CashierID pgtype.Int8 `json:"cashier_id"` +} + +func (q *Queries) GetAllTransactions(ctx context.Context, arg GetAllTransactionsParams) ([]Transaction, error) { + rows, err := q.db.Query(ctx, GetAllTransactions, arg.BranchID, arg.CompanyID, arg.CashierID) if err != nil { return nil, err } diff --git a/internal/domain/bet.go b/internal/domain/bet.go index 9c5b53b..cbd904e 100644 --- a/internal/domain/bet.go +++ b/internal/domain/bet.go @@ -48,6 +48,7 @@ type Bet struct { FullName string PhoneNumber string BranchID ValidInt64 // Can Be Nullable + CompanyID ValidInt64 // Can Be Nullable UserID ValidInt64 // Can Be Nullable IsShopBet bool CashedOut bool @@ -55,6 +56,12 @@ type Bet struct { CreatedAt time.Time } +type BetFilter struct { + BranchID ValidInt64 // Can Be Nullable + CompanyID ValidInt64 // Can Be Nullable + UserID ValidInt64 // Can Be Nullable +} + type GetBet struct { ID int64 Amount Currency @@ -63,6 +70,7 @@ type GetBet struct { FullName string PhoneNumber string BranchID ValidInt64 // Can Be Nullable + CompanyID ValidInt64 // Can Be Nullable UserID ValidInt64 // Can Be Nullable IsShopBet bool CashedOut bool @@ -77,6 +85,7 @@ type CreateBet struct { Status OutcomeStatus FullName string PhoneNumber string + CompanyID ValidInt64 // Can Be Nullable BranchID ValidInt64 // Can Be Nullable UserID ValidInt64 // Can Be Nullable IsShopBet bool @@ -164,3 +173,4 @@ func ConvertBet(bet GetBet) BetRes { CreatedAt: bet.CreatedAt, } } + diff --git a/internal/domain/common.go b/internal/domain/common.go index fc652d1..d90d9ce 100644 --- a/internal/domain/common.go +++ b/internal/domain/common.go @@ -47,3 +47,14 @@ func (m Currency) String() string { x = x / 100 return fmt.Sprintf("$%.2f", x) } + +func CalculateWinnings(amount Currency, totalOdds float32) Currency { + + vat := amount.Float32() * 0.15 + stakeAfterVat := amount.Float32() - vat + possibleWin := stakeAfterVat * totalOdds + incomeTax := possibleWin * 0.15 + + return ToCurrency(possibleWin - incomeTax) + +} diff --git a/internal/domain/transaction.go b/internal/domain/transaction.go index d767600..b104348 100644 --- a/internal/domain/transaction.go +++ b/internal/domain/transaction.go @@ -47,6 +47,12 @@ type Transaction struct { UpdatedAt time.Time CreatedAt time.Time } + +type TransactionFilter struct { + CompanyID ValidInt64 + BranchID ValidInt64 + CashierID ValidInt64 +} type CreateTransaction struct { Amount Currency BranchID int64 diff --git a/internal/repository/bet.go b/internal/repository/bet.go index 24fe5b8..28ea2ff 100644 --- a/internal/repository/bet.go +++ b/internal/repository/bet.go @@ -22,6 +22,10 @@ func convertDBBet(bet dbgen.Bet) domain.Bet { Value: bet.BranchID.Int64, Valid: bet.BranchID.Valid, }, + CompanyID: domain.ValidInt64{ + Value: bet.CompanyID.Int64, + Valid: bet.CompanyID.Valid, + }, UserID: domain.ValidInt64{ Value: bet.UserID.Int64, Valid: bet.UserID.Valid, @@ -111,6 +115,7 @@ func convertCreateBet(bet domain.CreateBet) dbgen.CreateBetParams { Status: int32(bet.Status), FullName: bet.FullName, PhoneNumber: bet.PhoneNumber, + BranchID: pgtype.Int8{ Int64: bet.BranchID.Value, Valid: bet.BranchID.Valid, @@ -168,8 +173,21 @@ func (s *Store) GetBetByCashoutID(ctx context.Context, id string) (domain.GetBet return convertDBBetWithOutcomes(bet), nil } -func (s *Store) GetAllBets(ctx context.Context) ([]domain.GetBet, error) { - bets, err := s.queries.GetAllBets(ctx) +func (s *Store) GetAllBets(ctx context.Context, filter domain.BetFilter) ([]domain.GetBet, error) { + bets, err := s.queries.GetAllBets(ctx, dbgen.GetAllBetsParams{ + BranchID: pgtype.Int8{ + Int64: filter.BranchID.Value, + Valid: filter.BranchID.Valid, + }, + CompanyID: pgtype.Int8{ + Int64: filter.CompanyID.Value, + Valid: filter.CompanyID.Valid, + }, + UserID: pgtype.Int8{ + Int64: filter.UserID.Value, + Valid: filter.UserID.Valid, + }, + }) if err != nil { return nil, err } diff --git a/internal/repository/transaction.go b/internal/repository/transaction.go index da53fc3..dd38797 100644 --- a/internal/repository/transaction.go +++ b/internal/repository/transaction.go @@ -84,8 +84,21 @@ func (s *Store) GetTransactionByID(ctx context.Context, id int64) (domain.Transa return convertDBTransaction(transaction), nil } -func (s *Store) GetAllTransactions(ctx context.Context) ([]domain.Transaction, error) { - transaction, err := s.queries.GetAllTransactions(ctx) +func (s *Store) GetAllTransactions(ctx context.Context, filter domain.TransactionFilter) ([]domain.Transaction, error) { + transaction, err := s.queries.GetAllTransactions(ctx, dbgen.GetAllTransactionsParams{ + BranchID: pgtype.Int8{ + Int64: filter.BranchID.Value, + Valid: filter.BranchID.Valid, + }, + CompanyID: pgtype.Int8{ + Int64: filter.CompanyID.Value, + Valid: filter.CompanyID.Valid, + }, + CashierID: pgtype.Int8{ + Int64: filter.CashierID.Value, + Valid: filter.CashierID.Valid, + }, + }) if err != nil { return nil, err diff --git a/internal/services/bet/port.go b/internal/services/bet/port.go index 452083a..358bdee 100644 --- a/internal/services/bet/port.go +++ b/internal/services/bet/port.go @@ -11,7 +11,7 @@ type BetStore interface { CreateBetOutcome(ctx context.Context, outcomes []domain.CreateBetOutcome) (int64, error) GetBetByCashoutID(ctx context.Context, id string) (domain.GetBet, error) GetBetByID(ctx context.Context, id int64) (domain.GetBet, error) - GetAllBets(ctx context.Context) ([]domain.GetBet, error) + GetAllBets(ctx context.Context, filter domain.BetFilter) ([]domain.GetBet, error) GetBetByBranchID(ctx context.Context, BranchID int64) ([]domain.GetBet, error) GetBetByUserID(ctx context.Context, UserID int64) ([]domain.GetBet, error) GetBetOutcomeByEventID(ctx context.Context, eventID int64) ([]domain.BetOutcome, error) diff --git a/internal/services/bet/service.go b/internal/services/bet/service.go index 65af3d7..470b9de 100644 --- a/internal/services/bet/service.go +++ b/internal/services/bet/service.go @@ -197,6 +197,11 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID Value: branch.ID, Valid: true, } + + newBet.CompanyID = domain.ValidInt64{ + Value: branch.CompanyID, + Valid: true, + } newBet.UserID = domain.ValidInt64{ Value: userID, Valid: true, @@ -227,6 +232,10 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID Value: branch.ID, Valid: true, } + newBet.CompanyID = domain.ValidInt64{ + Value: branch.CompanyID, + Valid: true, + } newBet.UserID = domain.ValidInt64{ Value: userID, Valid: true, @@ -483,8 +492,8 @@ func (s *Service) GetBetByID(ctx context.Context, id int64) (domain.GetBet, erro func (s *Service) GetBetByCashoutID(ctx context.Context, id string) (domain.GetBet, error) { return s.betStore.GetBetByCashoutID(ctx, id) } -func (s *Service) GetAllBets(ctx context.Context) ([]domain.GetBet, error) { - return s.betStore.GetAllBets(ctx) +func (s *Service) GetAllBets(ctx context.Context, filter domain.BetFilter) ([]domain.GetBet, error) { + return s.betStore.GetAllBets(ctx, filter) } func (s *Service) GetBetByBranchID(ctx context.Context, branchID int64) ([]domain.GetBet, error) { @@ -500,6 +509,41 @@ func (s *Service) UpdateCashOut(ctx context.Context, id int64, cashedOut bool) e } func (s *Service) UpdateStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error { + + bet, err := s.GetBetByID(ctx, id) + if err != nil { + s.logger.Error("Failed to update bet status. Invalid bet id") + return err + } + + if bet.IsShopBet || + status == domain.OUTCOME_STATUS_ERROR || + status == domain.OUTCOME_STATUS_PENDING || + status == domain.OUTCOME_STATUS_LOSS { + return s.betStore.UpdateStatus(ctx, id, status) + } + + customerWallet, err := s.walletSvc.GetCustomerWallet(ctx, id) + if err != nil { + s.logger.Error("Failed to update bet status. Invalid customer wallet id") + return err + } + + var amount domain.Currency + if status == domain.OUTCOME_STATUS_WIN { + amount = domain.CalculateWinnings(bet.Amount, bet.TotalOdds) + } else if status == domain.OUTCOME_STATUS_HALF { + amount = (domain.CalculateWinnings(bet.Amount, bet.TotalOdds)) / 2 + } else { + amount = bet.Amount + } + err = s.walletSvc.AddToWallet(ctx, customerWallet.RegularID, amount) + + if err != nil { + s.logger.Error("Failed to update bet status. Failed to update user wallet") + return err + } + return s.betStore.UpdateStatus(ctx, id, status) } diff --git a/internal/services/transaction/port.go b/internal/services/transaction/port.go index d0c500b..2bc6f6b 100644 --- a/internal/services/transaction/port.go +++ b/internal/services/transaction/port.go @@ -9,7 +9,7 @@ import ( type TransactionStore interface { CreateTransaction(ctx context.Context, transaction domain.CreateTransaction) (domain.Transaction, error) GetTransactionByID(ctx context.Context, id int64) (domain.Transaction, error) - GetAllTransactions(ctx context.Context) ([]domain.Transaction, error) + GetAllTransactions(ctx context.Context, filter domain.TransactionFilter) ([]domain.Transaction, error) GetTransactionByBranch(ctx context.Context, id int64) ([]domain.Transaction, error) UpdateTransactionVerified(ctx context.Context, id int64, verified bool, approvedBy int64, approverName string) error } diff --git a/internal/services/transaction/service.go b/internal/services/transaction/service.go index c7504b4..658b938 100644 --- a/internal/services/transaction/service.go +++ b/internal/services/transaction/service.go @@ -22,8 +22,8 @@ func (s *Service) CreateTransaction(ctx context.Context, transaction domain.Crea func (s *Service) GetTransactionByID(ctx context.Context, id int64) (domain.Transaction, error) { return s.transactionStore.GetTransactionByID(ctx, id) } -func (s *Service) GetAllTransactions(ctx context.Context) ([]domain.Transaction, error) { - return s.transactionStore.GetAllTransactions(ctx) +func (s *Service) GetAllTransactions(ctx context.Context, filter domain.TransactionFilter) ([]domain.Transaction, error) { + return s.transactionStore.GetAllTransactions(ctx, filter) } func (s *Service) GetTransactionByBranch(ctx context.Context, id int64) ([]domain.Transaction, error) { return s.transactionStore.GetTransactionByBranch(ctx, id) diff --git a/internal/web_server/cron.go b/internal/web_server/cron.go index 769d0b3..e07a014 100644 --- a/internal/web_server/cron.go +++ b/internal/web_server/cron.go @@ -21,22 +21,22 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S spec string task func() }{ - { - spec: "0 0 * * * *", // Every 1 hour - task: func() { - if err := eventService.FetchUpcomingEvents(context.Background()); err != nil { - log.Printf("FetchUpcomingEvents error: %v", err) - } - }, - }, - { - spec: "0 */15 * * * *", // Every 15 minutes - task: func() { - if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil { - log.Printf("FetchNonLiveOdds error: %v", err) - } - }, - }, + // { + // spec: "0 0 * * * *", // Every 1 hour + // task: func() { + // if err := eventService.FetchUpcomingEvents(context.Background()); err != nil { + // log.Printf("FetchUpcomingEvents error: %v", err) + // } + // }, + // }, + // { + // spec: "0 */15 * * * *", // Every 15 minutes + // task: func() { + // if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil { + // log.Printf("FetchNonLiveOdds error: %v", err) + // } + // }, + // }, { spec: "0 */15 * * * *", // Every 15 Minutes task: func() { diff --git a/internal/web_server/handlers/bet_handler.go b/internal/web_server/handlers/bet_handler.go index b5f87ec..0a5d285 100644 --- a/internal/web_server/handlers/bet_handler.go +++ b/internal/web_server/handlers/bet_handler.go @@ -150,7 +150,13 @@ func (h *Handler) RandomBet(c *fiber.Ctx) error { // @Failure 500 {object} response.APIResponse // @Router /bet [get] func (h *Handler) GetAllBet(c *fiber.Ctx) error { - bets, err := h.betSvc.GetAllBets(c.Context()) + companyID := c.Locals("company_id").(domain.ValidInt64) + branchID := c.Locals("branch_id").(domain.ValidInt64) + + bets, err := h.betSvc.GetAllBets(c.Context(), domain.BetFilter{ + BranchID: branchID, + CompanyID: companyID, + }) if err != nil { h.logger.Error("Failed to get bets", "error", err) return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve bets") diff --git a/internal/web_server/handlers/cashier.go b/internal/web_server/handlers/cashier.go index 4fdebfc..18efb18 100644 --- a/internal/web_server/handlers/cashier.go +++ b/internal/web_server/handlers/cashier.go @@ -37,7 +37,7 @@ type CreateCashierReq struct { func (h *Handler) CreateCashier(c *fiber.Ctx) error { // Get user_id from middleware - companyID := c.Locals("company_id").(domain.ValidInt64) + // companyID := c.Locals("company_id").(domain.ValidInt64) var req CreateCashierReq if err := c.BodyParser(&req); err != nil { @@ -48,6 +48,13 @@ func (h *Handler) CreateCashier(c *fiber.Ctx) error { if !ok { return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) } + + // Cashiers inherit the company id from the branch id + branch, err := h.branchSvc.GetBranchByID(c.Context(), req.BranchID) + + if err != nil { + return response.WriteJSON(c, fiber.StatusBadRequest, "Branch ID is invalid", nil, nil) + } userRequest := domain.CreateUserReq{ FirstName: req.FirstName, LastName: req.LastName, @@ -56,7 +63,10 @@ func (h *Handler) CreateCashier(c *fiber.Ctx) error { Password: req.Password, Role: string(domain.RoleCashier), Suspended: req.Suspended, - CompanyID: companyID, + CompanyID: domain.ValidInt64{ + Value: branch.CompanyID, + Valid: true, + }, } fmt.Print(req.Suspended) newUser, err := h.userSvc.CreateUser(c.Context(), userRequest, true) diff --git a/internal/web_server/handlers/transaction_handler.go b/internal/web_server/handlers/transaction_handler.go index 8918023..77189dd 100644 --- a/internal/web_server/handlers/transaction_handler.go +++ b/internal/web_server/handlers/transaction_handler.go @@ -225,35 +225,18 @@ func (h *Handler) CreateTransaction(c *fiber.Ctx) error { // @Router /transaction [get] func (h *Handler) GetAllTransactions(c *fiber.Ctx) error { // Get user_id from middleware - userID := c.Locals("user_id").(int64) - - // Fetch user details - user, err := h.userSvc.GetUserByID(c.Context(), userID) - if err != nil { - h.logger.Error("Failed to fetch user details", "user_id", userID, "error", err) - return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve user details", err, nil) - } + // userID := c.Locals("user_id").(int64) + // role := c.Locals("role").(domain.Role) + companyID := c.Locals("company_id").(domain.ValidInt64) + branchID := c.Locals("branch_id").(domain.ValidInt64) var transactions []domain.Transaction // Check user role and fetch transactions accordingly - // TODO: filtering by the user role - switch user.Role { - case domain.RoleSuperAdmin: - // Admin can fetch all transactions - transactions, err = h.transactionSvc.GetAllTransactions(c.Context()) - case domain.RoleAdmin: - // Admins can fetch transaction for company branches - - transactions, err = h.transactionSvc.GetAllTransactions(c.Context()) - case domain.RoleBranchManager, domain.RoleCashier: - // Branch Manager or Cashier can fetch transactions for their branches - // transactions, err = transactionSvc.GetTransactionByBranch(c.Context(), user.BranchID) - transactions, err = h.transactionSvc.GetAllTransactions(c.Context()) - default: - // Unauthorized role - return response.WriteJSON(c, fiber.StatusForbidden, "Unauthorized", nil, nil) - } + transactions, err := h.transactionSvc.GetAllTransactions(c.Context(), domain.TransactionFilter{ + CompanyID: companyID, + BranchID: branchID, + }) if err != nil { h.logger.Error("Failed to get transactions", "error", err) diff --git a/internal/web_server/middleware.go b/internal/web_server/middleware.go index 8e550cb..33c8829 100644 --- a/internal/web_server/middleware.go +++ b/internal/web_server/middleware.go @@ -53,6 +53,22 @@ func (a *App) authMiddleware(c *fiber.Ctx) error { c.Locals("company_id", claim.CompanyID) c.Locals("refresh_token", refreshToken) + var branchID domain.ValidInt64 + + if claim.Role == domain.RoleCashier { + branch, err := a.branchSvc.GetBranchByCashier(c.Context(), claim.UserId) + if err != nil { + a.logger.Error("Failed to get branch id for bet", "error", err) + return fiber.NewError(fiber.StatusInternalServerError, "Failed to branch id for bet") + } + branchID = domain.ValidInt64{ + Value: branch.ID, + Valid: true, + } + + } + + c.Locals("branch_id", branchID) return c.Next() } diff --git a/makefile b/makefile index 5c688d8..2a55cc9 100644 --- a/makefile +++ b/makefile @@ -49,6 +49,7 @@ db-up: .PHONY: db-down db-down: + @docker volume rm fortunebet-backend_postgres_data @docker compose down postgres: @docker exec -it fortunebet-backend-postgres-1 psql -U root -d gh