feat: add get product feature pagination
This commit is contained in:
parent
3ff8a22325
commit
e465ebcd6b
|
@ -67,6 +67,8 @@ func InitDatabase() {
|
||||||
&domain.CoverageSubdistrict{},
|
&domain.CoverageSubdistrict{},
|
||||||
&domain.RequestPickup{},
|
&domain.RequestPickup{},
|
||||||
&domain.RequestItem{},
|
&domain.RequestItem{},
|
||||||
|
&domain.Product{},
|
||||||
|
&domain.ProductImage{},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error: Failed to auto migrate domain:", err)
|
log.Fatal("Error: Failed to auto migrate domain:", err)
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Product struct {
|
||||||
|
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
|
||||||
|
UserID string `gorm:"type:uuid;not null" json:"user_id"`
|
||||||
|
ProductTitle string `gorm:"not null" json:"product_title"`
|
||||||
|
ProductImages []ProductImage `gorm:"foreignKey:ProductID" json:"product_images"`
|
||||||
|
TrashDetailID string `gorm:"type:uuid;not null" json:"trash_detail_id"`
|
||||||
|
TrashDetail TrashDetail `gorm:"foreignKey:TrashDetailID" json:"trash_detail"`
|
||||||
|
SalePrice int64 `gorm:"not null" json:"sale_price"`
|
||||||
|
Quantity int `gorm:"not null" json:"quantity"`
|
||||||
|
ProductDescribe string `gorm:"type:text" json:"product_describe"`
|
||||||
|
Sold int `gorm:"default:0" json:"sold"`
|
||||||
|
CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProductImage struct {
|
||||||
|
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
|
||||||
|
ProductID string `gorm:"type:uuid;not null" json:"product_id"`
|
||||||
|
ImageURL string `gorm:"not null" json:"image_url"`
|
||||||
|
CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package dto
|
||||||
|
|
||||||
|
type ProductResponseDTO struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
ProductTitle string `json:"product_title"`
|
||||||
|
ProductImages []ProductImageDTO `json:"product_images"`
|
||||||
|
TrashDetail TrashDetailResponseDTO `json:"trash_detail"`
|
||||||
|
|
||||||
|
SalePrice int64 `json:"sale_price"`
|
||||||
|
Quantity int `json:"quantity"`
|
||||||
|
ProductDescribe string `json:"product_describe"`
|
||||||
|
Sold int `json:"sold"`
|
||||||
|
CreatedAt string `json:"created_at"`
|
||||||
|
UpdatedAt string `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProductImageDTO struct {
|
||||||
|
ImageURL string `json:"image_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TrashDetailResponseDTO struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Price int `json:"price"`
|
||||||
|
}
|
|
@ -105,4 +105,8 @@ func AppRouter(app *fiber.App) {
|
||||||
api.Get("/requestpickup", middleware.RoleRequired(utils.RoleMasyarakat), controllers.GetRequestPickupsByUser)
|
api.Get("/requestpickup", middleware.RoleRequired(utils.RoleMasyarakat), controllers.GetRequestPickupsByUser)
|
||||||
api.Post("/addrequestpickup", middleware.RoleRequired(utils.RoleMasyarakat), controllers.CreateRequestPickup)
|
api.Post("/addrequestpickup", middleware.RoleRequired(utils.RoleMasyarakat), controllers.CreateRequestPickup)
|
||||||
api.Delete("/deleterequestpickup/:id", middleware.RoleRequired(utils.RoleMasyarakat), controllers.DeleteRequestPickup)
|
api.Delete("/deleterequestpickup/:id", middleware.RoleRequired(utils.RoleMasyarakat), controllers.DeleteRequestPickup)
|
||||||
|
|
||||||
|
// # product post by pengepul
|
||||||
|
api.Get("/post/products", middleware.RoleRequired(utils.RolePengepul), controllers.GetAllProducts)
|
||||||
|
api.Get("/post/product/:productid", middleware.RoleRequired(utils.RolePengepul), controllers.GetProductByID)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/dto"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/internal/services"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetAllProducts(c *fiber.Ctx) error {
|
||||||
|
limit := c.QueryInt("limit", 0)
|
||||||
|
page := c.QueryInt("page", 1)
|
||||||
|
|
||||||
|
if limit < 0 || page <= 0 {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusBadRequest,
|
||||||
|
"Invalid pagination parameters",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
var products []dto.ProductResponseDTO
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if limit == 0 {
|
||||||
|
products, err = services.GetProducts(0, 0)
|
||||||
|
} else {
|
||||||
|
products, err = services.GetProducts(limit, page)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusInternalServerError,
|
||||||
|
"Failed to fetch products",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusOK,
|
||||||
|
"Products fetched successfully",
|
||||||
|
products,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetProductByID(c *fiber.Ctx) error {
|
||||||
|
productID := c.Params("productid")
|
||||||
|
if productID == "" {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusBadRequest,
|
||||||
|
"Product ID is required",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
product, err := services.GetProductByID(productID)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusNotFound,
|
||||||
|
"Product not found",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusOK,
|
||||||
|
"Product fetched successfully",
|
||||||
|
product,
|
||||||
|
))
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pahmiudahgede/senggoldong/config"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetAllProducts(limit, offset int) ([]domain.Product, error) {
|
||||||
|
var products []domain.Product
|
||||||
|
|
||||||
|
query := config.DB.Preload("ProductImages").Preload("TrashDetail")
|
||||||
|
if limit > 0 {
|
||||||
|
query = query.Limit(limit).Offset(offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := query.Find(&products).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return products, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetProductByID(productID string) (domain.Product, error) {
|
||||||
|
var product domain.Product
|
||||||
|
err := config.DB.Preload("ProductImages").Preload("TrashDetail").Where("id = ?", productID).First(&product).Error
|
||||||
|
if err != nil {
|
||||||
|
return domain.Product{}, err
|
||||||
|
}
|
||||||
|
return product, nil
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pahmiudahgede/senggoldong/dto"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetProducts(limit, page int) ([]dto.ProductResponseDTO, error) {
|
||||||
|
offset := (page - 1) * limit
|
||||||
|
|
||||||
|
products, err := repositories.GetAllProducts(limit, offset)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var productResponses []dto.ProductResponseDTO
|
||||||
|
for _, product := range products {
|
||||||
|
var images []dto.ProductImageDTO
|
||||||
|
for _, img := range product.ProductImages {
|
||||||
|
images = append(images, dto.ProductImageDTO{ImageURL: img.ImageURL})
|
||||||
|
}
|
||||||
|
|
||||||
|
trashDetail := dto.TrashDetailResponseDTO{
|
||||||
|
ID: product.TrashDetail.ID,
|
||||||
|
Description: product.TrashDetail.Description,
|
||||||
|
Price: product.TrashDetail.Price,
|
||||||
|
}
|
||||||
|
|
||||||
|
productResponses = append(productResponses, dto.ProductResponseDTO{
|
||||||
|
ID: product.ID,
|
||||||
|
UserID: product.UserID,
|
||||||
|
ProductTitle: product.ProductTitle,
|
||||||
|
ProductImages: images,
|
||||||
|
TrashDetail: trashDetail,
|
||||||
|
SalePrice: product.SalePrice,
|
||||||
|
Quantity: product.Quantity,
|
||||||
|
ProductDescribe: product.ProductDescribe,
|
||||||
|
Sold: product.Sold,
|
||||||
|
CreatedAt: utils.FormatDateToIndonesianFormat(product.CreatedAt),
|
||||||
|
UpdatedAt: utils.FormatDateToIndonesianFormat(product.UpdatedAt),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return productResponses, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetProductByID(productID string) (dto.ProductResponseDTO, error) {
|
||||||
|
product, err := repositories.GetProductByID(productID)
|
||||||
|
if err != nil {
|
||||||
|
return dto.ProductResponseDTO{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var images []dto.ProductImageDTO
|
||||||
|
for _, img := range product.ProductImages {
|
||||||
|
images = append(images, dto.ProductImageDTO{ImageURL: img.ImageURL})
|
||||||
|
}
|
||||||
|
|
||||||
|
trashDetail := dto.TrashDetailResponseDTO{
|
||||||
|
ID: product.TrashDetail.ID,
|
||||||
|
Description: product.TrashDetail.Description,
|
||||||
|
Price: product.TrashDetail.Price,
|
||||||
|
}
|
||||||
|
|
||||||
|
productResponse := dto.ProductResponseDTO{
|
||||||
|
ID: product.ID,
|
||||||
|
UserID: product.UserID,
|
||||||
|
ProductTitle: product.ProductTitle,
|
||||||
|
ProductImages: images,
|
||||||
|
TrashDetail: trashDetail,
|
||||||
|
SalePrice: product.SalePrice,
|
||||||
|
Quantity: product.Quantity,
|
||||||
|
ProductDescribe: product.ProductDescribe,
|
||||||
|
Sold: product.Sold,
|
||||||
|
CreatedAt: utils.FormatDateToIndonesianFormat(product.CreatedAt),
|
||||||
|
UpdatedAt: utils.FormatDateToIndonesianFormat(product.UpdatedAt),
|
||||||
|
}
|
||||||
|
|
||||||
|
return productResponse, nil
|
||||||
|
}
|
Loading…
Reference in New Issue