feat: company profile feature

This commit is contained in:
pahmiudahgede 2025-05-05 18:56:48 +07:00
parent b747fb06d0
commit 9a2481be09
10 changed files with 457 additions and 10 deletions

View File

@ -0,0 +1,65 @@
package dto
import (
"strings"
)
type ResponseCompanyProfileDTO struct {
ID string `json:"id"`
UserID string `json:"userId"`
CompanyName string `json:"company_name"`
CompanyAddress string `json:"company_address"`
CompanyPhone string `json:"company_phone"`
CompanyEmail string `json:"company_email"`
CompanyLogo string `json:"company_logo,omitempty"`
CompanyWebsite string `json:"company_website,omitempty"`
TaxID string `json:"taxId,omitempty"`
FoundedDate string `json:"founded_date,omitempty"`
CompanyType string `json:"company_type,omitempty"`
CompanyDescription string `json:"company_description"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
}
type RequestCompanyProfileDTO struct {
CompanyName string `json:"company_name"`
CompanyAddress string `json:"company_address"`
CompanyPhone string `json:"company_phone"`
CompanyEmail string `json:"company_email"`
CompanyLogo string `json:"company_logo,omitempty"`
CompanyWebsite string `json:"company_website,omitempty"`
TaxID string `json:"taxId,omitempty"`
FoundedDate string `json:"founded_date,omitempty"`
CompanyType string `json:"company_type,omitempty"`
CompanyDescription string `json:"company_description"`
}
func (r *RequestCompanyProfileDTO) ValidateCompanyProfileInput() (map[string][]string, bool) {
errors := make(map[string][]string)
if strings.TrimSpace(r.CompanyName) == "" {
errors["company_Name"] = append(errors["company_name"], "Company name is required")
}
if strings.TrimSpace(r.CompanyAddress) == "" {
errors["company_Address"] = append(errors["company_address"], "Company address is required")
}
if strings.TrimSpace(r.CompanyPhone) == "" {
errors["company_Phone"] = append(errors["company_phone"], "Company phone is required")
}
if strings.TrimSpace(r.CompanyEmail) == "" {
errors["company_Email"] = append(errors["company_email"], "Company email is required")
}
if strings.TrimSpace(r.CompanyDescription) == "" {
errors["company_Description"] = append(errors["company_description"], "Company description is required")
}
if len(errors) > 0 {
return errors, false
}
return nil, true
}

View File

@ -0,0 +1,100 @@
package handler
import (
"fmt"
"rijig/dto"
"rijig/internal/services"
"rijig/utils"
"github.com/gofiber/fiber/v2"
)
type CompanyProfileHandler struct {
companyProfileService services.CompanyProfileService
}
func NewCompanyProfileHandler(service services.CompanyProfileService) *CompanyProfileHandler {
return &CompanyProfileHandler{
companyProfileService: service,
}
}
func (h *CompanyProfileHandler) CreateCompanyProfile(c *fiber.Ctx) error {
userID, ok := c.Locals("userID").(string)
if !ok || userID == "" {
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
}
var requestDTO dto.RequestCompanyProfileDTO
if err := c.BodyParser(&requestDTO); err != nil {
return utils.ValidationErrorResponse(c, map[string][]string{"body": {"Invalid input data"}})
}
companyProfileResponse, err := h.companyProfileService.CreateCompanyProfile(userID, &requestDTO)
if err != nil {
return utils.ErrorResponse(c, fmt.Sprintf("Failed to create company profile: %v", err))
}
return utils.SuccessResponse(c, companyProfileResponse, "Company profile created successfully")
}
func (h *CompanyProfileHandler) GetCompanyProfileByID(c *fiber.Ctx) error {
id := c.Params("company_id")
companyProfileResponse, err := h.companyProfileService.GetCompanyProfileByID(id)
if err != nil {
return utils.ErrorResponse(c, fmt.Sprintf("Failed to fetch company profile: %v", err))
}
return utils.SuccessResponse(c, companyProfileResponse, "Company profile fetched successfully")
}
func (h *CompanyProfileHandler) GetCompanyProfilesByUserID(c *fiber.Ctx) error {
userID, ok := c.Locals("userID").(string)
if !ok || userID == "" {
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
}
companyProfilesResponse, err := h.companyProfileService.GetCompanyProfilesByUserID(userID)
if err != nil {
return utils.ErrorResponse(c, fmt.Sprintf("Failed to fetch company profiles: %v", err))
}
return utils.NonPaginatedResponse(c, companyProfilesResponse, len(companyProfilesResponse), "Company profiles fetched successfully")
}
func (h *CompanyProfileHandler) UpdateCompanyProfile(c *fiber.Ctx) error {
userID, ok := c.Locals("userID").(string)
if !ok || userID == "" {
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
}
id := c.Params("company_id")
var requestDTO dto.RequestCompanyProfileDTO
if err := c.BodyParser(&requestDTO); err != nil {
return utils.ValidationErrorResponse(c, map[string][]string{"body": {"Invalid input data"}})
}
companyProfileResponse, err := h.companyProfileService.UpdateCompanyProfile(id, &requestDTO)
if err != nil {
return utils.ErrorResponse(c, fmt.Sprintf("Failed to update company profile: %v", err))
}
return utils.SuccessResponse(c, companyProfileResponse, "Company profile updated successfully")
}
func (h *CompanyProfileHandler) DeleteCompanyProfile(c *fiber.Ctx) error {
userID, ok := c.Locals("userID").(string)
if !ok || userID == "" {
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
}
id := c.Params("company_id")
err := h.companyProfileService.DeleteCompanyProfile(id)
if err != nil {
return utils.ErrorResponse(c, fmt.Sprintf("Failed to delete company profile: %v", err))
}
return utils.SuccessResponse(c, nil, "Company profile deleted successfully")
}

View File

@ -0,0 +1,78 @@
package repositories
import (
"fmt"
"rijig/model"
"gorm.io/gorm"
)
type CompanyProfileRepository interface {
CreateCompanyProfile(companyProfile *model.CompanyProfile) (*model.CompanyProfile, error)
GetCompanyProfileByID(id string) (*model.CompanyProfile, error)
GetCompanyProfilesByUserID(userID string) ([]model.CompanyProfile, error)
UpdateCompanyProfile(id string, companyProfile *model.CompanyProfile) (*model.CompanyProfile, error)
DeleteCompanyProfile(id string) error
}
type companyProfileRepository struct {
DB *gorm.DB
}
func NewCompanyProfileRepository(db *gorm.DB) CompanyProfileRepository {
return &companyProfileRepository{
DB: db,
}
}
func (r *companyProfileRepository) CreateCompanyProfile(companyProfile *model.CompanyProfile) (*model.CompanyProfile, error) {
err := r.DB.Create(companyProfile).Error
if err != nil {
return nil, fmt.Errorf("failed to create company profile: %v", err)
}
return companyProfile, nil
}
func (r *companyProfileRepository) GetCompanyProfileByID(id string) (*model.CompanyProfile, error) {
var companyProfile model.CompanyProfile
err := r.DB.Preload("User").First(&companyProfile, "id = ?", id).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, fmt.Errorf("company profile with ID %s not found", id)
}
return nil, fmt.Errorf("error fetching company profile: %v", err)
}
return &companyProfile, nil
}
func (r *companyProfileRepository) GetCompanyProfilesByUserID(userID string) ([]model.CompanyProfile, error) {
var companyProfiles []model.CompanyProfile
err := r.DB.Preload("User").Where("user_id = ?", userID).Find(&companyProfiles).Error
if err != nil {
return nil, fmt.Errorf("error fetching company profiles for userID %s: %v", userID, err)
}
return companyProfiles, nil
}
func (r *companyProfileRepository) UpdateCompanyProfile(id string, companyProfile *model.CompanyProfile) (*model.CompanyProfile, error) {
var existingProfile model.CompanyProfile
err := r.DB.First(&existingProfile, "id = ?", id).Error
if err != nil {
return nil, fmt.Errorf("company profile not found: %v", err)
}
err = r.DB.Model(&existingProfile).Updates(companyProfile).Error
if err != nil {
return nil, fmt.Errorf("failed to update company profile: %v", err)
}
return &existingProfile, nil
}
func (r *companyProfileRepository) DeleteCompanyProfile(id string) error {
err := r.DB.Delete(&model.CompanyProfile{}, "id = ?", id).Error
if err != nil {
return fmt.Errorf("failed to delete company profile: %v", err)
}
return nil
}

View File

@ -0,0 +1,163 @@
package services
import (
"fmt"
"rijig/dto"
"rijig/internal/repositories"
"rijig/model"
"rijig/utils"
)
type CompanyProfileService interface {
CreateCompanyProfile(userID string, request *dto.RequestCompanyProfileDTO) (*dto.ResponseCompanyProfileDTO, error)
GetCompanyProfileByID(id string) (*dto.ResponseCompanyProfileDTO, error)
GetCompanyProfilesByUserID(userID string) ([]dto.ResponseCompanyProfileDTO, error)
UpdateCompanyProfile(id string, request *dto.RequestCompanyProfileDTO) (*dto.ResponseCompanyProfileDTO, error)
DeleteCompanyProfile(id string) error
}
type companyProfileService struct {
companyProfileRepo repositories.CompanyProfileRepository
}
func NewCompanyProfileService(companyProfileRepo repositories.CompanyProfileRepository) CompanyProfileService {
return &companyProfileService{
companyProfileRepo: companyProfileRepo,
}
}
func FormatResponseCompanyProfile(companyProfile *model.CompanyProfile) (*dto.ResponseCompanyProfileDTO, error) {
createdAt, _ := utils.FormatDateToIndonesianFormat(companyProfile.CreatedAt)
updatedAt, _ := utils.FormatDateToIndonesianFormat(companyProfile.UpdatedAt)
responseDTO := &dto.ResponseCompanyProfileDTO{
ID: companyProfile.ID,
UserID: companyProfile.UserID,
CompanyName: companyProfile.CompanyName,
CompanyAddress: companyProfile.CompanyAddress,
CompanyPhone: companyProfile.CompanyPhone,
CompanyEmail: companyProfile.CompanyEmail,
CompanyLogo: companyProfile.CompanyLogo,
CompanyWebsite: companyProfile.CompanyWebsite,
TaxID: companyProfile.TaxID,
FoundedDate: companyProfile.FoundedDate,
CompanyType: companyProfile.CompanyType,
CompanyDescription: companyProfile.CompanyDescription,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}
return responseDTO, nil
}
func (s *companyProfileService) CreateCompanyProfile(userID string, request *dto.RequestCompanyProfileDTO) (*dto.ResponseCompanyProfileDTO, error) {
errors, valid := request.ValidateCompanyProfileInput()
if !valid {
return nil, fmt.Errorf("validation failed: %v", errors)
}
companyProfile := &model.CompanyProfile{
UserID: userID,
CompanyName: request.CompanyName,
CompanyAddress: request.CompanyAddress,
CompanyPhone: request.CompanyPhone,
CompanyEmail: request.CompanyEmail,
CompanyLogo: request.CompanyLogo,
CompanyWebsite: request.CompanyWebsite,
TaxID: request.TaxID,
FoundedDate: request.FoundedDate,
CompanyType: request.CompanyType,
CompanyDescription: request.CompanyDescription,
}
createdCompanyProfile, err := s.companyProfileRepo.CreateCompanyProfile(companyProfile)
if err != nil {
return nil, fmt.Errorf("failed to create company profile: %v", err)
}
responseDTO, err := FormatResponseCompanyProfile(createdCompanyProfile)
if err != nil {
return nil, fmt.Errorf("failed to format company profile response: %v", err)
}
return responseDTO, nil
}
func (s *companyProfileService) GetCompanyProfileByID(id string) (*dto.ResponseCompanyProfileDTO, error) {
companyProfile, err := s.companyProfileRepo.GetCompanyProfileByID(id)
if err != nil {
return nil, fmt.Errorf("error retrieving company profile by ID: %v", err)
}
responseDTO, err := FormatResponseCompanyProfile(companyProfile)
if err != nil {
return nil, fmt.Errorf("error formatting company profile response: %v", err)
}
return responseDTO, nil
}
func (s *companyProfileService) GetCompanyProfilesByUserID(userID string) ([]dto.ResponseCompanyProfileDTO, error) {
companyProfiles, err := s.companyProfileRepo.GetCompanyProfilesByUserID(userID)
if err != nil {
return nil, fmt.Errorf("error retrieving company profiles by userID: %v", err)
}
var responseDTOs []dto.ResponseCompanyProfileDTO
for _, companyProfile := range companyProfiles {
responseDTO, err := FormatResponseCompanyProfile(&companyProfile)
if err != nil {
return nil, fmt.Errorf("error formatting company profile response: %v", err)
}
responseDTOs = append(responseDTOs, *responseDTO)
}
return responseDTOs, nil
}
func (s *companyProfileService) UpdateCompanyProfile(id string, request *dto.RequestCompanyProfileDTO) (*dto.ResponseCompanyProfileDTO, error) {
errors, valid := request.ValidateCompanyProfileInput()
if !valid {
return nil, fmt.Errorf("validation failed: %v", errors)
}
companyProfile := &model.CompanyProfile{
CompanyName: request.CompanyName,
CompanyAddress: request.CompanyAddress,
CompanyPhone: request.CompanyPhone,
CompanyEmail: request.CompanyEmail,
CompanyLogo: request.CompanyLogo,
CompanyWebsite: request.CompanyWebsite,
TaxID: request.TaxID,
FoundedDate: request.FoundedDate,
CompanyType: request.CompanyType,
CompanyDescription: request.CompanyDescription,
}
updatedCompanyProfile, err := s.companyProfileRepo.UpdateCompanyProfile(id, companyProfile)
if err != nil {
return nil, fmt.Errorf("failed to update company profile: %v", err)
}
responseDTO, err := FormatResponseCompanyProfile(updatedCompanyProfile)
if err != nil {
return nil, fmt.Errorf("failed to format company profile response: %v", err)
}
return responseDTO, nil
}
func (s *companyProfileService) DeleteCompanyProfile(id string) error {
err := s.companyProfileRepo.DeleteCompanyProfile(id)
if err != nil {
return fmt.Errorf("failed to delete company profile: %v", err)
}
return nil
}

View File

@ -22,11 +22,13 @@ type IdentityCardService interface {
type identityCardService struct {
identityCardRepo repositories.IdentityCardRepository
userRepo repositories.UserProfileRepository
}
func NewIdentityCardService(identityCardRepo repositories.IdentityCardRepository) IdentityCardService {
func NewIdentityCardService(identityCardRepo repositories.IdentityCardRepository, userRepo repositories.UserProfileRepository) IdentityCardService {
return &identityCardService{
identityCardRepo: identityCardRepo,
userRepo: userRepo,
}
}
@ -156,6 +158,17 @@ func (s *identityCardService) CreateIdentityCard(userID string, request *dto.Req
return nil, fmt.Errorf("failed to create identity card: %v", err)
}
user, err := s.userRepo.FindByID(userID)
if err != nil {
return nil, fmt.Errorf("failde to fint user: %v", err)
}
user.RegistrationStatus = "onreview"
err = s.userRepo.Update(user)
if err != nil {
return nil, fmt.Errorf("failed to update user: %v", err)
}
idcardResponseDTO, _ := FormatResponseIdentityCars(identityCard)
return idcardResponseDTO, nil

View File

@ -12,13 +12,12 @@ type CompanyProfile struct {
CompanyAddress string `gorm:"not null" json:"company_address"`
CompanyPhone string `gorm:"not null" json:"company_phone"`
CompanyEmail string `gorm:"not null" json:"company_email"`
CompanyLogo string `gorm:"not null" json:"company_logo"`
CompanyWebsite string `json:"company_website"`
TaxID string `json:"tax_id"`
FoundedDate time.Time `json:"founded_date"`
CompanyType string `gorm:"not null" json:"company_type"`
CompanyLogo string `json:"company_logo,omitempty"`
CompanyWebsite string `json:"company_website,omitempty"`
TaxID string `json:"tax_id,omitempty"`
FoundedDate string `json:"founded_date,omitempty"`
CompanyType string `json:"company_type,omitempty"`
CompanyDescription string `gorm:"type:text" json:"company_description"`
CompanyStatus string `gorm:"not null" json:"company_status"`
CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
}

View File

@ -13,7 +13,7 @@ import (
"github.com/gofiber/fiber/v2"
)
func AdminAuthRouter(api fiber.Router) {
func AuthAdminRouter(api fiber.Router) {
secretKey := os.Getenv("SECRET_KEY")
if secretKey == "" {
log.Fatal("SECRET_KEY is not set in the environment variables")

View File

@ -0,0 +1,27 @@
package presentation
import (
"rijig/config"
"rijig/internal/handler"
"rijig/internal/repositories"
"rijig/internal/services"
"rijig/middleware"
"github.com/gofiber/fiber/v2"
)
func CompanyProfileRouter(api fiber.Router) {
companyProfileRepo := repositories.NewCompanyProfileRepository(config.DB)
companyProfileService := services.NewCompanyProfileService(companyProfileRepo)
companyProfileHandler := handler.NewCompanyProfileHandler(companyProfileService)
companyProfileAPI := api.Group("/company-profile")
companyProfileAPI.Use(middleware.AuthMiddleware)
companyProfileAPI.Post("/create", companyProfileHandler.CreateCompanyProfile)
companyProfileAPI.Get("/get/:company_id", companyProfileHandler.GetCompanyProfileByID)
companyProfileAPI.Get("/get", companyProfileHandler.GetCompanyProfilesByUserID)
companyProfileAPI.Put("/update/:company_id", companyProfileHandler.UpdateCompanyProfile)
companyProfileAPI.Delete("/delete/:company_id", companyProfileHandler.DeleteCompanyProfile)
}

View File

@ -13,7 +13,8 @@ import (
func IdentityCardRouter(api fiber.Router) {
identityCardRepo := repositories.NewIdentityCardRepository(config.DB)
identityCardService := services.NewIdentityCardService(identityCardRepo)
userRepo := repositories.NewUserProfileRepository(config.DB)
identityCardService := services.NewIdentityCardService(identityCardRepo, userRepo)
identityCardHandler := handler.NewIdentityCardHandler(identityCardService)
identityCardApi := api.Group("/identitycard")

View File

@ -18,12 +18,13 @@ func SetupRoutes(app *fiber.App) {
// || auth router || //
// presentation.AuthRouter(api)
presentationn.AdminAuthRouter(api)
presentationn.AuthAdminRouter(api)
presentationn.AuthPengelolaRouter(api)
presentationn.AuthPengepulRouter(api)
presentationn.AuthMasyarakatRouter(api)
// || auth router || //
presentation.IdentityCardRouter(api)
presentation.CompanyProfileRouter(api)
presentation.UserProfileRouter(api)
presentation.UserPinRouter(api)