package repository import ( "context" "fmt" dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/jackc/pgx/v5/pgtype" ) func (s *Store) CreateBranch(ctx context.Context, branch domain.CreateBranch) (domain.Branch, error) { dbBranch, err := s.queries.CreateBranch(ctx, domain.ConvertCreateBranch(branch)) if err != nil { return domain.Branch{}, err } return domain.ConvertDBBranch(dbBranch), nil } func (s *Store) GetBranchByID(ctx context.Context, id int64) (domain.BranchDetail, error) { dbBranch, err := s.queries.GetBranchByID(ctx, id) if err != nil { return domain.BranchDetail{}, err } return domain.ConvertDBBranchDetail(dbBranch), nil } func (s *Store) GetBranchByManagerID(ctx context.Context, branchManagerID int64) ([]domain.BranchDetail, error) { dbBranches, err := s.queries.GetBranchByManagerID(ctx, branchManagerID) if err != nil { return nil, err } var branches []domain.BranchDetail = make([]domain.BranchDetail, 0, len(dbBranches)) for _, dbBranch := range dbBranches { branches = append(branches, domain.ConvertDBBranchDetail(dbBranch)) } return branches, nil } func (s *Store) GetBranchByCompanyID(ctx context.Context, companyID int64) ([]domain.BranchDetail, error) { dbBranches, err := s.queries.GetBranchByCompanyID(ctx, companyID) if err != nil { return nil, err } var branches []domain.BranchDetail = make([]domain.BranchDetail, 0, len(dbBranches)) for _, dbBranch := range dbBranches { branches = append(branches, domain.ConvertDBBranchDetail(dbBranch)) } return branches, nil } func (s *Store) GetAllBranches(ctx context.Context, filter domain.BranchFilter) ([]domain.BranchDetail, error) { dbBranches, err := s.queries.GetAllBranches(ctx, dbgen.GetAllBranchesParams{ CompanyID: filter.CompanyID.ToPG(), BranchManagerID: filter.BranchManagerID.ToPG(), Query: filter.Query.ToPG(), CreatedBefore: filter.CreatedBefore.ToPG(), CreatedAfter: filter.CreatedAfter.ToPG(), }) if err != nil { return nil, err } var branches []domain.BranchDetail = make([]domain.BranchDetail, 0, len(dbBranches)) for _, dbBranch := range dbBranches { branches = append(branches, domain.ConvertDBBranchDetail(dbBranch)) } return branches, nil } func (s *Store) SearchBranchByName(ctx context.Context, name string, companyID domain.ValidInt64) ([]domain.BranchDetail, error) { dbBranches, err := s.queries.SearchBranchByName(ctx, dbgen.SearchBranchByNameParams{ Column1: pgtype.Text{String: name, Valid: true}, CompanyID: companyID.ToPG(), }) if err != nil { return nil, err } var branches []domain.BranchDetail = make([]domain.BranchDetail, 0, len(dbBranches)) for _, dbBranch := range dbBranches { branches = append(branches, domain.ConvertDBBranchDetail(dbBranch)) } return branches, nil } func (s *Store) UpdateBranch(ctx context.Context, branch domain.UpdateBranch) (domain.Branch, error) { dbBranch, err := s.queries.UpdateBranch(ctx, domain.ConvertUpdateBranch(branch)) if err != nil { return domain.Branch{}, err } return domain.ConvertDBBranch(dbBranch), nil } func (s *Store) DeleteBranch(ctx context.Context, id int64) error { return s.queries.DeleteBranch(ctx, id) } // Branch Operations func (s *Store) CreateBranchOperation(ctx context.Context, branchOperation domain.CreateBranchOperation) error { _, err := s.queries.CreateBranchOperation(ctx, dbgen.CreateBranchOperationParams{ BranchID: branchOperation.BranchID, OperationID: branchOperation.OperationID, }) return err } func (s *Store) CreateSupportedOperation(ctx context.Context, supportedOperation domain.CreateSupportedOperation) (domain.SupportedOperation, error) { dbSupportedOperation, err := s.queries.CreateSupportedOperation(ctx, dbgen.CreateSupportedOperationParams{ Name: supportedOperation.Name, Description: supportedOperation.Description, }) if err != nil { return domain.SupportedOperation{}, err } return domain.SupportedOperation{ ID: dbSupportedOperation.ID, Name: dbSupportedOperation.Name, Description: dbSupportedOperation.Description, }, nil } func (s *Store) CreateBranchCashier(ctx context.Context, branchID int64, userID int64) error { _, err := s.queries.CreateBranchCashier(ctx, dbgen.CreateBranchCashierParams{ UserID: userID, BranchID: branchID, }) if err != nil { return err } return nil } func (s *Store) GetAllSupportedOperations(ctx context.Context) ([]domain.SupportedOperation, error) { dbOperations, err := s.queries.GetAllSupportedOperations(ctx) if err != nil { return nil, err } var operations []domain.SupportedOperation = make([]domain.SupportedOperation, 0, len(dbOperations)) for _, dbOperation := range dbOperations { operations = append(operations, domain.SupportedOperation{ ID: dbOperation.ID, Name: dbOperation.Name, Description: dbOperation.Description, }) } return operations, nil } func (s *Store) GetBranchOperations(ctx context.Context, branchID int64) ([]domain.BranchOperation, error) { dbBranchOperations, err := s.queries.GetBranchOperations(ctx, branchID) if err != nil { return nil, err } var branchOperations []domain.BranchOperation = make([]domain.BranchOperation, 0, len(dbBranchOperations)) for _, dbBranchOperation := range dbBranchOperations { branchOperations = append(branchOperations, domain.BranchOperation{ ID: dbBranchOperation.ID, OperationName: dbBranchOperation.Name, OperationDescription: dbBranchOperation.Description, }) } return branchOperations, nil } func (s *Store) GetBranchByCashier(ctx context.Context, userID int64) (domain.Branch, error) { branch, err := s.queries.GetBranchByCashier(ctx, userID) if err != nil { return domain.Branch{}, err } return domain.ConvertDBBranch(branch), err } func (s *Store) DeleteBranchOperation(ctx context.Context, branchID int64, operationID int64) error { err := s.queries.DeleteBranchOperation(ctx, dbgen.DeleteBranchOperationParams{ BranchID: branchID, OperationID: operationID, }) return err } func (s *Store) DeleteBranchCashier(ctx context.Context, userID int64) error { return s.queries.DeleteBranchCashier(ctx, userID) } // GetBranchCounts returns total and active branch counts func (s *Store) GetBranchCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) { query := `SELECT COUNT(*) as total, COUNT(CASE WHEN is_active = true THEN 1 END) as active, COUNT(CASE WHEN is_active = false THEN 1 END) as inactive FROM branches` args := []interface{}{} argPos := 1 // Add filters if provided if filter.CompanyID.Valid { query += fmt.Sprintf(" WHERE company_id = $%d", argPos) args = append(args, filter.CompanyID.Value) argPos++ } if filter.StartTime.Valid { query += fmt.Sprintf(" AND %screated_at >= $%d", func() string { if len(args) == 0 { return " WHERE " } return " AND " }(), argPos) args = append(args, filter.StartTime.Value) argPos++ } if filter.EndTime.Valid { query += fmt.Sprintf(" AND created_at <= $%d", argPos) args = append(args, filter.EndTime.Value) argPos++ } row := s.conn.QueryRow(ctx, query, args...) err = row.Scan(&total, &active, &inactive) if err != nil { return 0, 0, 0, fmt.Errorf("failed to get branch counts: %w", err) } return total, active, inactive, nil } // GetBranchDetails returns branch details map func (s *Store) GetBranchDetails(ctx context.Context, filter domain.ReportFilter) (map[int64]domain.BranchDetail, error) { query := `SELECT b.id, b.name, b.location, CONCAT(u.first_name, ' ', u.last_name) as manager_name FROM branches b LEFT JOIN users u ON b.branch_manager_id = u.id` args := []interface{}{} argPos := 1 // Add filters if provided if filter.CompanyID.Valid { query += fmt.Sprintf(" WHERE b.company_id = $%d", argPos) args = append(args, filter.CompanyID.Value) argPos++ } if filter.BranchID.Valid { query += fmt.Sprintf(" AND %sb.id = $%d", func() string { if len(args) == 0 { return " WHERE " } return " AND " }(), argPos) args = append(args, filter.BranchID.Value) argPos++ } if filter.StartTime.Valid { query += fmt.Sprintf(" AND %sb.created_at >= $%d", func() string { if len(args) == 0 { return " WHERE " } return " AND " }(), argPos) args = append(args, filter.StartTime.Value) argPos++ } if filter.EndTime.Valid { query += fmt.Sprintf(" AND b.created_at <= $%d", argPos) args = append(args, filter.EndTime.Value) argPos++ } rows, err := s.conn.Query(ctx, query, args...) if err != nil { return nil, fmt.Errorf("failed to query branch details: %w", err) } defer rows.Close() details := make(map[int64]domain.BranchDetail) for rows.Next() { var id int64 var detail domain.BranchDetail if err := rows.Scan(&id, &detail.Name, &detail.Location, &detail.ManagerName); err != nil { return nil, fmt.Errorf("failed to scan branch detail: %w", err) } details[id] = detail } if err = rows.Err(); err != nil { return nil, fmt.Errorf("rows error: %w", err) } return details, nil } // In internal/repository/branch.go func (s *Store) GetAllCompaniesBranch(ctx context.Context) ([]domain.Company, error) { dbCompanies, err := s.queries.GetAllCompanies(ctx, dbgen.GetAllCompaniesParams{}) if err != nil { return nil, fmt.Errorf("failed to get all companies: %w", err) } companies := make([]domain.Company, 0, len(dbCompanies)) for _, dbCompany := range dbCompanies { companies = append(companies, domain.Company{ ID: dbCompany.ID, Name: dbCompany.Name, WalletID: dbCompany.WalletID, AdminID: dbCompany.AdminID, }) } return companies, nil } // In internal/repository/branch.go func (s *Store) GetBranchesByCompany(ctx context.Context, companyID int64) ([]domain.Branch, error) { dbBranches, err := s.queries.GetBranchByCompanyID(ctx, companyID) if err != nil { return nil, fmt.Errorf("failed to get branches for company %d: %w", companyID, err) } branches := make([]domain.Branch, 0, len(dbBranches)) for _, dbBranch := range dbBranches { branch := domain.Branch{ ID: dbBranch.ID, Name: dbBranch.Name, Location: dbBranch.Location, WalletID: dbBranch.WalletID, CompanyID: dbBranch.CompanyID, IsSelfOwned: dbBranch.IsSelfOwned, } branch.BranchManagerID = dbBranch.BranchManagerID branches = append(branches, branch) } return branches, nil }