refact: upload file statement fixing and refact
This commit is contained in:
parent
b144ac7750
commit
f22351ffbe
|
|
@ -26,7 +26,5 @@ go.work.sum
|
||||||
.env.prod
|
.env.prod
|
||||||
.env.dev
|
.env.dev
|
||||||
|
|
||||||
# Ignore avatar images
|
# Ignore public uploads
|
||||||
/public/uploads/avatars/
|
/public/uploads/
|
||||||
/public/uploads/articles/
|
|
||||||
/public/uploads/banners/
|
|
||||||
|
|
@ -31,33 +31,33 @@ func (r *RequestStoreDTO) ValidateStoreInput() (map[string][]string, bool) {
|
||||||
errors := make(map[string][]string)
|
errors := make(map[string][]string)
|
||||||
|
|
||||||
if strings.TrimSpace(r.StoreName) == "" {
|
if strings.TrimSpace(r.StoreName) == "" {
|
||||||
errors["storeName"] = append(errors["storeName"], "Store name is required")
|
errors["store_name"] = append(errors["store_name"], "Store name is required")
|
||||||
} else if len(r.StoreName) < 3 {
|
} else if len(r.StoreName) < 3 {
|
||||||
errors["storeName"] = append(errors["storeName"], "Store name must be at least 3 characters long")
|
errors["store_name"] = append(errors["store_name"], "Store name must be at least 3 characters long")
|
||||||
} else {
|
} else {
|
||||||
validNameRegex := `^[a-zA-Z0-9_.\s]+$`
|
validNameRegex := `^[a-zA-Z0-9_.\s]+$`
|
||||||
if matched, _ := regexp.MatchString(validNameRegex, r.StoreName); !matched {
|
if matched, _ := regexp.MatchString(validNameRegex, r.StoreName); !matched {
|
||||||
errors["storeName"] = append(errors["storeName"], "Store name can only contain letters, numbers, underscores, and periods")
|
errors["store_name"] = append(errors["store_name"], "Store name can only contain letters, numbers, underscores, and periods")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(r.StoreLogo) == "" {
|
if strings.TrimSpace(r.StoreLogo) == "" {
|
||||||
errors["storeLogo"] = append(errors["storeLogo"], "Store logo is required")
|
errors["store_logo"] = append(errors["store_logo"], "Store logo is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(r.StoreBanner) == "" {
|
if strings.TrimSpace(r.StoreBanner) == "" {
|
||||||
errors["storeBanner"] = append(errors["storeBanner"], "Store banner is required")
|
errors["store_banner"] = append(errors["store_banner"], "Store banner is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(r.StoreInfo) == "" {
|
if strings.TrimSpace(r.StoreInfo) == "" {
|
||||||
errors["storeInfo"] = append(errors["storeInfo"], "Store info is required")
|
errors["store_info"] = append(errors["store_info"], "Store info is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
uuidRegex := `^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$`
|
uuidRegex := `^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$`
|
||||||
if r.StoreAddressID == "" {
|
if r.StoreAddressID == "" {
|
||||||
errors["storeAddressId"] = append(errors["storeAddressId"], "Store address ID is required")
|
errors["store_address_id"] = append(errors["store_address_id"], "Store address ID is required")
|
||||||
} else if matched, _ := regexp.MatchString(uuidRegex, r.StoreAddressID); !matched {
|
} else if matched, _ := regexp.MatchString(uuidRegex, r.StoreAddressID); !matched {
|
||||||
errors["storeAddressId"] = append(errors["storeAddressId"], "Invalid Store Address ID format")
|
errors["store_address_id"] = append(errors["store_address_id"], "Invalid Store Address ID format")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
|
|
|
||||||
|
|
@ -19,32 +19,140 @@ func NewStoreHandler(storeService services.StoreService) *StoreHandler {
|
||||||
|
|
||||||
func (h *StoreHandler) CreateStore(c *fiber.Ctx) error {
|
func (h *StoreHandler) CreateStore(c *fiber.Ctx) error {
|
||||||
|
|
||||||
var requestStoreDTO dto.RequestStoreDTO
|
storeName := c.FormValue("store_name")
|
||||||
if err := c.BodyParser(&requestStoreDTO); err != nil {
|
storeInfo := c.FormValue("store_info")
|
||||||
|
storeAddressID := c.FormValue("store_address_id")
|
||||||
|
|
||||||
log.Printf("Error parsing body: %v", err)
|
if storeName == "" || storeInfo == "" || storeAddressID == "" {
|
||||||
return utils.ValidationErrorResponse(c, map[string][]string{"body": {"Invalid request body"}})
|
log.Println("Missing required fields")
|
||||||
|
return utils.GenericResponse(c, fiber.StatusBadRequest, "All fields are required")
|
||||||
|
}
|
||||||
|
|
||||||
|
storeLogo, err := c.FormFile("store_logo")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error parsing store logo: %v", err)
|
||||||
|
return utils.GenericResponse(c, fiber.StatusBadRequest, "Store logo is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
storeBanner, err := c.FormFile("store_banner")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error parsing store banner: %v", err)
|
||||||
|
return utils.GenericResponse(c, fiber.StatusBadRequest, "Store banner is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
requestStoreDTO := dto.RequestStoreDTO{
|
||||||
|
StoreName: storeName,
|
||||||
|
StoreLogo: storeLogo.Filename,
|
||||||
|
StoreBanner: storeBanner.Filename,
|
||||||
|
StoreInfo: storeInfo,
|
||||||
|
StoreAddressID: storeAddressID,
|
||||||
}
|
}
|
||||||
|
|
||||||
errors, valid := requestStoreDTO.ValidateStoreInput()
|
errors, valid := requestStoreDTO.ValidateStoreInput()
|
||||||
if !valid {
|
if !valid {
|
||||||
|
|
||||||
return utils.ValidationErrorResponse(c, errors)
|
return utils.ValidationErrorResponse(c, errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, ok := c.Locals("userID").(string)
|
userID, ok := c.Locals("userID").(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
||||||
log.Println("User ID not found in Locals")
|
log.Println("User ID not found in Locals")
|
||||||
return utils.GenericResponse(c, fiber.StatusUnauthorized, "User ID not found")
|
return utils.GenericResponse(c, fiber.StatusUnauthorized, "User ID not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
store, err := h.StoreService.CreateStore(userID, &requestStoreDTO)
|
store, err := h.StoreService.CreateStore(userID, requestStoreDTO, storeLogo, storeBanner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
log.Printf("Error creating store: %v", err)
|
log.Printf("Error creating store: %v", err)
|
||||||
return utils.GenericResponse(c, fiber.StatusConflict, err.Error())
|
return utils.GenericResponse(c, fiber.StatusConflict, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.CreateResponse(c, store, "store created successfully")
|
return utils.CreateResponse(c, store, "Store created successfully")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *StoreHandler) GetStoreByUserID(c *fiber.Ctx) error {
|
||||||
|
userID, ok := c.Locals("userID").(string)
|
||||||
|
if !ok {
|
||||||
|
log.Println("User ID not found in Locals")
|
||||||
|
return utils.GenericResponse(c, fiber.StatusUnauthorized, "User ID not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
store, err := h.StoreService.GetStoreByUserID(userID)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error fetching store: %v", err)
|
||||||
|
return utils.GenericResponse(c, fiber.StatusNotFound, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Store fetched successfully: %v", store)
|
||||||
|
return utils.SuccessResponse(c, store, "Store fetched successfully")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *StoreHandler) UpdateStore(c *fiber.Ctx) error {
|
||||||
|
storeID := c.Params("store_id")
|
||||||
|
if storeID == "" {
|
||||||
|
return utils.GenericResponse(c, fiber.StatusBadRequest, "Store ID is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
storeName := c.FormValue("store_name")
|
||||||
|
storeInfo := c.FormValue("store_info")
|
||||||
|
storeAddressID := c.FormValue("store_address_id")
|
||||||
|
|
||||||
|
if storeName == "" || storeInfo == "" || storeAddressID == "" {
|
||||||
|
log.Println("Missing required fields")
|
||||||
|
return utils.GenericResponse(c, fiber.StatusBadRequest, "All fields are required")
|
||||||
|
}
|
||||||
|
|
||||||
|
storeLogo, err := c.FormFile("store_logo")
|
||||||
|
if err != nil && err.Error() != "missing file" {
|
||||||
|
log.Printf("Error parsing store logo: %v", err)
|
||||||
|
return utils.GenericResponse(c, fiber.StatusBadRequest, "Error parsing store logo")
|
||||||
|
}
|
||||||
|
|
||||||
|
storeBanner, err := c.FormFile("store_banner")
|
||||||
|
if err != nil && err.Error() != "missing file" {
|
||||||
|
log.Printf("Error parsing store banner: %v", err)
|
||||||
|
return utils.GenericResponse(c, fiber.StatusBadRequest, "Error parsing store banner")
|
||||||
|
}
|
||||||
|
|
||||||
|
requestStoreDTO := dto.RequestStoreDTO{
|
||||||
|
StoreName: storeName,
|
||||||
|
StoreLogo: storeLogo.Filename,
|
||||||
|
StoreBanner: storeBanner.Filename,
|
||||||
|
StoreInfo: storeInfo,
|
||||||
|
StoreAddressID: storeAddressID,
|
||||||
|
}
|
||||||
|
|
||||||
|
errors, valid := requestStoreDTO.ValidateStoreInput()
|
||||||
|
if !valid {
|
||||||
|
return utils.ValidationErrorResponse(c, errors)
|
||||||
|
}
|
||||||
|
|
||||||
|
userID, ok := c.Locals("userID").(string)
|
||||||
|
if !ok {
|
||||||
|
log.Println("User ID not found in Locals")
|
||||||
|
return utils.GenericResponse(c, fiber.StatusUnauthorized, "User ID not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
store, err := h.StoreService.UpdateStore(storeID, &requestStoreDTO, storeLogo, storeBanner, userID)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error updating store: %v", err)
|
||||||
|
return utils.GenericResponse(c, fiber.StatusNotFound, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Store updated successfully: %v", store)
|
||||||
|
return utils.SuccessResponse(c, store, "Store updated successfully")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *StoreHandler) DeleteStore(c *fiber.Ctx) error {
|
||||||
|
storeID := c.Params("store_id")
|
||||||
|
if storeID == "" {
|
||||||
|
return utils.GenericResponse(c, fiber.StatusBadRequest, "Store ID is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := h.StoreService.DeleteStore(storeID)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error deleting store: %v", err)
|
||||||
|
return utils.GenericResponse(c, fiber.StatusNotFound, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Store deleted successfully: %v", storeID)
|
||||||
|
return utils.GenericResponse(c, fiber.StatusOK, "Store deleted successfully")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,21 @@
|
||||||
package repositories
|
package repositories
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/pahmiudahgede/senggoldong/model"
|
"github.com/pahmiudahgede/senggoldong/model"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StoreRepository interface {
|
type StoreRepository interface {
|
||||||
FindStoreByUserID(userID string) (*model.Store, error)
|
FindStoreByUserID(userID string) (*model.Store, error)
|
||||||
|
FindStoreByID(storeID string) (*model.Store, error)
|
||||||
FindAddressByID(addressID string) (*model.Address, error)
|
FindAddressByID(addressID string) (*model.Address, error)
|
||||||
|
|
||||||
CreateStore(store *model.Store) error
|
CreateStore(store *model.Store) error
|
||||||
|
UpdateStore(store *model.Store) error
|
||||||
|
|
||||||
|
DeleteStore(storeID string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type storeRepository struct {
|
type storeRepository struct {
|
||||||
|
|
@ -30,6 +37,17 @@ func (r *storeRepository) FindStoreByUserID(userID string) (*model.Store, error)
|
||||||
return &store, nil
|
return &store, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *storeRepository) FindStoreByID(storeID string) (*model.Store, error) {
|
||||||
|
var store model.Store
|
||||||
|
if err := r.DB.Where("id = ?", storeID).First(&store).Error; err != nil {
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &store, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *storeRepository) FindAddressByID(addressID string) (*model.Address, error) {
|
func (r *storeRepository) FindAddressByID(addressID string) (*model.Address, error) {
|
||||||
var address model.Address
|
var address model.Address
|
||||||
if err := r.DB.Where("id = ?", addressID).First(&address).Error; err != nil {
|
if err := r.DB.Where("id = ?", addressID).First(&address).Error; err != nil {
|
||||||
|
|
@ -47,3 +65,23 @@ func (r *storeRepository) CreateStore(store *model.Store) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *storeRepository) UpdateStore(store *model.Store) error {
|
||||||
|
if err := r.DB.Save(store).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *storeRepository) DeleteStore(storeID string) error {
|
||||||
|
|
||||||
|
if storeID == "" {
|
||||||
|
return fmt.Errorf("store ID cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := r.DB.Where("id = ?", storeID).Delete(&model.Store{}).Error; err != nil {
|
||||||
|
return fmt.Errorf("failed to delete store: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,11 @@ package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"mime/multipart"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/pahmiudahgede/senggoldong/dto"
|
"github.com/pahmiudahgede/senggoldong/dto"
|
||||||
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
||||||
"github.com/pahmiudahgede/senggoldong/model"
|
"github.com/pahmiudahgede/senggoldong/model"
|
||||||
|
|
@ -10,7 +14,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type StoreService interface {
|
type StoreService interface {
|
||||||
CreateStore(userID string, storeDTO *dto.RequestStoreDTO) (*dto.ResponseStoreDTO, error)
|
CreateStore(userID string, storeDTO dto.RequestStoreDTO, storeLogo *multipart.FileHeader, storeBanner *multipart.FileHeader) (*dto.ResponseStoreDTO, error)
|
||||||
|
GetStoreByUserID(userID string) (*dto.ResponseStoreDTO, error)
|
||||||
|
UpdateStore(storeID string, storeDTO *dto.RequestStoreDTO, storeLogo *multipart.FileHeader, storeBanner *multipart.FileHeader, userID string) (*dto.ResponseStoreDTO, error)
|
||||||
|
DeleteStore(storeID string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type storeService struct {
|
type storeService struct {
|
||||||
|
|
@ -21,7 +28,11 @@ func NewStoreService(storeRepo repositories.StoreRepository) StoreService {
|
||||||
return &storeService{storeRepo}
|
return &storeService{storeRepo}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storeService) CreateStore(userID string, storeDTO *dto.RequestStoreDTO) (*dto.ResponseStoreDTO, error) {
|
func (s *storeService) CreateStore(userID string, storeDTO dto.RequestStoreDTO, storeLogo, storeBanner *multipart.FileHeader) (*dto.ResponseStoreDTO, error) {
|
||||||
|
|
||||||
|
if errors, valid := storeDTO.ValidateStoreInput(); !valid {
|
||||||
|
return nil, fmt.Errorf("validation error: %v", errors)
|
||||||
|
}
|
||||||
|
|
||||||
existingStore, err := s.storeRepo.FindStoreByUserID(userID)
|
existingStore, err := s.storeRepo.FindStoreByUserID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -39,11 +50,21 @@ func (s *storeService) CreateStore(userID string, storeDTO *dto.RequestStoreDTO)
|
||||||
return nil, fmt.Errorf("store address ID not found")
|
return nil, fmt.Errorf("store address ID not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
storeLogoPath, err := s.saveStoreImage(storeLogo, "logo")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to save store logo: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
storeBannerPath, err := s.saveStoreImage(storeBanner, "banner")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to save store banner: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
store := model.Store{
|
store := model.Store{
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
StoreName: storeDTO.StoreName,
|
StoreName: storeDTO.StoreName,
|
||||||
StoreLogo: storeDTO.StoreLogo,
|
StoreLogo: storeLogoPath,
|
||||||
StoreBanner: storeDTO.StoreBanner,
|
StoreBanner: storeBannerPath,
|
||||||
StoreInfo: storeDTO.StoreInfo,
|
StoreInfo: storeDTO.StoreInfo,
|
||||||
StoreAddressID: storeDTO.StoreAddressID,
|
StoreAddressID: storeDTO.StoreAddressID,
|
||||||
}
|
}
|
||||||
|
|
@ -71,3 +92,202 @@ func (s *storeService) CreateStore(userID string, storeDTO *dto.RequestStoreDTO)
|
||||||
|
|
||||||
return storeResponseDTO, nil
|
return storeResponseDTO, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *storeService) GetStoreByUserID(userID string) (*dto.ResponseStoreDTO, error) {
|
||||||
|
|
||||||
|
store, err := s.storeRepo.FindStoreByUserID(userID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error retrieving store by user ID: %w", err)
|
||||||
|
}
|
||||||
|
if store == nil {
|
||||||
|
return nil, fmt.Errorf("store not found for user ID: %s", userID)
|
||||||
|
}
|
||||||
|
|
||||||
|
createdAt, err := utils.FormatDateToIndonesianFormat(store.CreatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to format createdAt: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedAt, err := utils.FormatDateToIndonesianFormat(store.UpdatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to format updatedAt: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
storeResponseDTO := &dto.ResponseStoreDTO{
|
||||||
|
ID: store.ID,
|
||||||
|
UserID: store.UserID,
|
||||||
|
StoreName: store.StoreName,
|
||||||
|
StoreLogo: store.StoreLogo,
|
||||||
|
StoreBanner: store.StoreBanner,
|
||||||
|
StoreInfo: store.StoreInfo,
|
||||||
|
StoreAddressID: store.StoreAddressID,
|
||||||
|
TotalProduct: store.TotalProduct,
|
||||||
|
Followers: store.Followers,
|
||||||
|
CreatedAt: createdAt,
|
||||||
|
UpdatedAt: updatedAt,
|
||||||
|
}
|
||||||
|
|
||||||
|
return storeResponseDTO, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storeService) UpdateStore(storeID string, storeDTO *dto.RequestStoreDTO, storeLogo, storeBanner *multipart.FileHeader, userID string) (*dto.ResponseStoreDTO, error) {
|
||||||
|
store, err := s.storeRepo.FindStoreByID(storeID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error retrieving store by ID: %w", err)
|
||||||
|
}
|
||||||
|
if store == nil {
|
||||||
|
return nil, fmt.Errorf("store not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
if storeDTO.StoreAddressID == "" {
|
||||||
|
return nil, fmt.Errorf("store address ID cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
address, err := s.storeRepo.FindAddressByID(storeDTO.StoreAddressID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error validating store address ID: %w", err)
|
||||||
|
}
|
||||||
|
if address == nil {
|
||||||
|
return nil, fmt.Errorf("store address ID not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
if storeLogo != nil {
|
||||||
|
if err := s.deleteStoreImage(store.StoreLogo); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to delete old store logo: %w", err)
|
||||||
|
}
|
||||||
|
storeLogoPath, err := s.saveStoreImage(storeLogo, "logo")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to save store logo: %w", err)
|
||||||
|
}
|
||||||
|
store.StoreLogo = storeLogoPath
|
||||||
|
}
|
||||||
|
|
||||||
|
if storeBanner != nil {
|
||||||
|
if err := s.deleteStoreImage(store.StoreBanner); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to delete old store banner: %w", err)
|
||||||
|
}
|
||||||
|
storeBannerPath, err := s.saveStoreImage(storeBanner, "banner")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to save store banner: %w", err)
|
||||||
|
}
|
||||||
|
store.StoreBanner = storeBannerPath
|
||||||
|
}
|
||||||
|
|
||||||
|
store.StoreName = storeDTO.StoreName
|
||||||
|
store.StoreInfo = storeDTO.StoreInfo
|
||||||
|
store.StoreAddressID = storeDTO.StoreAddressID
|
||||||
|
|
||||||
|
if err := s.storeRepo.UpdateStore(store); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to update store: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
createdAt, err := utils.FormatDateToIndonesianFormat(store.CreatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to format createdAt: %w", err)
|
||||||
|
}
|
||||||
|
updatedAt, err := utils.FormatDateToIndonesianFormat(store.UpdatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to format updatedAt: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
storeResponseDTO := &dto.ResponseStoreDTO{
|
||||||
|
ID: store.ID,
|
||||||
|
UserID: store.UserID,
|
||||||
|
StoreName: store.StoreName,
|
||||||
|
StoreLogo: store.StoreLogo,
|
||||||
|
StoreBanner: store.StoreBanner,
|
||||||
|
StoreInfo: store.StoreInfo,
|
||||||
|
StoreAddressID: store.StoreAddressID,
|
||||||
|
TotalProduct: store.TotalProduct,
|
||||||
|
Followers: store.Followers,
|
||||||
|
CreatedAt: createdAt,
|
||||||
|
UpdatedAt: updatedAt,
|
||||||
|
}
|
||||||
|
|
||||||
|
return storeResponseDTO, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storeService) DeleteStore(storeID string) error {
|
||||||
|
store, err := s.storeRepo.FindStoreByID(storeID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error retrieving store by ID: %w", err)
|
||||||
|
}
|
||||||
|
if store == nil {
|
||||||
|
return fmt.Errorf("store not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
if store.StoreLogo != "" {
|
||||||
|
if err := s.deleteStoreImage(store.StoreLogo); err != nil {
|
||||||
|
return fmt.Errorf("failed to delete store logo: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if store.StoreBanner != "" {
|
||||||
|
if err := s.deleteStoreImage(store.StoreBanner); err != nil {
|
||||||
|
return fmt.Errorf("failed to delete store banner: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.storeRepo.DeleteStore(storeID); err != nil {
|
||||||
|
return fmt.Errorf("failed to delete store: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storeService) saveStoreImage(file *multipart.FileHeader, imageType string) (string, error) {
|
||||||
|
|
||||||
|
imageDir := fmt.Sprintf("./public/uploads/store/%s", imageType)
|
||||||
|
if _, err := os.Stat(imageDir); os.IsNotExist(err) {
|
||||||
|
|
||||||
|
if err := os.MkdirAll(imageDir, os.ModePerm); err != nil {
|
||||||
|
return "", fmt.Errorf("failed to create directory for %s image: %v", imageType, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allowedExtensions := map[string]bool{".jpg": true, ".jpeg": true, ".png": true}
|
||||||
|
extension := filepath.Ext(file.Filename)
|
||||||
|
if !allowedExtensions[extension] {
|
||||||
|
return "", fmt.Errorf("invalid file type, only .jpg, .jpeg, and .png are allowed for %s", imageType)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName := fmt.Sprintf("%s_%s%s", imageType, uuid.New().String(), extension)
|
||||||
|
filePath := filepath.Join(imageDir, fileName)
|
||||||
|
|
||||||
|
fileData, err := file.Open()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to open file: %w", err)
|
||||||
|
}
|
||||||
|
defer fileData.Close()
|
||||||
|
|
||||||
|
outFile, err := os.Create(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to create %s image file: %v", imageType, err)
|
||||||
|
}
|
||||||
|
defer outFile.Close()
|
||||||
|
|
||||||
|
if _, err := outFile.ReadFrom(fileData); err != nil {
|
||||||
|
return "", fmt.Errorf("failed to save %s image: %v", imageType, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return filepath.Join("/uploads/store", imageType, fileName), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storeService) deleteStoreImage(imagePath string) error {
|
||||||
|
if imagePath == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := filepath.Join("./public", imagePath)
|
||||||
|
|
||||||
|
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err := os.Remove(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to delete file at %s: %w", filePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,5 +17,9 @@ func StoreRouter(api fiber.Router) {
|
||||||
storeHandler := handler.NewStoreHandler(storeService)
|
storeHandler := handler.NewStoreHandler(storeService)
|
||||||
|
|
||||||
storeAPI := api.Group("/storerijig")
|
storeAPI := api.Group("/storerijig")
|
||||||
storeAPI.Post("/create", middleware.AuthMiddleware, middleware.RoleMiddleware(utils.RoleAdministrator), storeHandler.CreateStore)
|
|
||||||
|
storeAPI.Post("/create", middleware.AuthMiddleware, middleware.RoleMiddleware(utils.RoleAdministrator, utils.RolePengelola, utils.RolePengepul), storeHandler.CreateStore)
|
||||||
|
storeAPI.Get("/getbyuser", middleware.AuthMiddleware, storeHandler.GetStoreByUserID)
|
||||||
|
storeAPI.Put("/update/:store_id", middleware.AuthMiddleware, middleware.RoleMiddleware(utils.RoleAdministrator, utils.RolePengelola, utils.RolePengepul), storeHandler.UpdateStore)
|
||||||
|
storeAPI.Delete("/delete/:store_id", middleware.AuthMiddleware, middleware.RoleMiddleware(utils.RoleAdministrator, utils.RolePengelola, utils.RolePengepul), storeHandler.DeleteStore)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue