fix: company filter
This commit is contained in:
parent
c4328dedf0
commit
c2a9de6671
|
|
@ -285,7 +285,9 @@ CREATE TABLE companies (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
admin_id BIGINT NOT NULL,
|
admin_id BIGINT NOT NULL,
|
||||||
wallet_id BIGINT NOT NULL
|
wallet_id BIGINT NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
CREATE TABLE leagues (
|
CREATE TABLE leagues (
|
||||||
id BIGINT PRIMARY KEY,
|
id BIGINT PRIMARY KEY,
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,8 @@ SET name = COALESCE(sqlc.narg(name), name),
|
||||||
branch_manager_id = COALESCE(sqlc.narg(branch_manager_id), branch_manager_id),
|
branch_manager_id = COALESCE(sqlc.narg(branch_manager_id), branch_manager_id),
|
||||||
company_id = COALESCE(sqlc.narg(company_id), company_id),
|
company_id = COALESCE(sqlc.narg(company_id), company_id),
|
||||||
is_self_owned = COALESCE(sqlc.narg(is_self_owned), is_self_owned),
|
is_self_owned = COALESCE(sqlc.narg(is_self_owned), is_self_owned),
|
||||||
is_active = COALESCE(sqlc.narg(is_active), is_active)
|
is_active = COALESCE(sqlc.narg(is_active), is_active),
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
-- name: DeleteBranch :exec
|
-- name: DeleteBranch :exec
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,22 @@ VALUES ($1, $2, $3)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
-- name: GetAllCompanies :many
|
-- name: GetAllCompanies :many
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM companies_details;
|
FROM companies_details
|
||||||
|
WHERE (
|
||||||
|
name ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR admin_first_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR admin_last_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR admin_phone_number ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR sqlc.narg('query') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > sqlc.narg('created_before')
|
||||||
|
OR sqlc.narg('created_before') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < sqlc.narg('created_after')
|
||||||
|
OR sqlc.narg('created_after') IS NULL
|
||||||
|
);
|
||||||
-- name: GetCompanyByID :one
|
-- name: GetCompanyByID :one
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM companies_details
|
FROM companies_details
|
||||||
|
|
@ -20,7 +35,8 @@ WHERE name ILIKE '%' || $1 || '%';
|
||||||
-- name: UpdateCompany :one
|
-- name: UpdateCompany :one
|
||||||
UPDATE companies
|
UPDATE companies
|
||||||
SET name = COALESCE(sqlc.narg(name), name),
|
SET name = COALESCE(sqlc.narg(name), name),
|
||||||
admin_id = COALESCE(sqlc.narg(admin_id), admin_id)
|
admin_id = COALESCE(sqlc.narg(admin_id), admin_id),
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
-- name: DeleteCompany :exec
|
-- name: DeleteCompany :exec
|
||||||
|
|
|
||||||
|
|
@ -490,7 +490,8 @@ SET name = COALESCE($2, name),
|
||||||
branch_manager_id = COALESCE($4, branch_manager_id),
|
branch_manager_id = COALESCE($4, branch_manager_id),
|
||||||
company_id = COALESCE($5, company_id),
|
company_id = COALESCE($5, company_id),
|
||||||
is_self_owned = COALESCE($6, is_self_owned),
|
is_self_owned = COALESCE($6, is_self_owned),
|
||||||
is_active = COALESCE($7, is_active)
|
is_active = COALESCE($7, is_active),
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING id, name, location, is_active, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at
|
RETURNING id, name, location, is_active, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at
|
||||||
`
|
`
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ INSERT INTO companies (
|
||||||
wallet_id
|
wallet_id
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3)
|
VALUES ($1, $2, $3)
|
||||||
RETURNING id, name, admin_id, wallet_id
|
RETURNING id, name, admin_id, wallet_id, created_at, updated_at
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateCompanyParams struct {
|
type CreateCompanyParams struct {
|
||||||
|
|
@ -35,6 +35,8 @@ func (q *Queries) CreateCompany(ctx context.Context, arg CreateCompanyParams) (C
|
||||||
&i.Name,
|
&i.Name,
|
||||||
&i.AdminID,
|
&i.AdminID,
|
||||||
&i.WalletID,
|
&i.WalletID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
@ -50,12 +52,33 @@ func (q *Queries) DeleteCompany(ctx context.Context, id int64) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetAllCompanies = `-- name: GetAllCompanies :many
|
const GetAllCompanies = `-- name: GetAllCompanies :many
|
||||||
SELECT id, name, admin_id, wallet_id, balance, is_active, admin_first_name, admin_last_name, admin_phone_number
|
SELECT id, name, admin_id, wallet_id, created_at, updated_at, balance, is_active, admin_first_name, admin_last_name, admin_phone_number
|
||||||
FROM companies_details
|
FROM companies_details
|
||||||
|
WHERE (
|
||||||
|
name ILIKE '%' || $1 || '%'
|
||||||
|
OR admin_first_name ILIKE '%' || $1 || '%'
|
||||||
|
OR admin_last_name ILIKE '%' || $1 || '%'
|
||||||
|
OR admin_phone_number ILIKE '%' || $1 || '%'
|
||||||
|
OR $1 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > $2
|
||||||
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < $3
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetAllCompanies(ctx context.Context) ([]CompaniesDetail, error) {
|
type GetAllCompaniesParams struct {
|
||||||
rows, err := q.db.Query(ctx, GetAllCompanies)
|
Query pgtype.Text `json:"query"`
|
||||||
|
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||||
|
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetAllCompanies(ctx context.Context, arg GetAllCompaniesParams) ([]CompaniesDetail, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetAllCompanies, arg.Query, arg.CreatedBefore, arg.CreatedAfter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -68,6 +91,8 @@ func (q *Queries) GetAllCompanies(ctx context.Context) ([]CompaniesDetail, error
|
||||||
&i.Name,
|
&i.Name,
|
||||||
&i.AdminID,
|
&i.AdminID,
|
||||||
&i.WalletID,
|
&i.WalletID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
&i.Balance,
|
&i.Balance,
|
||||||
&i.IsActive,
|
&i.IsActive,
|
||||||
&i.AdminFirstName,
|
&i.AdminFirstName,
|
||||||
|
|
@ -85,7 +110,7 @@ func (q *Queries) GetAllCompanies(ctx context.Context) ([]CompaniesDetail, error
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetCompanyByID = `-- name: GetCompanyByID :one
|
const GetCompanyByID = `-- name: GetCompanyByID :one
|
||||||
SELECT id, name, admin_id, wallet_id, balance, is_active, admin_first_name, admin_last_name, admin_phone_number
|
SELECT id, name, admin_id, wallet_id, created_at, updated_at, balance, is_active, admin_first_name, admin_last_name, admin_phone_number
|
||||||
FROM companies_details
|
FROM companies_details
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -98,6 +123,8 @@ func (q *Queries) GetCompanyByID(ctx context.Context, id int64) (CompaniesDetail
|
||||||
&i.Name,
|
&i.Name,
|
||||||
&i.AdminID,
|
&i.AdminID,
|
||||||
&i.WalletID,
|
&i.WalletID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
&i.Balance,
|
&i.Balance,
|
||||||
&i.IsActive,
|
&i.IsActive,
|
||||||
&i.AdminFirstName,
|
&i.AdminFirstName,
|
||||||
|
|
@ -108,7 +135,7 @@ func (q *Queries) GetCompanyByID(ctx context.Context, id int64) (CompaniesDetail
|
||||||
}
|
}
|
||||||
|
|
||||||
const SearchCompanyByName = `-- name: SearchCompanyByName :many
|
const SearchCompanyByName = `-- name: SearchCompanyByName :many
|
||||||
SELECT id, name, admin_id, wallet_id, balance, is_active, admin_first_name, admin_last_name, admin_phone_number
|
SELECT id, name, admin_id, wallet_id, created_at, updated_at, balance, is_active, admin_first_name, admin_last_name, admin_phone_number
|
||||||
FROM companies_details
|
FROM companies_details
|
||||||
WHERE name ILIKE '%' || $1 || '%'
|
WHERE name ILIKE '%' || $1 || '%'
|
||||||
`
|
`
|
||||||
|
|
@ -127,6 +154,8 @@ func (q *Queries) SearchCompanyByName(ctx context.Context, dollar_1 pgtype.Text)
|
||||||
&i.Name,
|
&i.Name,
|
||||||
&i.AdminID,
|
&i.AdminID,
|
||||||
&i.WalletID,
|
&i.WalletID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
&i.Balance,
|
&i.Balance,
|
||||||
&i.IsActive,
|
&i.IsActive,
|
||||||
&i.AdminFirstName,
|
&i.AdminFirstName,
|
||||||
|
|
@ -146,9 +175,10 @@ func (q *Queries) SearchCompanyByName(ctx context.Context, dollar_1 pgtype.Text)
|
||||||
const UpdateCompany = `-- name: UpdateCompany :one
|
const UpdateCompany = `-- name: UpdateCompany :one
|
||||||
UPDATE companies
|
UPDATE companies
|
||||||
SET name = COALESCE($2, name),
|
SET name = COALESCE($2, name),
|
||||||
admin_id = COALESCE($3, admin_id)
|
admin_id = COALESCE($3, admin_id),
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING id, name, admin_id, wallet_id
|
RETURNING id, name, admin_id, wallet_id, created_at, updated_at
|
||||||
`
|
`
|
||||||
|
|
||||||
type UpdateCompanyParams struct {
|
type UpdateCompanyParams struct {
|
||||||
|
|
@ -165,6 +195,8 @@ func (q *Queries) UpdateCompany(ctx context.Context, arg UpdateCompanyParams) (C
|
||||||
&i.Name,
|
&i.Name,
|
||||||
&i.AdminID,
|
&i.AdminID,
|
||||||
&i.WalletID,
|
&i.WalletID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,8 @@ type CompaniesDetail struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
AdminID int64 `json:"admin_id"`
|
AdminID int64 `json:"admin_id"`
|
||||||
WalletID int64 `json:"wallet_id"`
|
WalletID int64 `json:"wallet_id"`
|
||||||
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
Balance int64 `json:"balance"`
|
Balance int64 `json:"balance"`
|
||||||
IsActive bool `json:"is_active"`
|
IsActive bool `json:"is_active"`
|
||||||
AdminFirstName string `json:"admin_first_name"`
|
AdminFirstName string `json:"admin_first_name"`
|
||||||
|
|
@ -195,6 +197,8 @@ type Company struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
AdminID int64 `json:"admin_id"`
|
AdminID int64 `json:"admin_id"`
|
||||||
WalletID int64 `json:"wallet_id"`
|
WalletID int64 `json:"wallet_id"`
|
||||||
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CustomerWallet struct {
|
type CustomerWallet struct {
|
||||||
|
|
|
||||||
|
|
@ -253,9 +253,16 @@ WHERE wallet_id = $1
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetCompanyByWalletID(ctx context.Context, walletID int64) (Company, error) {
|
type GetCompanyByWalletIDRow struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
AdminID int64 `json:"admin_id"`
|
||||||
|
WalletID int64 `json:"wallet_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetCompanyByWalletID(ctx context.Context, walletID int64) (GetCompanyByWalletIDRow, error) {
|
||||||
row := q.db.QueryRow(ctx, GetCompanyByWalletID, walletID)
|
row := q.db.QueryRow(ctx, GetCompanyByWalletID, walletID)
|
||||||
var i Company
|
var i GetCompanyByWalletIDRow
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.Name,
|
&i.Name,
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,13 @@ type Company struct {
|
||||||
WalletID int64
|
WalletID int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CompanyFilter struct {
|
||||||
|
IsActive ValidBool
|
||||||
|
Query ValidString
|
||||||
|
CreatedBefore ValidTime
|
||||||
|
CreatedAfter ValidTime
|
||||||
|
}
|
||||||
|
|
||||||
type GetCompany struct {
|
type GetCompany struct {
|
||||||
ID int64
|
ID int64
|
||||||
Name string
|
Name string
|
||||||
|
|
|
||||||
|
|
@ -400,7 +400,7 @@ func (s *Store) GetBranchDetails(ctx context.Context, filter domain.ReportFilter
|
||||||
|
|
||||||
// In internal/repository/branch.go
|
// In internal/repository/branch.go
|
||||||
func (s *Store) GetAllCompaniesBranch(ctx context.Context) ([]domain.Company, error) {
|
func (s *Store) GetAllCompaniesBranch(ctx context.Context) ([]domain.Company, error) {
|
||||||
dbCompanies, err := s.queries.GetAllCompanies(ctx)
|
dbCompanies, err := s.queries.GetAllCompanies(ctx, dbgen.GetAllCompaniesParams{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get all companies: %w", err)
|
return nil, fmt.Errorf("failed to get all companies: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,21 @@ func (s *Store) CreateCompany(ctx context.Context, company domain.CreateCompany)
|
||||||
return convertDBCompany(dbCompany), nil
|
return convertDBCompany(dbCompany), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetAllCompanies(ctx context.Context) ([]domain.GetCompany, error) {
|
func (s *Store) GetAllCompanies(ctx context.Context, filter domain.CompanyFilter) ([]domain.GetCompany, error) {
|
||||||
dbCompanies, err := s.queries.GetAllCompanies(ctx)
|
dbCompanies, err := s.queries.GetAllCompanies(ctx, dbgen.GetAllCompaniesParams{
|
||||||
|
Query: pgtype.Text{
|
||||||
|
String: filter.Query.Value,
|
||||||
|
Valid: filter.Query.Valid,
|
||||||
|
},
|
||||||
|
CreatedBefore: pgtype.Timestamp{
|
||||||
|
Time: filter.CreatedBefore.Value,
|
||||||
|
Valid: filter.CreatedBefore.Valid,
|
||||||
|
},
|
||||||
|
CreatedAfter: pgtype.Timestamp{
|
||||||
|
Time: filter.CreatedAfter.Value,
|
||||||
|
Valid: filter.CreatedAfter.Valid,
|
||||||
|
},
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ func (r *Repository) ListNotifications(ctx context.Context, recipientID int64, l
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var result []domain.Notification
|
var result []domain.Notification = make([]domain.Notification, 0, len(dbNotifications))
|
||||||
for _, dbNotif := range dbNotifications {
|
for _, dbNotif := range dbNotifications {
|
||||||
domainNotif := r.mapDBToDomain(&dbNotif)
|
domainNotif := r.mapDBToDomain(&dbNotif)
|
||||||
result = append(result, *domainNotif)
|
result = append(result, *domainNotif)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
type CompanyStore interface {
|
type CompanyStore interface {
|
||||||
CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error)
|
CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error)
|
||||||
GetAllCompanies(ctx context.Context) ([]domain.GetCompany, error)
|
GetAllCompanies(ctx context.Context, filter domain.CompanyFilter) ([]domain.GetCompany, error)
|
||||||
SearchCompanyByName(ctx context.Context, name string) ([]domain.GetCompany, error)
|
SearchCompanyByName(ctx context.Context, name string) ([]domain.GetCompany, error)
|
||||||
GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany, error)
|
GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany, error)
|
||||||
UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error)
|
UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error)
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ func NewService(companyStore CompanyStore) *Service {
|
||||||
func (s *Service) CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error) {
|
func (s *Service) CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error) {
|
||||||
return s.companyStore.CreateCompany(ctx, company)
|
return s.companyStore.CreateCompany(ctx, company)
|
||||||
}
|
}
|
||||||
func (s *Service) GetAllCompanies(ctx context.Context) ([]domain.GetCompany, error) {
|
func (s *Service) GetAllCompanies(ctx context.Context, filter domain.CompanyFilter) ([]domain.GetCompany, error) {
|
||||||
return s.companyStore.GetAllCompanies(ctx)
|
return s.companyStore.GetAllCompanies(ctx, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany, error) {
|
func (s *Service) GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany, error) {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
||||||
|
|
@ -137,8 +138,45 @@ func (h *Handler) CreateCompany(c *fiber.Ctx) error {
|
||||||
// @Failure 500 {object} response.APIResponse
|
// @Failure 500 {object} response.APIResponse
|
||||||
// @Router /company [get]
|
// @Router /company [get]
|
||||||
func (h *Handler) GetAllCompanies(c *fiber.Ctx) error {
|
func (h *Handler) GetAllCompanies(c *fiber.Ctx) error {
|
||||||
|
searchQuery := c.Query("query")
|
||||||
|
searchString := domain.ValidString{
|
||||||
|
Value: searchQuery,
|
||||||
|
Valid: searchQuery != "",
|
||||||
|
}
|
||||||
|
|
||||||
companies, err := h.companySvc.GetAllCompanies(c.Context())
|
createdBeforeQuery := c.Query("created_before")
|
||||||
|
var createdBefore domain.ValidTime
|
||||||
|
if createdBeforeQuery != "" {
|
||||||
|
createdBeforeParsed, err := time.Parse(time.RFC3339, createdBeforeQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("invalid start_time format", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid start_time format", nil, nil)
|
||||||
|
}
|
||||||
|
createdBefore = domain.ValidTime{
|
||||||
|
Value: createdBeforeParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createdAfterQuery := c.Query("created_after")
|
||||||
|
var createdAfter domain.ValidTime
|
||||||
|
if createdAfterQuery != "" {
|
||||||
|
createdAfterParsed, err := time.Parse(time.RFC3339, createdAfterQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("invalid start_time format", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid start_time format", nil, nil)
|
||||||
|
}
|
||||||
|
createdAfter = domain.ValidTime{
|
||||||
|
Value: createdAfterParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companies, err := h.companySvc.GetAllCompanies(c.Context(), domain.CompanyFilter{
|
||||||
|
Query: searchString,
|
||||||
|
CreatedBefore: createdBefore,
|
||||||
|
CreatedAfter: createdAfter,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.logger.Error("Failed to get companies", "error", err)
|
h.logger.Error("Failed to get companies", "error", err)
|
||||||
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get companies", err, nil)
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get companies", err, nil)
|
||||||
|
|
|
||||||
270
internal/web_server/handlers/customer.go
Normal file
270
internal/web_server/handlers/customer.go
Normal file
|
|
@ -0,0 +1,270 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type CustomersRes struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
FirstName string `json:"first_name"`
|
||||||
|
LastName string `json:"last_name"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
PhoneNumber string `json:"phone_number"`
|
||||||
|
Role domain.Role `json:"role"`
|
||||||
|
EmailVerified bool `json:"email_verified"`
|
||||||
|
PhoneVerified bool `json:"phone_verified"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
LastLogin time.Time `json:"last_login"`
|
||||||
|
SuspendedAt time.Time `json:"suspended_at"`
|
||||||
|
Suspended bool `json:"suspended"`
|
||||||
|
}
|
||||||
|
// GetAllCustomers godoc
|
||||||
|
// @Summary Get all Customers
|
||||||
|
// @Description Get all Customers
|
||||||
|
// @Tags customer
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param page query int false "Page number"
|
||||||
|
// @Param page_size query int false "Page size"
|
||||||
|
// @Success 200 {object} CustomersRes
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 401 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /customer [get]
|
||||||
|
func (h *Handler) GetAllCustomers(c *fiber.Ctx) error {
|
||||||
|
role := c.Locals("role").(domain.Role)
|
||||||
|
companyId := c.Locals("company_id").(domain.ValidInt64)
|
||||||
|
|
||||||
|
// Checking to make sure that admin user has a company id in the token
|
||||||
|
if role != domain.RoleSuperAdmin && !companyId.Valid {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Cannot get company ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
searchQuery := c.Query("query")
|
||||||
|
searchString := domain.ValidString{
|
||||||
|
Value: searchQuery,
|
||||||
|
Valid: searchQuery != "",
|
||||||
|
}
|
||||||
|
|
||||||
|
createdBeforeQuery := c.Query("created_before")
|
||||||
|
var createdBefore domain.ValidTime
|
||||||
|
if createdBeforeQuery != "" {
|
||||||
|
createdBeforeParsed, err := time.Parse(time.RFC3339, createdBeforeQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("invalid start_time format", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid start_time format", nil, nil)
|
||||||
|
}
|
||||||
|
createdBefore = domain.ValidTime{
|
||||||
|
Value: createdBeforeParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createdAfterQuery := c.Query("created_after")
|
||||||
|
var createdAfter domain.ValidTime
|
||||||
|
if createdAfterQuery != "" {
|
||||||
|
createdAfterParsed, err := time.Parse(time.RFC3339, createdAfterQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("invalid start_time format", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid start_time format", nil, nil)
|
||||||
|
}
|
||||||
|
createdAfter = domain.ValidTime{
|
||||||
|
Value: createdAfterParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filter := domain.UserFilter{
|
||||||
|
Role: string(domain.RoleCustomer),
|
||||||
|
CompanyID: companyId,
|
||||||
|
Page: domain.ValidInt{
|
||||||
|
Value: c.QueryInt("page", 1) - 1,
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
PageSize: domain.ValidInt{
|
||||||
|
Value: c.QueryInt("page_size", 10),
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
Query: searchString,
|
||||||
|
CreatedBefore: createdBefore,
|
||||||
|
CreatedAfter: createdAfter,
|
||||||
|
}
|
||||||
|
valErrs, ok := h.validator.Validate(c, filter)
|
||||||
|
if !ok {
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
||||||
|
}
|
||||||
|
customers, total, err := h.userSvc.GetAllUsers(c.Context(), filter)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("GetAllCustomers failed", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get Customers", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
var result []CustomersRes = make([]CustomersRes, len(customers))
|
||||||
|
for index, customer := range customers {
|
||||||
|
lastLogin, err := h.authSvc.GetLastLogin(c.Context(), customer.ID)
|
||||||
|
if err != nil {
|
||||||
|
if err == authentication.ErrRefreshTokenNotFound {
|
||||||
|
lastLogin = &customer.CreatedAt
|
||||||
|
} else {
|
||||||
|
h.logger.Error("Failed to get user last login", "userID", customer.ID, "error", err)
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve user last login")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result[index] = CustomersRes{
|
||||||
|
ID: customer.ID,
|
||||||
|
FirstName: customer.FirstName,
|
||||||
|
LastName: customer.LastName,
|
||||||
|
Email: customer.Email,
|
||||||
|
PhoneNumber: customer.PhoneNumber,
|
||||||
|
Role: customer.Role,
|
||||||
|
EmailVerified: customer.EmailVerified,
|
||||||
|
PhoneVerified: customer.PhoneVerified,
|
||||||
|
CreatedAt: customer.CreatedAt,
|
||||||
|
UpdatedAt: customer.UpdatedAt,
|
||||||
|
SuspendedAt: customer.SuspendedAt,
|
||||||
|
Suspended: customer.Suspended,
|
||||||
|
LastLogin: *lastLogin,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.WritePaginatedJSON(c, fiber.StatusOK, "Customers retrieved successfully", result, nil, filter.Page.Value, int(total))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCustomerByID godoc
|
||||||
|
// @Summary Get customer by id
|
||||||
|
// @Description Get a single customer by id
|
||||||
|
// @Tags customer
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "User ID"
|
||||||
|
// @Success 200 {object} CustomersRes
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 401 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /customer/{id} [get]
|
||||||
|
func (h *Handler) GetCustomerByID(c *fiber.Ctx) error {
|
||||||
|
userIDstr := c.Params("id")
|
||||||
|
userID, err := strconv.ParseInt(userIDstr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid customers ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := h.userSvc.GetUserByID(c.Context(), userID)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get customers")
|
||||||
|
}
|
||||||
|
|
||||||
|
lastLogin, err := h.authSvc.GetLastLogin(c.Context(), user.ID)
|
||||||
|
if err != nil {
|
||||||
|
if err != authentication.ErrRefreshTokenNotFound {
|
||||||
|
h.logger.Error("Failed to get user last login", "userID", user.ID, "error", err)
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve user last login")
|
||||||
|
}
|
||||||
|
|
||||||
|
lastLogin = &user.CreatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
res := CustomersRes{
|
||||||
|
ID: user.ID,
|
||||||
|
FirstName: user.FirstName,
|
||||||
|
LastName: user.LastName,
|
||||||
|
Email: user.Email,
|
||||||
|
PhoneNumber: user.PhoneNumber,
|
||||||
|
Role: user.Role,
|
||||||
|
EmailVerified: user.EmailVerified,
|
||||||
|
PhoneVerified: user.PhoneVerified,
|
||||||
|
CreatedAt: user.CreatedAt,
|
||||||
|
UpdatedAt: user.UpdatedAt,
|
||||||
|
SuspendedAt: user.SuspendedAt,
|
||||||
|
Suspended: user.Suspended,
|
||||||
|
LastLogin: *lastLogin,
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "User retrieved successfully", res, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
type updateCustomerReq struct {
|
||||||
|
FirstName string `json:"first_name" example:"John"`
|
||||||
|
LastName string `json:"last_name" example:"Doe"`
|
||||||
|
Suspended bool `json:"suspended" example:"false"`
|
||||||
|
CompanyID *int64 `json:"company_id,omitempty" example:"1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateCustomers godoc
|
||||||
|
// @Summary Update Customers
|
||||||
|
// @Description Update Customers
|
||||||
|
// @Tags customer
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param Customers body updateCustomerReq true "Update Customers"
|
||||||
|
// @Success 200 {object} response.APIResponse
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 401 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /customer/{id} [put]
|
||||||
|
func (h *Handler) UpdateCustomer(c *fiber.Ctx) error {
|
||||||
|
|
||||||
|
var req updateCustomerReq
|
||||||
|
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
h.logger.Error("UpdateCustomers failed", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
valErrs, ok := h.validator.Validate(c, req)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
||||||
|
}
|
||||||
|
CustomersIdStr := c.Params("id")
|
||||||
|
CustomersId, err := strconv.ParseInt(CustomersIdStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("UpdateCustomers failed", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid Customers ID", nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// var companyID domain.ValidInt64
|
||||||
|
// role := c.Locals("role").(domain.Role)
|
||||||
|
// if req.CompanyID != nil {
|
||||||
|
// if role != domain.RoleSuperAdmin {
|
||||||
|
// h.logger.Error("UpdateCustomers failed", "error", err)
|
||||||
|
// return response.WriteJSON(c, fiber.StatusUnauthorized, "This user role cannot modify company ID", nil, nil)
|
||||||
|
// }
|
||||||
|
// companyID = domain.ValidInt64{
|
||||||
|
// Value: *req.CompanyID,
|
||||||
|
// Valid: true,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
err = h.userSvc.UpdateUser(c.Context(), domain.UpdateUserReq{
|
||||||
|
UserId: CustomersId,
|
||||||
|
FirstName: domain.ValidString{
|
||||||
|
Value: req.FirstName,
|
||||||
|
Valid: req.FirstName != "",
|
||||||
|
},
|
||||||
|
LastName: domain.ValidString{
|
||||||
|
Value: req.LastName,
|
||||||
|
Valid: req.LastName != "",
|
||||||
|
},
|
||||||
|
Suspended: domain.ValidBool{
|
||||||
|
Value: req.Suspended,
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("UpdateCustomers failed", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update Customers", nil, nil)
|
||||||
|
}
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Customers updated successfully", nil, nil)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -123,6 +123,10 @@ func (a *App) initAppRoutes() {
|
||||||
a.fiber.Post("/cashiers", a.authMiddleware, h.CreateCashier)
|
a.fiber.Post("/cashiers", a.authMiddleware, h.CreateCashier)
|
||||||
a.fiber.Put("/cashiers/:id", a.authMiddleware, h.UpdateCashier)
|
a.fiber.Put("/cashiers/:id", a.authMiddleware, h.UpdateCashier)
|
||||||
|
|
||||||
|
a.fiber.Get("/customer", a.authMiddleware, a.SuperAdminOnly, h.GetAllCustomers)
|
||||||
|
a.fiber.Get("/customer/:id", a.authMiddleware, a.SuperAdminOnly, h.GetCustomerByID)
|
||||||
|
a.fiber.Put("/customer/:id", a.authMiddleware, a.SuperAdminOnly, h.UpdateCustomer)
|
||||||
|
|
||||||
a.fiber.Get("/admin", a.authMiddleware, h.GetAllAdmins)
|
a.fiber.Get("/admin", a.authMiddleware, h.GetAllAdmins)
|
||||||
a.fiber.Get("/admin/:id", a.authMiddleware, h.GetAdminByID)
|
a.fiber.Get("/admin/:id", a.authMiddleware, h.GetAdminByID)
|
||||||
a.fiber.Post("/admin", a.authMiddleware, h.CreateAdmin)
|
a.fiber.Post("/admin", a.authMiddleware, h.CreateAdmin)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user