248 lines
7.0 KiB
Go
248 lines
7.0 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/oklog/ulid/v2"
|
|
"github.com/timetracker/backend/internal/api/utils"
|
|
dto "github.com/timetracker/backend/internal/dtos"
|
|
"github.com/timetracker/backend/internal/models"
|
|
)
|
|
|
|
// 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) {
|
|
// Get companies from the database
|
|
companies, err := models.GetAllCompanies(c.Request.Context())
|
|
if err != nil {
|
|
utils.InternalErrorResponse(c, "Error retrieving companies: "+err.Error())
|
|
return
|
|
}
|
|
|
|
// Convert to DTOs
|
|
companyDTOs := make([]dto.CompanyDto, len(companies))
|
|
for i, company := range companies {
|
|
companyDTOs[i] = convertCompanyToDTO(&company)
|
|
}
|
|
|
|
utils.SuccessResponse(c, http.StatusOK, companyDTOs)
|
|
}
|
|
|
|
// 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) {
|
|
// Parse ID from URL
|
|
idStr := c.Param("id")
|
|
id, err := ulid.Parse(idStr)
|
|
if err != nil {
|
|
utils.BadRequestResponse(c, "Invalid company ID format")
|
|
return
|
|
}
|
|
|
|
// Get company from the database
|
|
company, err := models.GetCompanyByID(c.Request.Context(), models.FromULID(id))
|
|
if err != nil {
|
|
utils.InternalErrorResponse(c, "Error retrieving company: "+err.Error())
|
|
return
|
|
}
|
|
|
|
if company == nil {
|
|
utils.NotFoundResponse(c, "Company not found")
|
|
return
|
|
}
|
|
|
|
// Convert to DTO
|
|
companyDTO := convertCompanyToDTO(company)
|
|
|
|
utils.SuccessResponse(c, http.StatusOK, companyDTO)
|
|
}
|
|
|
|
// 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) {
|
|
// Parse request body
|
|
var companyCreateDTO dto.CompanyCreateDto
|
|
if err := c.ShouldBindJSON(&companyCreateDTO); err != nil {
|
|
utils.BadRequestResponse(c, "Invalid request body: "+err.Error())
|
|
return
|
|
}
|
|
|
|
// Convert DTO to model
|
|
companyCreate := convertCreateCompanyDTOToModel(companyCreateDTO)
|
|
|
|
// Create company in the database
|
|
company, err := models.CreateCompany(c.Request.Context(), companyCreate)
|
|
if err != nil {
|
|
utils.InternalErrorResponse(c, "Error creating company: "+err.Error())
|
|
return
|
|
}
|
|
|
|
// Convert to DTO
|
|
companyDTO := convertCompanyToDTO(company)
|
|
|
|
utils.SuccessResponse(c, http.StatusCreated, companyDTO)
|
|
}
|
|
|
|
// 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) {
|
|
// Parse ID from URL
|
|
idStr := c.Param("id")
|
|
id, err := ulid.Parse(idStr)
|
|
if err != nil {
|
|
utils.BadRequestResponse(c, "Invalid company ID format")
|
|
return
|
|
}
|
|
|
|
// Parse request body
|
|
var companyUpdateDTO dto.CompanyUpdateDto
|
|
if err := c.ShouldBindJSON(&companyUpdateDTO); err != nil {
|
|
utils.BadRequestResponse(c, "Invalid request body: "+err.Error())
|
|
return
|
|
}
|
|
|
|
// Set ID from URL
|
|
companyUpdateDTO.ID = id.String()
|
|
|
|
// Convert DTO to model
|
|
companyUpdate := convertUpdateCompanyDTOToModel(companyUpdateDTO)
|
|
|
|
// Update company in the database
|
|
company, err := models.UpdateCompany(c.Request.Context(), companyUpdate)
|
|
if err != nil {
|
|
utils.InternalErrorResponse(c, "Error updating company: "+err.Error())
|
|
return
|
|
}
|
|
|
|
if company == nil {
|
|
utils.NotFoundResponse(c, "Company not found")
|
|
return
|
|
}
|
|
|
|
// Convert to DTO
|
|
companyDTO := convertCompanyToDTO(company)
|
|
|
|
utils.SuccessResponse(c, http.StatusOK, companyDTO)
|
|
}
|
|
|
|
// 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) {
|
|
// Parse ID from URL
|
|
idStr := c.Param("id")
|
|
id, err := ulid.Parse(idStr)
|
|
if err != nil {
|
|
utils.BadRequestResponse(c, "Invalid company ID format")
|
|
return
|
|
}
|
|
|
|
// Delete company from the database
|
|
err = models.DeleteCompany(c.Request.Context(), models.FromULID(id))
|
|
if err != nil {
|
|
utils.InternalErrorResponse(c, "Error deleting company: "+err.Error())
|
|
return
|
|
}
|
|
|
|
utils.SuccessResponse(c, http.StatusNoContent, nil)
|
|
}
|
|
|
|
// 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) models.CompanyUpdate {
|
|
id, _ := ulid.Parse(dto.ID)
|
|
update := models.CompanyUpdate{
|
|
ID: models.FromULID(id),
|
|
}
|
|
|
|
if dto.Name != nil {
|
|
update.Name = dto.Name
|
|
}
|
|
|
|
return update
|
|
}
|