170 lines
5.5 KiB
Go

package handlers
import (
"context"
"github.com/gin-gonic/gin"
"github.com/timetracker/backend/internal/api/dto"
"github.com/timetracker/backend/internal/api/responses"
"github.com/timetracker/backend/internal/api/utils"
"github.com/timetracker/backend/internal/models"
"github.com/timetracker/backend/internal/types"
)
// CompanyHandler handles company-related API endpoints
type CompanyHandler struct{}
// NewCompanyHandler creates a new CompanyHandler
func NewCompanyHandler() *CompanyHandler {
return &CompanyHandler{}
}
// GetCompanies handles GET /companies
//
// @Summary Get all companies
// @Description Get a list of all companies
// @Tags companies
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 200 {object} utils.Response{data=[]dto.CompanyDto}
// @Failure 401 {object} utils.Response{error=utils.ErrorInfo}
// @Failure 500 {object} utils.Response{error=utils.ErrorInfo}
// @Router /companies [get]
func (h *CompanyHandler) GetCompanies(c *gin.Context) {
utils.HandleGetAll(c, models.GetAllCompanies, convertCompanyToDTO, "companies")
}
// GetCompanyByID handles GET /companies/:id
//
// @Summary Get company by ID
// @Description Get a company by its ID
// @Tags companies
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "Company ID"
// @Success 200 {object} utils.Response{data=dto.CompanyDto}
// @Failure 400 {object} utils.Response{error=utils.ErrorInfo}
// @Failure 401 {object} utils.Response{error=utils.ErrorInfo}
// @Failure 404 {object} utils.Response{error=utils.ErrorInfo}
// @Failure 500 {object} utils.Response{error=utils.ErrorInfo}
// @Router /companies/{id} [get]
func (h *CompanyHandler) GetCompanyByID(c *gin.Context) {
utils.HandleGetByID(c, models.GetCompanyByID, convertCompanyToDTO, "company")
}
// CreateCompany handles POST /companies
//
// @Summary Create a new company
// @Description Create a new company
// @Tags companies
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param company body dto.CompanyCreateDto true "Company data"
// @Success 201 {object} utils.Response{data=dto.CompanyDto}
// @Failure 400 {object} utils.Response{error=utils.ErrorInfo}
// @Failure 401 {object} utils.Response{error=utils.ErrorInfo}
// @Failure 500 {object} utils.Response{error=utils.ErrorInfo}
// @Router /companies [post]
func (h *CompanyHandler) CreateCompany(c *gin.Context) {
utils.HandleCreate(c, createCompanyWrapper, convertCompanyToDTO, "company")
}
// UpdateCompany handles PUT /companies/:id
//
// @Summary Update a company
// @Description Update an existing company
// @Tags companies
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "Company ID"
// @Param company body dto.CompanyUpdateDto true "Company data"
// @Success 200 {object} utils.Response{data=dto.CompanyDto}
// @Failure 400 {object} utils.Response{error=utils.ErrorInfo}
// @Failure 401 {object} utils.Response{error=utils.ErrorInfo}
// @Failure 404 {object} utils.Response{error=utils.ErrorInfo}
// @Failure 500 {object} utils.Response{error=utils.ErrorInfo}
// @Router /companies/{id} [put]
func (h *CompanyHandler) UpdateCompany(c *gin.Context) {
utils.HandleUpdate(c, models.UpdateCompany, convertCompanyToDTO, prepareCompanyUpdate, "company")
}
// DeleteCompany handles DELETE /companies/:id
//
// @Summary Delete a company
// @Description Delete a company by its ID
// @Tags companies
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "Company ID"
// @Success 204 {object} utils.Response
// @Failure 400 {object} utils.Response{error=utils.ErrorInfo}
// @Failure 401 {object} utils.Response{error=utils.ErrorInfo}
// @Failure 500 {object} utils.Response{error=utils.ErrorInfo}
// @Router /companies/{id} [delete]
func (h *CompanyHandler) DeleteCompany(c *gin.Context) {
utils.HandleDelete(c, models.DeleteCompany, "company")
}
// Helper functions for DTO conversion
func convertCompanyToDTO(company *models.Company) dto.CompanyDto {
return dto.CompanyDto{
ID: company.ID.String(),
CreatedAt: company.CreatedAt,
UpdatedAt: company.UpdatedAt,
Name: company.Name,
}
}
func convertCreateCompanyDTOToModel(dto dto.CompanyCreateDto) models.CompanyCreate {
return models.CompanyCreate{
Name: dto.Name,
}
}
func convertUpdateCompanyDTOToModel(dto dto.CompanyUpdateDto, id types.ULID) models.CompanyUpdate {
update := models.CompanyUpdate{
ID: id,
}
if dto.Name != nil {
update.Name = dto.Name
}
return update
}
// prepareCompanyUpdate prepares the company update object by parsing the ID, binding the JSON, and converting the DTO to a model
func prepareCompanyUpdate(c *gin.Context) (models.CompanyUpdate, error) {
// Parse ID from URL
id, err := utils.ParseID(c, "id")
if err != nil {
responses.BadRequestResponse(c, "Invalid company ID format")
return models.CompanyUpdate{}, err
}
// Parse request body
var companyUpdateDTO dto.CompanyUpdateDto
if err := utils.BindJSON(c, &companyUpdateDTO); err != nil {
responses.BadRequestResponse(c, err.Error())
return models.CompanyUpdate{}, err
}
// Convert DTO to model
return convertUpdateCompanyDTOToModel(companyUpdateDTO, id), nil
}
// createCompanyWrapper is a wrapper function for models.CreateCompany that takes a DTO as input
func createCompanyWrapper(ctx context.Context, createDTO dto.CompanyCreateDto) (*models.Company, error) {
// Convert DTO to model
companyCreate := convertCreateCompanyDTOToModel(createDTO)
// Call the original function
return models.CreateCompany(ctx, companyCreate)
}