Yimaru-BackEnd/internal/repository/branch.go

428 lines
12 KiB
Go

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 convertCreateBranch(branch domain.CreateBranch) dbgen.CreateBranchParams {
return dbgen.CreateBranchParams{
Name: branch.Name,
Location: branch.Location,
WalletID: branch.WalletID,
BranchManagerID: branch.BranchManagerID,
CompanyID: branch.CompanyID,
IsSelfOwned: branch.IsSelfOwned,
}
}
func convertDBBranchDetail(dbBranch dbgen.BranchDetail) domain.BranchDetail {
return domain.BranchDetail{
ID: dbBranch.ID,
Name: dbBranch.Name,
Location: dbBranch.Location,
WalletID: dbBranch.WalletID,
BranchManagerID: dbBranch.BranchManagerID,
CompanyID: dbBranch.CompanyID,
IsSelfOwned: dbBranch.IsSelfOwned,
ManagerName: dbBranch.ManagerName.(string),
ManagerPhoneNumber: dbBranch.ManagerPhoneNumber.String,
Balance: domain.Currency(dbBranch.Balance.Int64),
}
}
func convertDBBranch(dbBranch dbgen.Branch) domain.Branch {
return domain.Branch{
ID: dbBranch.ID,
Name: dbBranch.Name,
Location: dbBranch.Location,
WalletID: dbBranch.WalletID,
BranchManagerID: dbBranch.BranchManagerID,
CompanyID: dbBranch.CompanyID,
IsSelfOwned: dbBranch.IsSelfOwned,
}
}
func convertUpdateBranch(updateBranch domain.UpdateBranch) dbgen.UpdateBranchParams {
var newUpdateBranch dbgen.UpdateBranchParams
newUpdateBranch.ID = updateBranch.ID
if updateBranch.Name != nil {
newUpdateBranch.Name = pgtype.Text{
String: *updateBranch.Name,
Valid: true,
}
}
if updateBranch.Location != nil {
newUpdateBranch.Location = pgtype.Text{
String: *updateBranch.Location,
Valid: true,
}
}
if updateBranch.BranchManagerID != nil {
newUpdateBranch.BranchManagerID = pgtype.Int8{
Int64: *updateBranch.BranchManagerID,
Valid: true,
}
}
if updateBranch.CompanyID != nil {
newUpdateBranch.CompanyID = pgtype.Int8{
Int64: *updateBranch.CompanyID,
Valid: true,
}
}
if updateBranch.IsSelfOwned != nil {
newUpdateBranch.IsSelfOwned = pgtype.Bool{
Bool: *updateBranch.IsSelfOwned,
Valid: true,
}
}
if updateBranch.IsActive != nil {
newUpdateBranch.IsActive = pgtype.Bool{
Bool: *updateBranch.IsActive,
Valid: true,
}
}
return newUpdateBranch
}
func (s *Store) CreateBranch(ctx context.Context, branch domain.CreateBranch) (domain.Branch, error) {
dbBranch, err := s.queries.CreateBranch(ctx, convertCreateBranch(branch))
if err != nil {
return domain.Branch{}, err
}
return 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 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, 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, 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: pgtype.Int8{
Int64: filter.CompanyID.Value,
Valid: filter.CompanyID.Valid,
},
})
if err != nil {
return nil, err
}
var branches []domain.BranchDetail = make([]domain.BranchDetail, 0, len(dbBranches))
for _, dbBranch := range dbBranches {
branches = append(branches, convertDBBranchDetail(dbBranch))
}
return branches, nil
}
func (s *Store) SearchBranchByName(ctx context.Context, name string) ([]domain.BranchDetail, error) {
dbBranches, err := s.queries.SearchBranchByName(ctx, pgtype.Text{String: name, Valid: true})
if err != nil {
return nil, err
}
var branches []domain.BranchDetail = make([]domain.BranchDetail, 0, len(dbBranches))
for _, dbBranch := range dbBranches {
branches = append(branches, convertDBBranchDetail(dbBranch))
}
return branches, nil
}
func (s *Store) UpdateBranch(ctx context.Context, branch domain.UpdateBranch) (domain.Branch, error) {
dbBranch, err := s.queries.UpdateBranch(ctx, convertUpdateBranch(branch))
if err != nil {
return domain.Branch{}, err
}
return 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 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)
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
}