MIF_E31222379_BE/internal/services/about_service.go

427 lines
12 KiB
Go

package services
import (
"fmt"
"log"
"mime/multipart"
"os"
"path/filepath"
"rijig/dto"
"rijig/internal/repositories"
"rijig/model"
"rijig/utils"
"github.com/google/uuid"
)
type AboutService interface {
CreateAbout(request dto.RequestAboutDTO, coverImageAbout *multipart.FileHeader) (*dto.ResponseAboutDTO, error)
UpdateAbout(id string, request dto.RequestAboutDTO, coverImageAbout *multipart.FileHeader) (*dto.ResponseAboutDTO, error)
GetAllAbout() ([]dto.ResponseAboutDTO, error)
GetAboutByID(id string) (*dto.ResponseAboutDTO, error)
GetAboutDetailById(id string) (*dto.ResponseAboutDetailDTO, error)
DeleteAbout(id string) error
CreateAboutDetail(request dto.RequestAboutDetailDTO, coverImageAboutDetail *multipart.FileHeader) (*dto.ResponseAboutDetailDTO, error)
UpdateAboutDetail(id string, request dto.RequestAboutDetailDTO, imageDetail *multipart.FileHeader) (*dto.ResponseAboutDetailDTO, error)
DeleteAboutDetail(id string) error
}
type aboutService struct {
aboutRepo repositories.AboutRepository
}
func NewAboutService(aboutRepo repositories.AboutRepository) AboutService {
return &aboutService{aboutRepo: aboutRepo}
}
func formatResponseAboutDetailDTO(about *model.AboutDetail) (*dto.ResponseAboutDetailDTO, error) {
createdAt, _ := utils.FormatDateToIndonesianFormat(about.CreatedAt)
updatedAt, _ := utils.FormatDateToIndonesianFormat(about.UpdatedAt)
response := &dto.ResponseAboutDetailDTO{
ID: about.ID,
AboutID: about.AboutID,
ImageDetail: about.ImageDetail,
Description: about.Description,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}
return response, nil
}
func formatResponseAboutDTO(about *model.About) (*dto.ResponseAboutDTO, error) {
createdAt, _ := utils.FormatDateToIndonesianFormat(about.CreatedAt)
updatedAt, _ := utils.FormatDateToIndonesianFormat(about.UpdatedAt)
response := &dto.ResponseAboutDTO{
ID: about.ID,
Title: about.Title,
CoverImage: about.CoverImage,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}
return response, nil
}
func (s *aboutService) saveCoverImageAbout(coverImageAbout *multipart.FileHeader) (string, error) {
pathImage := "/uploads/coverabout/"
coverImageAboutDir := "./public" + os.Getenv("BASE_URL") + pathImage
if _, err := os.Stat(coverImageAboutDir); os.IsNotExist(err) {
if err := os.MkdirAll(coverImageAboutDir, os.ModePerm); err != nil {
return "", fmt.Errorf("gagal membuat direktori untuk cover image about: %v", err)
}
}
allowedExtensions := map[string]bool{".jpg": true, ".jpeg": true, ".png": true, ".svg": true}
extension := filepath.Ext(coverImageAbout.Filename)
if !allowedExtensions[extension] {
return "", fmt.Errorf("invalid file type, only .jpg, .jpeg, and .png are allowed")
}
coverImageFileName := fmt.Sprintf("%s_coverabout%s", uuid.New().String(), extension)
coverImagePath := filepath.Join(coverImageAboutDir, coverImageFileName)
src, err := coverImageAbout.Open()
if err != nil {
return "", fmt.Errorf("failed to open uploaded file: %v", err)
}
defer src.Close()
dst, err := os.Create(coverImagePath)
if err != nil {
return "", fmt.Errorf("failed to create cover image about file: %v", err)
}
defer dst.Close()
if _, err := dst.ReadFrom(src); err != nil {
return "", fmt.Errorf("failed to save cover image about: %v", err)
}
coverImageAboutUrl := fmt.Sprintf("%s%s", pathImage, coverImageFileName)
return coverImageAboutUrl, nil
}
func (s *aboutService) saveCoverImageAboutDetail(coverImageAbout *multipart.FileHeader) (string, error) {
pathImage := "/uploads/coverabout/coveraboutdetail"
coverImageAboutDir := "./public" + os.Getenv("BASE_URL") + pathImage
if _, err := os.Stat(coverImageAboutDir); os.IsNotExist(err) {
if err := os.MkdirAll(coverImageAboutDir, os.ModePerm); err != nil {
return "", fmt.Errorf("gagal membuat direktori untuk cover image about: %v", err)
}
}
allowedExtensions := map[string]bool{".jpg": true, ".jpeg": true, ".png": true, ".svg": true}
extension := filepath.Ext(coverImageAbout.Filename)
if !allowedExtensions[extension] {
return "", fmt.Errorf("invalid file type, only .jpg, .jpeg, and .png are allowed")
}
coverImageFileName := fmt.Sprintf("%s_coveraboutdetail_%s", uuid.New().String(), extension)
coverImagePath := filepath.Join(coverImageAboutDir, coverImageFileName)
src, err := coverImageAbout.Open()
if err != nil {
return "", fmt.Errorf("failed to open uploaded file: %v", err)
}
defer src.Close()
dst, err := os.Create(coverImagePath)
if err != nil {
return "", fmt.Errorf("failed to create cover image about file: %v", err)
}
defer dst.Close()
if _, err := dst.ReadFrom(src); err != nil {
return "", fmt.Errorf("failed to save cover image about: %v", err)
}
coverImageAboutUrl := fmt.Sprintf("%s%s", pathImage, coverImageFileName)
return coverImageAboutUrl, nil
}
func deleteCoverImageAbout(coverimageAboutPath string) error {
if coverimageAboutPath == "" {
return nil
}
baseDir := "./public/" + os.Getenv("BASE_URL")
absolutePath := baseDir + coverimageAboutPath
if _, err := os.Stat(absolutePath); os.IsNotExist(err) {
return fmt.Errorf("image file not found: %v", err)
}
err := os.Remove(absolutePath)
if err != nil {
return fmt.Errorf("failed to delete image: %v", err)
}
log.Printf("Image deleted successfully: %s", absolutePath)
return nil
}
func (s *aboutService) CreateAbout(request dto.RequestAboutDTO, coverImageAbout *multipart.FileHeader) (*dto.ResponseAboutDTO, error) {
errors, valid := request.ValidateAbout()
if !valid {
return nil, fmt.Errorf("validation error: %v", errors)
}
coverImageAboutPath, err := s.saveCoverImageAbout(coverImageAbout)
if err != nil {
return nil, fmt.Errorf("gagal menyimpan cover image about: %v ", err)
}
about := model.About{
Title: request.Title,
CoverImage: coverImageAboutPath,
}
if err := s.aboutRepo.CreateAbout(&about); err != nil {
return nil, fmt.Errorf("failed to create About: %v", err)
}
response, err := formatResponseAboutDTO(&about)
if err != nil {
return nil, fmt.Errorf("error formatting About response: %v", err)
}
return response, nil
}
func (s *aboutService) UpdateAbout(id string, request dto.RequestAboutDTO, coverImageAbout *multipart.FileHeader) (*dto.ResponseAboutDTO, error) {
errors, valid := request.ValidateAbout()
if !valid {
return nil, fmt.Errorf("validation error: %v", errors)
}
about, err := s.aboutRepo.GetAboutByID(id)
if err != nil {
return nil, fmt.Errorf("about not found: %v", err)
}
if about.CoverImage != "" {
err := deleteCoverImageAbout(about.CoverImage)
if err != nil {
return nil, fmt.Errorf("gagal mengahpus gambar lama: %v", err)
}
}
var coverImageAboutPath string
if coverImageAbout != nil {
coverImageAboutPath, err = s.saveCoverImageAbout(coverImageAbout)
if err != nil {
return nil, fmt.Errorf("gagal menyimpan gambar baru: %v", err)
}
}
about.Title = request.Title
if coverImageAboutPath != "" {
about.CoverImage = coverImageAboutPath
}
updatedAbout, err := s.aboutRepo.UpdateAbout(id, about)
if err != nil {
return nil, fmt.Errorf("failed to update About: %v", err)
}
response, err := formatResponseAboutDTO(updatedAbout)
if err != nil {
return nil, fmt.Errorf("error formatting About response: %v", err)
}
return response, nil
}
func (s *aboutService) GetAllAbout() ([]dto.ResponseAboutDTO, error) {
aboutList, err := s.aboutRepo.GetAllAbout()
if err != nil {
return nil, fmt.Errorf("failed to get About list: %v", err)
}
var aboutDTOList []dto.ResponseAboutDTO
for _, about := range aboutList {
response, err := formatResponseAboutDTO(&about)
if err != nil {
log.Printf("Error formatting About response: %v", err)
continue
}
aboutDTOList = append(aboutDTOList, *response)
}
return aboutDTOList, nil
}
func (s *aboutService) GetAboutByID(id string) (*dto.ResponseAboutDTO, error) {
about, err := s.aboutRepo.GetAboutByID(id)
if err != nil {
return nil, fmt.Errorf("about not found: %v", err)
}
response, err := formatResponseAboutDTO(about)
if err != nil {
return nil, fmt.Errorf("error formatting About response: %v", err)
}
return response, nil
}
func (s *aboutService) GetAboutDetailById(id string) (*dto.ResponseAboutDetailDTO, error) {
about, err := s.aboutRepo.GetAboutDetailByID(id)
if err != nil {
return nil, fmt.Errorf("about not found: %v", err)
}
response, err := formatResponseAboutDetailDTO(about)
if err != nil {
return nil, fmt.Errorf("error formatting About response: %v", err)
}
return response, nil
}
func (s *aboutService) DeleteAbout(id string) error {
about, err := s.aboutRepo.GetAboutByID(id)
if err != nil {
return fmt.Errorf("about not found: %v", err)
}
if about.CoverImage != "" {
err := deleteCoverImageAbout(about.CoverImage)
if err != nil {
return fmt.Errorf("gagal mengahpus gambar lama: %v", err)
}
}
if err := s.aboutRepo.DeleteAbout(id); err != nil {
return fmt.Errorf("failed to delete About: %v", err)
}
return nil
}
func (s *aboutService) CreateAboutDetail(request dto.RequestAboutDetailDTO, coverImageAboutDetail *multipart.FileHeader) (*dto.ResponseAboutDetailDTO, error) {
errors, valid := request.ValidateAboutDetail()
if !valid {
return nil, fmt.Errorf("validation error: %v", errors)
}
_, err := s.aboutRepo.GetAboutByID(request.AboutId)
if err != nil {
return nil, fmt.Errorf("about_id tidak ditemukan: %v", err)
}
coverImageAboutDetailPath, err := s.saveCoverImageAboutDetail(coverImageAboutDetail)
if err != nil {
return nil, fmt.Errorf("gagal menyimpan cover image about detail: %v ", err)
}
aboutDetail := model.AboutDetail{
AboutID: request.AboutId,
ImageDetail: coverImageAboutDetailPath,
Description: request.Description,
}
if err := s.aboutRepo.CreateAboutDetail(&aboutDetail); err != nil {
return nil, fmt.Errorf("failed to create AboutDetail: %v", err)
}
createdAt, _ := utils.FormatDateToIndonesianFormat(aboutDetail.CreatedAt)
updatedAt, _ := utils.FormatDateToIndonesianFormat(aboutDetail.UpdatedAt)
response := &dto.ResponseAboutDetailDTO{
ID: aboutDetail.ID,
AboutID: aboutDetail.AboutID,
ImageDetail: aboutDetail.ImageDetail,
Description: aboutDetail.Description,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}
return response, nil
}
func (s *aboutService) UpdateAboutDetail(id string, request dto.RequestAboutDetailDTO, imageDetail *multipart.FileHeader) (*dto.ResponseAboutDetailDTO, error) {
errors, valid := request.ValidateAboutDetail()
if !valid {
return nil, fmt.Errorf("validation error: %v", errors)
}
aboutDetail, err := s.aboutRepo.GetAboutDetailByID(id)
if err != nil {
return nil, fmt.Errorf("about detail tidakck ditemukan: %v", err)
}
if aboutDetail.ImageDetail != "" {
err := deleteCoverImageAbout(aboutDetail.ImageDetail)
if err != nil {
return nil, fmt.Errorf("gagal menghapus gambar lama: %v", err)
}
}
var coverImageAboutDeatilPath string
if imageDetail != nil {
coverImageAboutDeatilPath, err = s.saveCoverImageAbout(imageDetail)
if err != nil {
return nil, fmt.Errorf("gagal menyimpan gambar baru: %v", err)
}
}
aboutDetail.Description = request.Description
if coverImageAboutDeatilPath != "" {
aboutDetail.ImageDetail = coverImageAboutDeatilPath
}
aboutDetail, err = s.aboutRepo.UpdateAboutDetail(id, aboutDetail)
if err != nil {
log.Printf("Error updating about detail: %v", err)
return nil, fmt.Errorf("failed to update about detail: %v", err)
}
createdAt, _ := utils.FormatDateToIndonesianFormat(aboutDetail.CreatedAt)
updatedAt, _ := utils.FormatDateToIndonesianFormat(aboutDetail.UpdatedAt)
response := &dto.ResponseAboutDetailDTO{
ID: aboutDetail.ID,
AboutID: aboutDetail.AboutID,
ImageDetail: aboutDetail.ImageDetail,
Description: aboutDetail.Description,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}
return response, nil
}
func (s *aboutService) DeleteAboutDetail(id string) error {
aboutDetail, err := s.aboutRepo.GetAboutDetailByID(id)
if err != nil {
return fmt.Errorf("about detail tidakck ditemukan: %v", err)
}
if aboutDetail.ImageDetail != "" {
err := deleteCoverImageAbout(aboutDetail.ImageDetail)
if err != nil {
return fmt.Errorf("gagal menghapus gambar lama: %v", err)
}
}
if err := s.aboutRepo.DeleteAboutDetail(id); err != nil {
return fmt.Errorf("failed to delete AboutDetail: %v", err)
}
return nil
}