package handlers import ( "net/http" "github.com/gin-gonic/gin" "github.com/timetracker/backend/internal/api/utils" dto "github.com/timetracker/backend/internal/dtos" "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) { // Parse request body var companyCreateDTO dto.CompanyCreateDto if err := utils.BindJSON(c, &companyCreateDTO); err != nil { utils.BadRequestResponse(c, 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 id, err := utils.ParseID(c, "id") if err != nil { utils.BadRequestResponse(c, "Invalid company ID format") return } // Parse request body var companyUpdateDTO dto.CompanyUpdateDto if err := utils.BindJSON(c, &companyUpdateDTO); err != nil { utils.BadRequestResponse(c, err.Error()) return } // Convert DTO to model companyUpdate := convertUpdateCompanyDTOToModel(companyUpdateDTO, id) // 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) { 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 }