feat: update approval on 5 main module
This commit is contained in:
parent
4976e47a9d
commit
6da67768df
|
|
@ -11,6 +11,7 @@ type Banners struct {
|
||||||
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
|
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
|
||||||
Position *string `json:"position" gorm:"type:varchar"`
|
Position *string `json:"position" gorm:"type:varchar"`
|
||||||
Status *string `json:"status" gorm:"type:varchar"`
|
Status *string `json:"status" gorm:"type:varchar"`
|
||||||
|
StatusId *int `json:"status_id" gorm:"type:int4;default:1"`
|
||||||
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
|
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
|
||||||
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
||||||
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
|
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ type Galleries struct {
|
||||||
Title string `json:"title" gorm:"type:varchar"`
|
Title string `json:"title" gorm:"type:varchar"`
|
||||||
Description *string `json:"description" gorm:"type:text"`
|
Description *string `json:"description" gorm:"type:text"`
|
||||||
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
|
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
|
||||||
|
StatusId *int `json:"status_id" gorm:"type:int4;default:1"`
|
||||||
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
|
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
|
||||||
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
||||||
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
|
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ type Products struct {
|
||||||
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
|
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
|
||||||
Colors *string `json:"colors" gorm:"type:text"` // JSON array stored as text
|
Colors *string `json:"colors" gorm:"type:text"` // JSON array stored as text
|
||||||
Status *string `json:"status" gorm:"type:varchar"`
|
Status *string `json:"status" gorm:"type:varchar"`
|
||||||
|
StatusId *int `json:"status_id" gorm:"type:int4;default:1"`
|
||||||
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
|
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
|
||||||
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
||||||
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
|
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ type Promotions struct {
|
||||||
Title string `json:"title" gorm:"type:varchar"`
|
Title string `json:"title" gorm:"type:varchar"`
|
||||||
Description *string `json:"description" gorm:"type:text"`
|
Description *string `json:"description" gorm:"type:text"`
|
||||||
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
|
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
|
||||||
|
StatusId *int `json:"status_id" gorm:"type:int4;default:1"`
|
||||||
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
|
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
|
||||||
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
||||||
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
|
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ type SalesAgents struct {
|
||||||
Phone *string `json:"phone" gorm:"type:varchar"`
|
Phone *string `json:"phone" gorm:"type:varchar"`
|
||||||
AgentType *string `json:"agent_type" gorm:"type:text"` // JSON array stored as text
|
AgentType *string `json:"agent_type" gorm:"type:text"` // JSON array stored as text
|
||||||
ProfilePicturePath *string `json:"profile_picture_path" gorm:"type:varchar"`
|
ProfilePicturePath *string `json:"profile_picture_path" gorm:"type:varchar"`
|
||||||
|
StatusId *int `json:"status_id" gorm:"type:int4;default:1"`
|
||||||
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
|
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
|
||||||
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
||||||
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
|
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ func (_i *BannersRouter) RegisterBannersRoutes() {
|
||||||
router.Get("/:id", bannersController.Show)
|
router.Get("/:id", bannersController.Show)
|
||||||
router.Post("/", bannersController.Save)
|
router.Post("/", bannersController.Save)
|
||||||
router.Put("/:id", bannersController.Update)
|
router.Put("/:id", bannersController.Update)
|
||||||
|
router.Put("/:id/approve", bannersController.Approve)
|
||||||
router.Delete("/:id", bannersController.Delete)
|
router.Delete("/:id", bannersController.Delete)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"jaecoo-be/app/database/entity/users"
|
||||||
"jaecoo-be/app/module/banners/request"
|
"jaecoo-be/app/module/banners/request"
|
||||||
"jaecoo-be/app/module/banners/service"
|
"jaecoo-be/app/module/banners/service"
|
||||||
"jaecoo-be/utils/paginator"
|
"jaecoo-be/utils/paginator"
|
||||||
|
|
@ -21,6 +22,7 @@ type BannersController interface {
|
||||||
Save(c *fiber.Ctx) error
|
Save(c *fiber.Ctx) error
|
||||||
Update(c *fiber.Ctx) error
|
Update(c *fiber.Ctx) error
|
||||||
Delete(c *fiber.Ctx) error
|
Delete(c *fiber.Ctx) error
|
||||||
|
Approve(c *fiber.Ctx) error
|
||||||
Viewer(c *fiber.Ctx) error
|
Viewer(c *fiber.Ctx) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -271,6 +273,51 @@ func (_i *bannersController) Delete(c *fiber.Ctx) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Approve Banner
|
||||||
|
// @Summary Approve Banner
|
||||||
|
// @Description API for approving Banner (only for admin with roleId = 1)
|
||||||
|
// @Tags Banners
|
||||||
|
// @Security Bearer
|
||||||
|
// @Param X-Client-Key header string true "Insert the X-Client-Key"
|
||||||
|
// @Param id path int true "Banner ID"
|
||||||
|
// @Success 200 {object} response.Response
|
||||||
|
// @Failure 400 {object} response.BadRequestError
|
||||||
|
// @Failure 401 {object} response.UnauthorizedError
|
||||||
|
// @Failure 500 {object} response.InternalServerError
|
||||||
|
// @Router /banners/{id}/approve [put]
|
||||||
|
func (_i *bannersController) Approve(c *fiber.Ctx) error {
|
||||||
|
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get user from context
|
||||||
|
user := c.Locals("user")
|
||||||
|
if user == nil {
|
||||||
|
return utilRes.Resp(c, utilRes.Response{
|
||||||
|
Success: false,
|
||||||
|
Messages: utilRes.Messages{"Unauthorized: user not found"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type assert to get user role ID
|
||||||
|
userRoleId := uint(0)
|
||||||
|
if userData, ok := user.(*users.Users); ok {
|
||||||
|
userRoleId = userData.UserRoleId
|
||||||
|
}
|
||||||
|
|
||||||
|
bannerData, err := _i.bannersService.Approve(uint(id), userRoleId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return utilRes.Resp(c, utilRes.Response{
|
||||||
|
Success: true,
|
||||||
|
Messages: utilRes.Messages{"Banner successfully approved"},
|
||||||
|
Data: bannerData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Viewer Banner
|
// Viewer Banner
|
||||||
// @Summary Viewer Banner
|
// @Summary Viewer Banner
|
||||||
// @Description API for viewing Banner file
|
// @Description API for viewing Banner file
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ func BannersResponseMapper(banner *entity.Banners, host string) *res.BannersResp
|
||||||
ThumbnailPath: banner.ThumbnailPath,
|
ThumbnailPath: banner.ThumbnailPath,
|
||||||
Position: banner.Position,
|
Position: banner.Position,
|
||||||
Status: banner.Status,
|
Status: banner.Status,
|
||||||
|
StatusId: banner.StatusId,
|
||||||
IsActive: banner.IsActive,
|
IsActive: banner.IsActive,
|
||||||
CreatedAt: banner.CreatedAt,
|
CreatedAt: banner.CreatedAt,
|
||||||
UpdatedAt: banner.UpdatedAt,
|
UpdatedAt: banner.UpdatedAt,
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ type BannersRepository interface {
|
||||||
Update(id uint, banner *entity.Banners) (err error)
|
Update(id uint, banner *entity.Banners) (err error)
|
||||||
Delete(id uint) (err error)
|
Delete(id uint) (err error)
|
||||||
FindByThumbnailPath(thumbnailPath string) (banner *entity.Banners, err error)
|
FindByThumbnailPath(thumbnailPath string) (banner *entity.Banners, err error)
|
||||||
|
Approve(id uint) (err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBannersRepository(db *database.Database, log zerolog.Logger) BannersRepository {
|
func NewBannersRepository(db *database.Database, log zerolog.Logger) BannersRepository {
|
||||||
|
|
@ -97,3 +98,9 @@ func (_i *bannersRepository) FindByThumbnailPath(thumbnailPath string) (banner *
|
||||||
err = _i.DB.DB.Where("thumbnail_path LIKE ? AND is_active = ?", "%"+thumbnailPath, true).First(banner).Error
|
err = _i.DB.DB.Where("thumbnail_path LIKE ? AND is_active = ?", "%"+thumbnailPath, true).First(banner).Error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_i *bannersRepository) Approve(id uint) (err error) {
|
||||||
|
statusId := 2 // Approved status
|
||||||
|
err = _i.DB.DB.Model(&entity.Banners{}).Where("id = ?", id).Update("status_id", statusId).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ type BannersResponse struct {
|
||||||
ThumbnailUrl *string `json:"thumbnail_url"`
|
ThumbnailUrl *string `json:"thumbnail_url"`
|
||||||
Position *string `json:"position"`
|
Position *string `json:"position"`
|
||||||
Status *string `json:"status"`
|
Status *string `json:"status"`
|
||||||
|
StatusId *int `json:"status_id"`
|
||||||
IsActive *bool `json:"is_active"`
|
IsActive *bool `json:"is_active"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ type BannersService interface {
|
||||||
Create(c *fiber.Ctx, req request.BannersCreateRequest) (banner *response.BannersResponse, err error)
|
Create(c *fiber.Ctx, req request.BannersCreateRequest) (banner *response.BannersResponse, err error)
|
||||||
Update(c *fiber.Ctx, id uint, req request.BannersUpdateRequest) (banner *response.BannersResponse, err error)
|
Update(c *fiber.Ctx, id uint, req request.BannersUpdateRequest) (banner *response.BannersResponse, err error)
|
||||||
Delete(id uint) (err error)
|
Delete(id uint) (err error)
|
||||||
|
Approve(id uint, userRoleId uint) (banner *response.BannersResponse, err error)
|
||||||
UploadFileToMinio(c *fiber.Ctx, fileKey string) (filePath *string, err error)
|
UploadFileToMinio(c *fiber.Ctx, fileKey string) (filePath *string, err error)
|
||||||
Viewer(c *fiber.Ctx) (err error)
|
Viewer(c *fiber.Ctx) (err error)
|
||||||
}
|
}
|
||||||
|
|
@ -197,6 +198,35 @@ func (_i *bannersService) Delete(id uint) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_i *bannersService) Approve(id uint, userRoleId uint) (banner *response.BannersResponse, err error) {
|
||||||
|
// Check if user has admin role (roleId = 1)
|
||||||
|
if userRoleId != 1 {
|
||||||
|
err = errors.New("unauthorized: only admin can approve")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Approve banner (update status_id to 2)
|
||||||
|
err = _i.Repo.Approve(id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get updated banner data
|
||||||
|
bannerEntity, err := _i.Repo.FindOne(id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if bannerEntity == nil {
|
||||||
|
err = errors.New("banner not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
host := _i.Cfg.App.Domain
|
||||||
|
banner = mapper.BannersResponseMapper(bannerEntity, host)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (_i *bannersService) Viewer(c *fiber.Ctx) (err error) {
|
func (_i *bannersService) Viewer(c *fiber.Ctx) (err error) {
|
||||||
filename := c.Params("filename")
|
filename := c.Params("filename")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"jaecoo-be/app/database/entity/users"
|
||||||
"jaecoo-be/app/module/galleries/request"
|
"jaecoo-be/app/module/galleries/request"
|
||||||
"jaecoo-be/app/module/galleries/service"
|
"jaecoo-be/app/module/galleries/service"
|
||||||
"jaecoo-be/utils/paginator"
|
"jaecoo-be/utils/paginator"
|
||||||
|
|
@ -22,6 +23,7 @@ type GalleriesController interface {
|
||||||
Save(c *fiber.Ctx) error
|
Save(c *fiber.Ctx) error
|
||||||
Update(c *fiber.Ctx) error
|
Update(c *fiber.Ctx) error
|
||||||
Delete(c *fiber.Ctx) error
|
Delete(c *fiber.Ctx) error
|
||||||
|
Approve(c *fiber.Ctx) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGalleriesController(galleriesService service.GalleriesService) GalleriesController {
|
func NewGalleriesController(galleriesService service.GalleriesService) GalleriesController {
|
||||||
|
|
@ -192,3 +194,48 @@ func (_i *galleriesController) Delete(c *fiber.Ctx) error {
|
||||||
Messages: utilRes.Messages{"Gallery successfully deleted"},
|
Messages: utilRes.Messages{"Gallery successfully deleted"},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Approve Gallery
|
||||||
|
// @Summary Approve Gallery
|
||||||
|
// @Description API for approving Gallery (only for admin with roleId = 1)
|
||||||
|
// @Tags Galleries
|
||||||
|
// @Security Bearer
|
||||||
|
// @Param X-Client-Key header string true "Insert the X-Client-Key"
|
||||||
|
// @Param id path int true "Gallery ID"
|
||||||
|
// @Success 200 {object} response.Response
|
||||||
|
// @Failure 400 {object} response.BadRequestError
|
||||||
|
// @Failure 401 {object} response.UnauthorizedError
|
||||||
|
// @Failure 500 {object} response.InternalServerError
|
||||||
|
// @Router /galleries/{id}/approve [put]
|
||||||
|
func (_i *galleriesController) Approve(c *fiber.Ctx) error {
|
||||||
|
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get user from context
|
||||||
|
user := c.Locals("user")
|
||||||
|
if user == nil {
|
||||||
|
return utilRes.Resp(c, utilRes.Response{
|
||||||
|
Success: false,
|
||||||
|
Messages: utilRes.Messages{"Unauthorized: user not found"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type assert to get user role ID
|
||||||
|
userRoleId := uint(0)
|
||||||
|
if userData, ok := user.(*users.Users); ok {
|
||||||
|
userRoleId = userData.UserRoleId
|
||||||
|
}
|
||||||
|
|
||||||
|
galleryData, err := _i.galleriesService.Approve(uint(id), userRoleId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return utilRes.Resp(c, utilRes.Response{
|
||||||
|
Success: true,
|
||||||
|
Messages: utilRes.Messages{"Gallery successfully approved"},
|
||||||
|
Data: galleryData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ func (_i *GalleriesRouter) RegisterGalleriesRoutes() {
|
||||||
router.Get("/:id", galleriesController.Show)
|
router.Get("/:id", galleriesController.Show)
|
||||||
router.Post("/", galleriesController.Save)
|
router.Post("/", galleriesController.Save)
|
||||||
router.Put("/:id", galleriesController.Update)
|
router.Put("/:id", galleriesController.Update)
|
||||||
|
router.Put("/:id/approve", galleriesController.Approve)
|
||||||
router.Delete("/:id", galleriesController.Delete)
|
router.Delete("/:id", galleriesController.Delete)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ func GalleriesResponseMapper(gallery *entity.Galleries, host string) *res.Galler
|
||||||
Title: gallery.Title,
|
Title: gallery.Title,
|
||||||
Description: gallery.Description,
|
Description: gallery.Description,
|
||||||
ThumbnailPath: gallery.ThumbnailPath,
|
ThumbnailPath: gallery.ThumbnailPath,
|
||||||
|
StatusId: gallery.StatusId,
|
||||||
IsActive: gallery.IsActive,
|
IsActive: gallery.IsActive,
|
||||||
CreatedAt: gallery.CreatedAt,
|
CreatedAt: gallery.CreatedAt,
|
||||||
UpdatedAt: gallery.UpdatedAt,
|
UpdatedAt: gallery.UpdatedAt,
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ type GalleriesRepository interface {
|
||||||
Create(gallery *entity.Galleries) (galleryReturn *entity.Galleries, err error)
|
Create(gallery *entity.Galleries) (galleryReturn *entity.Galleries, err error)
|
||||||
Update(id uint, gallery *entity.Galleries) (err error)
|
Update(id uint, gallery *entity.Galleries) (err error)
|
||||||
Delete(id uint) (err error)
|
Delete(id uint) (err error)
|
||||||
|
Approve(id uint) (err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGalleriesRepository(db *database.Database, log zerolog.Logger) GalleriesRepository {
|
func NewGalleriesRepository(db *database.Database, log zerolog.Logger) GalleriesRepository {
|
||||||
|
|
@ -82,3 +83,9 @@ func (_i *galleriesRepository) Delete(id uint) (err error) {
|
||||||
err = _i.DB.DB.Model(&entity.Galleries{}).Where("id = ?", id).Update("is_active", false).Error
|
err = _i.DB.DB.Model(&entity.Galleries{}).Where("id = ?", id).Update("is_active", false).Error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_i *galleriesRepository) Approve(id uint) (err error) {
|
||||||
|
statusId := 2 // Approved status
|
||||||
|
err = _i.DB.DB.Model(&entity.Galleries{}).Where("id = ?", id).Update("status_id", statusId).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ type GalleriesResponse struct {
|
||||||
Description *string `json:"description"`
|
Description *string `json:"description"`
|
||||||
ThumbnailPath *string `json:"thumbnail_path"`
|
ThumbnailPath *string `json:"thumbnail_path"`
|
||||||
ThumbnailUrl *string `json:"thumbnail_url"`
|
ThumbnailUrl *string `json:"thumbnail_url"`
|
||||||
|
StatusId *int `json:"status_id"`
|
||||||
IsActive *bool `json:"is_active"`
|
IsActive *bool `json:"is_active"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ type GalleriesService interface {
|
||||||
Create(req request.GalleriesCreateRequest) (gallery *response.GalleriesResponse, err error)
|
Create(req request.GalleriesCreateRequest) (gallery *response.GalleriesResponse, err error)
|
||||||
Update(id uint, req request.GalleriesUpdateRequest) (gallery *response.GalleriesResponse, err error)
|
Update(id uint, req request.GalleriesUpdateRequest) (gallery *response.GalleriesResponse, err error)
|
||||||
Delete(id uint) (err error)
|
Delete(id uint) (err error)
|
||||||
|
Approve(id uint, userRoleId uint) (gallery *response.GalleriesResponse, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGalleriesService(repo repository.GalleriesRepository, log zerolog.Logger, cfg *config.Config) GalleriesService {
|
func NewGalleriesService(repo repository.GalleriesRepository, log zerolog.Logger, cfg *config.Config) GalleriesService {
|
||||||
|
|
@ -105,3 +106,32 @@ func (_i *galleriesService) Delete(id uint) (err error) {
|
||||||
err = _i.Repo.Delete(id)
|
err = _i.Repo.Delete(id)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_i *galleriesService) Approve(id uint, userRoleId uint) (gallery *response.GalleriesResponse, err error) {
|
||||||
|
// Check if user has admin role (roleId = 1)
|
||||||
|
if userRoleId != 1 {
|
||||||
|
err = errors.New("unauthorized: only admin can approve")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Approve gallery (update status_id to 2)
|
||||||
|
err = _i.Repo.Approve(id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get updated gallery data
|
||||||
|
galleryEntity, err := _i.Repo.FindOne(id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if galleryEntity == nil {
|
||||||
|
err = errors.New("gallery not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
host := _i.Cfg.App.Domain
|
||||||
|
gallery = mapper.GalleriesResponseMapper(galleryEntity, host)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"jaecoo-be/app/database/entity/users"
|
||||||
"jaecoo-be/app/module/products/request"
|
"jaecoo-be/app/module/products/request"
|
||||||
"jaecoo-be/app/module/products/service"
|
"jaecoo-be/app/module/products/service"
|
||||||
"jaecoo-be/utils/paginator"
|
"jaecoo-be/utils/paginator"
|
||||||
|
|
@ -22,6 +23,7 @@ type ProductsController interface {
|
||||||
Save(c *fiber.Ctx) error
|
Save(c *fiber.Ctx) error
|
||||||
Update(c *fiber.Ctx) error
|
Update(c *fiber.Ctx) error
|
||||||
Delete(c *fiber.Ctx) error
|
Delete(c *fiber.Ctx) error
|
||||||
|
Approve(c *fiber.Ctx) error
|
||||||
Viewer(c *fiber.Ctx) error
|
Viewer(c *fiber.Ctx) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -279,6 +281,51 @@ func (_i *productsController) Delete(c *fiber.Ctx) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Approve Product
|
||||||
|
// @Summary Approve Product
|
||||||
|
// @Description API for approving Product (only for admin with roleId = 1)
|
||||||
|
// @Tags Products
|
||||||
|
// @Security Bearer
|
||||||
|
// @Param X-Client-Key header string true "Insert the X-Client-Key"
|
||||||
|
// @Param id path int true "Product ID"
|
||||||
|
// @Success 200 {object} response.Response
|
||||||
|
// @Failure 400 {object} response.BadRequestError
|
||||||
|
// @Failure 401 {object} response.UnauthorizedError
|
||||||
|
// @Failure 500 {object} response.InternalServerError
|
||||||
|
// @Router /products/{id}/approve [put]
|
||||||
|
func (_i *productsController) Approve(c *fiber.Ctx) error {
|
||||||
|
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get user from context
|
||||||
|
user := c.Locals("user")
|
||||||
|
if user == nil {
|
||||||
|
return utilRes.Resp(c, utilRes.Response{
|
||||||
|
Success: false,
|
||||||
|
Messages: utilRes.Messages{"Unauthorized: user not found"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type assert to get user role ID
|
||||||
|
userRoleId := uint(0)
|
||||||
|
if userData, ok := user.(*users.Users); ok {
|
||||||
|
userRoleId = userData.UserRoleId
|
||||||
|
}
|
||||||
|
|
||||||
|
productData, err := _i.productsService.Approve(uint(id), userRoleId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return utilRes.Resp(c, utilRes.Response{
|
||||||
|
Success: true,
|
||||||
|
Messages: utilRes.Messages{"Product successfully approved"},
|
||||||
|
Data: productData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Viewer Product
|
// Viewer Product
|
||||||
// @Summary Viewer Product
|
// @Summary Viewer Product
|
||||||
// @Description API for viewing Product file
|
// @Description API for viewing Product file
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ func ProductsResponseMapper(product *entity.Products, host string) *res.Products
|
||||||
ThumbnailPath: product.ThumbnailPath,
|
ThumbnailPath: product.ThumbnailPath,
|
||||||
Colors: colors,
|
Colors: colors,
|
||||||
Status: product.Status,
|
Status: product.Status,
|
||||||
|
StatusId: product.StatusId,
|
||||||
IsActive: product.IsActive,
|
IsActive: product.IsActive,
|
||||||
CreatedAt: product.CreatedAt,
|
CreatedAt: product.CreatedAt,
|
||||||
UpdatedAt: product.UpdatedAt,
|
UpdatedAt: product.UpdatedAt,
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ func (_i *ProductsRouter) RegisterProductsRoutes() {
|
||||||
router.Get("/:id", productsController.Show)
|
router.Get("/:id", productsController.Show)
|
||||||
router.Post("/", productsController.Save)
|
router.Post("/", productsController.Save)
|
||||||
router.Put("/:id", productsController.Update)
|
router.Put("/:id", productsController.Update)
|
||||||
|
router.Put("/:id/approve", productsController.Approve)
|
||||||
router.Delete("/:id", productsController.Delete)
|
router.Delete("/:id", productsController.Delete)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ type ProductsRepository interface {
|
||||||
Update(id uint, product *entity.Products) (err error)
|
Update(id uint, product *entity.Products) (err error)
|
||||||
Delete(id uint) (err error)
|
Delete(id uint) (err error)
|
||||||
FindByThumbnailPath(thumbnailPath string) (product *entity.Products, err error)
|
FindByThumbnailPath(thumbnailPath string) (product *entity.Products, err error)
|
||||||
|
Approve(id uint) (err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProductsRepository(db *database.Database, log zerolog.Logger) ProductsRepository {
|
func NewProductsRepository(db *database.Database, log zerolog.Logger) ProductsRepository {
|
||||||
|
|
@ -98,3 +99,9 @@ func (_i *productsRepository) FindByThumbnailPath(thumbnailPath string) (product
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_i *productsRepository) Approve(id uint) (err error) {
|
||||||
|
statusId := 2 // Approved status
|
||||||
|
err = _i.DB.DB.Model(&entity.Products{}).Where("id = ?", id).Update("status_id", statusId).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ type ProductsResponse struct {
|
||||||
ThumbnailUrl *string `json:"thumbnail_url"`
|
ThumbnailUrl *string `json:"thumbnail_url"`
|
||||||
Colors []string `json:"colors"`
|
Colors []string `json:"colors"`
|
||||||
Status *string `json:"status"`
|
Status *string `json:"status"`
|
||||||
|
StatusId *int `json:"status_id"`
|
||||||
IsActive *bool `json:"is_active"`
|
IsActive *bool `json:"is_active"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ type ProductsService interface {
|
||||||
Create(c *fiber.Ctx, req request.ProductsCreateRequest) (product *response.ProductsResponse, err error)
|
Create(c *fiber.Ctx, req request.ProductsCreateRequest) (product *response.ProductsResponse, err error)
|
||||||
Update(c *fiber.Ctx, id uint, req request.ProductsUpdateRequest) (product *response.ProductsResponse, err error)
|
Update(c *fiber.Ctx, id uint, req request.ProductsUpdateRequest) (product *response.ProductsResponse, err error)
|
||||||
Delete(id uint) (err error)
|
Delete(id uint) (err error)
|
||||||
|
Approve(id uint, userRoleId uint) (product *response.ProductsResponse, err error)
|
||||||
UploadFileToMinio(c *fiber.Ctx, fileKey string) (filePath *string, err error)
|
UploadFileToMinio(c *fiber.Ctx, fileKey string) (filePath *string, err error)
|
||||||
Viewer(c *fiber.Ctx) (err error)
|
Viewer(c *fiber.Ctx) (err error)
|
||||||
}
|
}
|
||||||
|
|
@ -272,3 +273,32 @@ func getFileExtension(filename string) string {
|
||||||
// ambil ekstensi terakhir
|
// ambil ekstensi terakhir
|
||||||
return parts[len(parts)-1]
|
return parts[len(parts)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_i *productsService) Approve(id uint, userRoleId uint) (product *response.ProductsResponse, err error) {
|
||||||
|
// Check if user has admin role (roleId = 1)
|
||||||
|
if userRoleId != 1 {
|
||||||
|
err = errors.New("unauthorized: only admin can approve")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Approve product (update status_id to 2)
|
||||||
|
err = _i.Repo.Approve(id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get updated product data
|
||||||
|
productEntity, err := _i.Repo.FindOne(id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if productEntity == nil {
|
||||||
|
err = errors.New("product not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
host := _i.Cfg.App.Domain
|
||||||
|
product = mapper.ProductsResponseMapper(productEntity, host)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"jaecoo-be/app/database/entity/users"
|
||||||
"jaecoo-be/app/module/promotions/request"
|
"jaecoo-be/app/module/promotions/request"
|
||||||
"jaecoo-be/app/module/promotions/service"
|
"jaecoo-be/app/module/promotions/service"
|
||||||
"jaecoo-be/utils/paginator"
|
"jaecoo-be/utils/paginator"
|
||||||
|
|
@ -22,6 +23,7 @@ type PromotionsController interface {
|
||||||
Save(c *fiber.Ctx) error
|
Save(c *fiber.Ctx) error
|
||||||
Update(c *fiber.Ctx) error
|
Update(c *fiber.Ctx) error
|
||||||
Delete(c *fiber.Ctx) error
|
Delete(c *fiber.Ctx) error
|
||||||
|
Approve(c *fiber.Ctx) error
|
||||||
Viewer(c *fiber.Ctx) error
|
Viewer(c *fiber.Ctx) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,6 +224,51 @@ func (_i *promotionsController) Delete(c *fiber.Ctx) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Approve Promotion
|
||||||
|
// @Summary Approve Promotion
|
||||||
|
// @Description API for approving Promotion (only for admin with roleId = 1)
|
||||||
|
// @Tags Promotions
|
||||||
|
// @Security Bearer
|
||||||
|
// @Param X-Client-Key header string true "Insert the X-Client-Key"
|
||||||
|
// @Param id path int true "Promotion ID"
|
||||||
|
// @Success 200 {object} response.Response
|
||||||
|
// @Failure 400 {object} response.BadRequestError
|
||||||
|
// @Failure 401 {object} response.UnauthorizedError
|
||||||
|
// @Failure 500 {object} response.InternalServerError
|
||||||
|
// @Router /promotions/{id}/approve [put]
|
||||||
|
func (_i *promotionsController) Approve(c *fiber.Ctx) error {
|
||||||
|
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get user from context
|
||||||
|
user := c.Locals("user")
|
||||||
|
if user == nil {
|
||||||
|
return utilRes.Resp(c, utilRes.Response{
|
||||||
|
Success: false,
|
||||||
|
Messages: utilRes.Messages{"Unauthorized: user not found"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type assert to get user role ID
|
||||||
|
userRoleId := uint(0)
|
||||||
|
if userData, ok := user.(*users.Users); ok {
|
||||||
|
userRoleId = userData.UserRoleId
|
||||||
|
}
|
||||||
|
|
||||||
|
promotionData, err := _i.promotionsService.Approve(uint(id), userRoleId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return utilRes.Resp(c, utilRes.Response{
|
||||||
|
Success: true,
|
||||||
|
Messages: utilRes.Messages{"Promotion successfully approved"},
|
||||||
|
Data: promotionData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Viewer Promotion
|
// Viewer Promotion
|
||||||
// @Summary Viewer Promotion
|
// @Summary Viewer Promotion
|
||||||
// @Description API for viewing Promotion file
|
// @Description API for viewing Promotion file
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ func PromotionsResponseMapper(promotion *entity.Promotions, host string) *res.Pr
|
||||||
Title: promotion.Title,
|
Title: promotion.Title,
|
||||||
Description: promotion.Description,
|
Description: promotion.Description,
|
||||||
ThumbnailPath: promotion.ThumbnailPath,
|
ThumbnailPath: promotion.ThumbnailPath,
|
||||||
|
StatusId: promotion.StatusId,
|
||||||
IsActive: promotion.IsActive,
|
IsActive: promotion.IsActive,
|
||||||
CreatedAt: promotion.CreatedAt,
|
CreatedAt: promotion.CreatedAt,
|
||||||
UpdatedAt: promotion.UpdatedAt,
|
UpdatedAt: promotion.UpdatedAt,
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ func (_i *PromotionsRouter) RegisterPromotionsRoutes() {
|
||||||
router.Get("/:id", promotionsController.Show)
|
router.Get("/:id", promotionsController.Show)
|
||||||
router.Post("/", promotionsController.Save)
|
router.Post("/", promotionsController.Save)
|
||||||
router.Put("/:id", promotionsController.Update)
|
router.Put("/:id", promotionsController.Update)
|
||||||
|
router.Put("/:id/approve", promotionsController.Approve)
|
||||||
router.Delete("/:id", promotionsController.Delete)
|
router.Delete("/:id", promotionsController.Delete)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ type PromotionsRepository interface {
|
||||||
Update(id uint, promotion *entity.Promotions) (err error)
|
Update(id uint, promotion *entity.Promotions) (err error)
|
||||||
Delete(id uint) (err error)
|
Delete(id uint) (err error)
|
||||||
FindByThumbnailPath(thumbnailPath string) (promotion *entity.Promotions, err error)
|
FindByThumbnailPath(thumbnailPath string) (promotion *entity.Promotions, err error)
|
||||||
|
Approve(id uint) (err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPromotionsRepository(db *database.Database, log zerolog.Logger) PromotionsRepository {
|
func NewPromotionsRepository(db *database.Database, log zerolog.Logger) PromotionsRepository {
|
||||||
|
|
@ -90,3 +91,8 @@ func (_i *promotionsRepository) FindByThumbnailPath(thumbnailPath string) (promo
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_i *promotionsRepository) Approve(id uint) (err error) {
|
||||||
|
statusId := 2 // Approved status
|
||||||
|
err = _i.DB.DB.Model(&entity.Promotions{}).Where("id = ?", id).Update("status_id", statusId).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ type PromotionsResponse struct {
|
||||||
Description *string `json:"description"`
|
Description *string `json:"description"`
|
||||||
ThumbnailPath *string `json:"thumbnail_path"`
|
ThumbnailPath *string `json:"thumbnail_path"`
|
||||||
ThumbnailUrl *string `json:"thumbnail_url"`
|
ThumbnailUrl *string `json:"thumbnail_url"`
|
||||||
|
StatusId *int `json:"status_id"`
|
||||||
IsActive *bool `json:"is_active"`
|
IsActive *bool `json:"is_active"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ type PromotionsService interface {
|
||||||
Create(c *fiber.Ctx, req request.PromotionsCreateRequest) (promotion *response.PromotionsResponse, err error)
|
Create(c *fiber.Ctx, req request.PromotionsCreateRequest) (promotion *response.PromotionsResponse, err error)
|
||||||
Update(id uint, req request.PromotionsUpdateRequest) (promotion *response.PromotionsResponse, err error)
|
Update(id uint, req request.PromotionsUpdateRequest) (promotion *response.PromotionsResponse, err error)
|
||||||
Delete(id uint) (err error)
|
Delete(id uint) (err error)
|
||||||
|
Approve(id uint, userRoleId uint) (promotion *response.PromotionsResponse, err error)
|
||||||
UploadFileToMinio(c *fiber.Ctx, fileKey string) (filePath *string, err error)
|
UploadFileToMinio(c *fiber.Ctx, fileKey string) (filePath *string, err error)
|
||||||
Viewer(c *fiber.Ctx) (err error)
|
Viewer(c *fiber.Ctx) (err error)
|
||||||
}
|
}
|
||||||
|
|
@ -267,3 +268,32 @@ func getFileExtension(filename string) string {
|
||||||
// ambil ekstensi terakhir
|
// ambil ekstensi terakhir
|
||||||
return parts[len(parts)-1]
|
return parts[len(parts)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_i *promotionsService) Approve(id uint, userRoleId uint) (promotion *response.PromotionsResponse, err error) {
|
||||||
|
// Check if user has admin role (roleId = 1)
|
||||||
|
if userRoleId != 1 {
|
||||||
|
err = errors.New("unauthorized: only admin can approve")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Approve promotion (update status_id to 2)
|
||||||
|
err = _i.Repo.Approve(id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get updated promotion data
|
||||||
|
promotionEntity, err := _i.Repo.FindOne(id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if promotionEntity == nil {
|
||||||
|
err = errors.New("promotion not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
host := _i.Cfg.App.Domain
|
||||||
|
promotion = mapper.PromotionsResponseMapper(promotionEntity, host)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"jaecoo-be/app/database/entity/users"
|
||||||
"jaecoo-be/app/module/sales_agents/request"
|
"jaecoo-be/app/module/sales_agents/request"
|
||||||
"jaecoo-be/app/module/sales_agents/service"
|
"jaecoo-be/app/module/sales_agents/service"
|
||||||
"jaecoo-be/utils/paginator"
|
"jaecoo-be/utils/paginator"
|
||||||
|
|
@ -22,6 +23,7 @@ type SalesAgentsController interface {
|
||||||
Save(c *fiber.Ctx) error
|
Save(c *fiber.Ctx) error
|
||||||
Update(c *fiber.Ctx) error
|
Update(c *fiber.Ctx) error
|
||||||
Delete(c *fiber.Ctx) error
|
Delete(c *fiber.Ctx) error
|
||||||
|
Approve(c *fiber.Ctx) error
|
||||||
Viewer(c *fiber.Ctx) error
|
Viewer(c *fiber.Ctx) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -280,6 +282,51 @@ func (_i *salesAgentsController) Delete(c *fiber.Ctx) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Approve SalesAgent
|
||||||
|
// @Summary Approve SalesAgent
|
||||||
|
// @Description API for approving SalesAgent (only for admin with roleId = 1)
|
||||||
|
// @Tags SalesAgents
|
||||||
|
// @Security Bearer
|
||||||
|
// @Param X-Client-Key header string true "Insert the X-Client-Key"
|
||||||
|
// @Param id path int true "SalesAgent ID"
|
||||||
|
// @Success 200 {object} response.Response
|
||||||
|
// @Failure 400 {object} response.BadRequestError
|
||||||
|
// @Failure 401 {object} response.UnauthorizedError
|
||||||
|
// @Failure 500 {object} response.InternalServerError
|
||||||
|
// @Router /sales-agents/{id}/approve [put]
|
||||||
|
func (_i *salesAgentsController) Approve(c *fiber.Ctx) error {
|
||||||
|
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get user from context
|
||||||
|
user := c.Locals("user")
|
||||||
|
if user == nil {
|
||||||
|
return utilRes.Resp(c, utilRes.Response{
|
||||||
|
Success: false,
|
||||||
|
Messages: utilRes.Messages{"Unauthorized: user not found"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type assert to get user role ID
|
||||||
|
userRoleId := uint(0)
|
||||||
|
if userData, ok := user.(*users.Users); ok {
|
||||||
|
userRoleId = userData.UserRoleId
|
||||||
|
}
|
||||||
|
|
||||||
|
agentData, err := _i.salesAgentsService.Approve(uint(id), userRoleId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return utilRes.Resp(c, utilRes.Response{
|
||||||
|
Success: true,
|
||||||
|
Messages: utilRes.Messages{"SalesAgent successfully approved"},
|
||||||
|
Data: agentData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Viewer SalesAgent
|
// Viewer SalesAgent
|
||||||
// @Summary Viewer SalesAgent
|
// @Summary Viewer SalesAgent
|
||||||
// @Description API for viewing SalesAgent profile picture file
|
// @Description API for viewing SalesAgent profile picture file
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ func SalesAgentsResponseMapper(agent *entity.SalesAgents, host string) *res.Sale
|
||||||
Phone: agent.Phone,
|
Phone: agent.Phone,
|
||||||
AgentType: agentType,
|
AgentType: agentType,
|
||||||
ProfilePicturePath: agent.ProfilePicturePath,
|
ProfilePicturePath: agent.ProfilePicturePath,
|
||||||
|
StatusId: agent.StatusId,
|
||||||
IsActive: agent.IsActive,
|
IsActive: agent.IsActive,
|
||||||
CreatedAt: agent.CreatedAt,
|
CreatedAt: agent.CreatedAt,
|
||||||
UpdatedAt: agent.UpdatedAt,
|
UpdatedAt: agent.UpdatedAt,
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ type SalesAgentsRepository interface {
|
||||||
Update(id uint, agent *entity.SalesAgents) (err error)
|
Update(id uint, agent *entity.SalesAgents) (err error)
|
||||||
Delete(id uint) (err error)
|
Delete(id uint) (err error)
|
||||||
FindByProfilePicturePath(profilePicturePath string) (agent *entity.SalesAgents, err error)
|
FindByProfilePicturePath(profilePicturePath string) (agent *entity.SalesAgents, err error)
|
||||||
|
Approve(id uint) (err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSalesAgentsRepository(db *database.Database, log zerolog.Logger) SalesAgentsRepository {
|
func NewSalesAgentsRepository(db *database.Database, log zerolog.Logger) SalesAgentsRepository {
|
||||||
|
|
@ -98,3 +99,9 @@ func (_i *salesAgentsRepository) FindByProfilePicturePath(profilePicturePath str
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_i *salesAgentsRepository) Approve(id uint) (err error) {
|
||||||
|
statusId := 2 // Approved status
|
||||||
|
err = _i.DB.DB.Model(&entity.SalesAgents{}).Where("id = ?", id).Update("status_id", statusId).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ type SalesAgentsResponse struct {
|
||||||
AgentType []string `json:"agent_type"`
|
AgentType []string `json:"agent_type"`
|
||||||
ProfilePicturePath *string `json:"profile_picture_path"`
|
ProfilePicturePath *string `json:"profile_picture_path"`
|
||||||
ProfilePictureUrl *string `json:"profile_picture_url"`
|
ProfilePictureUrl *string `json:"profile_picture_url"`
|
||||||
|
StatusId *int `json:"status_id"`
|
||||||
IsActive *bool `json:"is_active"`
|
IsActive *bool `json:"is_active"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ func (_i *SalesAgentsRouter) RegisterSalesAgentsRoutes() {
|
||||||
router.Get("/:id", salesAgentsController.Show)
|
router.Get("/:id", salesAgentsController.Show)
|
||||||
router.Post("/", salesAgentsController.Save)
|
router.Post("/", salesAgentsController.Save)
|
||||||
router.Put("/:id", salesAgentsController.Update)
|
router.Put("/:id", salesAgentsController.Update)
|
||||||
|
router.Put("/:id/approve", salesAgentsController.Approve)
|
||||||
router.Delete("/:id", salesAgentsController.Delete)
|
router.Delete("/:id", salesAgentsController.Delete)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ type SalesAgentsService interface {
|
||||||
Create(c *fiber.Ctx, req request.SalesAgentsCreateRequest) (agent *response.SalesAgentsResponse, err error)
|
Create(c *fiber.Ctx, req request.SalesAgentsCreateRequest) (agent *response.SalesAgentsResponse, err error)
|
||||||
Update(c *fiber.Ctx, id uint, req request.SalesAgentsUpdateRequest) (agent *response.SalesAgentsResponse, err error)
|
Update(c *fiber.Ctx, id uint, req request.SalesAgentsUpdateRequest) (agent *response.SalesAgentsResponse, err error)
|
||||||
Delete(id uint) (err error)
|
Delete(id uint) (err error)
|
||||||
|
Approve(id uint, userRoleId uint) (agent *response.SalesAgentsResponse, err error)
|
||||||
UploadFileToMinio(c *fiber.Ctx, fileKey string) (filePath *string, err error)
|
UploadFileToMinio(c *fiber.Ctx, fileKey string) (filePath *string, err error)
|
||||||
Viewer(c *fiber.Ctx) (err error)
|
Viewer(c *fiber.Ctx) (err error)
|
||||||
}
|
}
|
||||||
|
|
@ -272,3 +273,32 @@ func getFileExtension(filename string) string {
|
||||||
// ambil ekstensi terakhir
|
// ambil ekstensi terakhir
|
||||||
return parts[len(parts)-1]
|
return parts[len(parts)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_i *salesAgentsService) Approve(id uint, userRoleId uint) (agent *response.SalesAgentsResponse, err error) {
|
||||||
|
// Check if user has admin role (roleId = 1)
|
||||||
|
if userRoleId != 1 {
|
||||||
|
err = errors.New("unauthorized: only admin can approve")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Approve sales agent (update status_id to 2)
|
||||||
|
err = _i.Repo.Approve(id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get updated sales agent data
|
||||||
|
agentEntity, err := _i.Repo.FindOne(id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if agentEntity == nil {
|
||||||
|
err = errors.New("sales agent not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
host := _i.Cfg.App.Domain
|
||||||
|
agent = mapper.SalesAgentsResponseMapper(agentEntity, host)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
1117
docs/swagger/docs.go
1117
docs/swagger/docs.go
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue