feat: add feature post and get ctegory category detail for trash domain

This commit is contained in:
pahmiudahgede 2024-12-11 06:27:00 +07:00
parent 8945080477
commit 22b61ce44e
9 changed files with 330 additions and 7 deletions

View File

@ -58,6 +58,8 @@ func InitDatabase() {
&domain.PlatformHandle{}, &domain.PlatformHandle{},
&domain.Address{}, &domain.Address{},
&domain.Article{}, &domain.Article{},
&domain.TrashCategory{},
&domain.TrashDetail{},
) )
if err != nil { if err != nil {
log.Fatal("Error: Failed to auto migrate domain:", err) log.Fatal("Error: Failed to auto migrate domain:", err)

20
domain/trashtype.go Normal file
View File

@ -0,0 +1,20 @@
package domain
import "time"
type TrashCategory struct {
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
Name string `gorm:"not null" json:"name"`
Details []TrashDetail `gorm:"foreignKey:CategoryID" json:"details"`
CreatedAt time.Time `gorm:"default:current_timestamp" json:"createdAt"`
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updatedAt"`
}
type TrashDetail struct {
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
CategoryID string `gorm:"type:uuid;not null" json:"category_id"`
Description string `gorm:"not null" json:"description"`
Price int `gorm:"not null" json:"price"`
CreatedAt time.Time `gorm:"default:current_timestamp" json:"createdAt"`
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updatedAt"`
}

View File

@ -91,7 +91,3 @@ func (c *ArticleUpdateRequest) ValidateUpdateArticle() error {
} }
return nil return nil
} }
// func (ar *ArticleRequest) Validate() error {
// return validate.Struct(ar)
// }

57
dto/trashtype.go Normal file
View File

@ -0,0 +1,57 @@
package dto
import "github.com/go-playground/validator/v10"
type TrashCategoryDTO struct {
Name string `json:"name" validate:"required,min=3,max=100"`
}
func (t *TrashCategoryDTO) Validate() error {
validate := validator.New()
return validate.Struct(t)
}
type TrashDetailDTO struct {
CategoryID string `json:"category_id" validate:"required,uuid4"`
Description string `json:"description" validate:"required,min=3,max=255"`
Price int `json:"price" validate:"required,min=0"`
}
func (t *TrashDetailDTO) Validate() error {
validate := validator.New()
return validate.Struct(t)
}
type TrashCategoryResponse struct {
ID string `json:"id"`
Name string `json:"name"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
}
func NewTrashCategoryResponse(id, name, createdAt, updatedAt string) TrashCategoryResponse {
return TrashCategoryResponse{
ID: id,
Name: name,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}
}
type TrashDetailResponse struct {
ID string `json:"id"`
Description string `json:"description"`
Price int `json:"price"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
}
func NewTrashDetailResponse(id, description string, price int, createdAt, updatedAt string) TrashDetailResponse {
return TrashDetailResponse{
ID: id,
Description: description,
Price: price,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}
}

View File

@ -38,4 +38,10 @@ func AppRouter(app *fiber.App) {
app.Get("/articles/:id", middleware.AuthMiddleware, controllers.GetArticleByID) app.Get("/articles/:id", middleware.AuthMiddleware, controllers.GetArticleByID)
app.Put("/articles/:id", middleware.AuthMiddleware, controllers.UpdateArticle) app.Put("/articles/:id", middleware.AuthMiddleware, controllers.UpdateArticle)
app.Delete("/articles/:id", middleware.AuthMiddleware, controllers.DeleteArticle) app.Delete("/articles/:id", middleware.AuthMiddleware, controllers.DeleteArticle)
// # trash type
app.Get("/trash-category", controllers.GetTrashCategories)
app.Get("/trash-categorydetail/:id", controllers.GetTrashCategoryDetail)
app.Post("/addtrash-category", controllers.CreateTrashCategory)
app.Post("/addtrash-categorydetail", controllers.CreateTrashDetail)
} }

View File

@ -0,0 +1,166 @@
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 GetTrashCategories(c *fiber.Ctx) error {
trashCategories, err := services.GetTrashCategories()
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
fiber.StatusInternalServerError,
"Failed to fetch trash categories",
nil,
))
}
var response []dto.TrashCategoryResponse
for _, category := range trashCategories {
response = append(response, dto.NewTrashCategoryResponse(
category.ID,
category.Name,
utils.FormatDateToIndonesianFormat(category.CreatedAt),
utils.FormatDateToIndonesianFormat(category.UpdatedAt),
))
}
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
fiber.StatusOK,
"Trash categories fetched successfully",
response,
))
}
func GetTrashCategoryDetail(c *fiber.Ctx) error {
id := c.Params("id")
trashCategoryDetail, err := services.GetTrashCategoryDetail(id)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
fiber.StatusInternalServerError,
"Failed to fetch trash category detail",
nil,
))
}
detailResponse := dto.NewTrashCategoryResponse(
trashCategoryDetail.ID,
trashCategoryDetail.Name,
utils.FormatDateToIndonesianFormat(trashCategoryDetail.CreatedAt),
utils.FormatDateToIndonesianFormat(trashCategoryDetail.UpdatedAt),
)
var detailResponseList []dto.TrashDetailResponse
if trashCategoryDetail.Details != nil {
for _, detail := range trashCategoryDetail.Details {
detailResponseList = append(detailResponseList, dto.NewTrashDetailResponse(
detail.ID,
detail.Description,
detail.Price,
utils.FormatDateToIndonesianFormat(detail.CreatedAt),
utils.FormatDateToIndonesianFormat(detail.UpdatedAt),
))
}
}
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
fiber.StatusOK,
"Trash category detail fetched successfully",
struct {
Category dto.TrashCategoryResponse `json:"category"`
Details []dto.TrashDetailResponse `json:"details,omitempty"`
}{
Category: detailResponse,
Details: detailResponseList,
},
))
}
func CreateTrashCategory(c *fiber.Ctx) error {
var categoryInput dto.TrashCategoryDTO
if err := c.BodyParser(&categoryInput); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
"Invalid input data",
nil,
))
}
if err := categoryInput.Validate(); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
"Validation failed: "+err.Error(),
nil,
))
}
newCategory, err := services.CreateTrashCategory(categoryInput.Name)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
fiber.StatusInternalServerError,
"Failed to create trash category",
nil,
))
}
categoryResponse := map[string]interface{}{
"id": newCategory.ID,
"name": newCategory.Name,
"createdAt": newCategory.CreatedAt,
"updatedAt": newCategory.UpdatedAt,
}
return c.Status(fiber.StatusCreated).JSON(utils.FormatResponse(
fiber.StatusCreated,
"Trash category created successfully",
categoryResponse,
))
}
func CreateTrashDetail(c *fiber.Ctx) error {
var detailInput dto.TrashDetailDTO
if err := c.BodyParser(&detailInput); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
"Invalid input data",
nil,
))
}
if err := detailInput.Validate(); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
"Validation failed: "+err.Error(),
nil,
))
}
newDetail, err := services.CreateTrashDetail(detailInput.CategoryID, detailInput.Description, detailInput.Price)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
fiber.StatusInternalServerError,
"Failed to create trash detail",
nil,
))
}
detailResponse := map[string]interface{}{
"id": newDetail.ID,
"description": newDetail.Description,
"price": newDetail.Price,
"createdAt": newDetail.CreatedAt,
"updatedAt": newDetail.UpdatedAt,
}
return c.Status(fiber.StatusCreated).JSON(utils.FormatResponse(
fiber.StatusCreated,
"Trash detail created successfully",
detailResponse,
))
}

View File

@ -46,12 +46,10 @@ func CreatePin(c *fiber.Ctx) error {
} }
formattedCreatedAt := utils.FormatDateToIndonesianFormat(pin.CreatedAt) formattedCreatedAt := utils.FormatDateToIndonesianFormat(pin.CreatedAt)
// formattedUpdatedAt := utils.FormatDateToIndonesianFormat(pin.UpdatedAt)
pinResponse := dto.PinResponse{ pinResponse := dto.PinResponse{
// ID: pin.ID,
CreatedAt: formattedCreatedAt, CreatedAt: formattedCreatedAt,
// UpdatedAt: formattedUpdatedAt,
} }
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse( return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(

View File

@ -0,0 +1,37 @@
package repositories
import (
"github.com/pahmiudahgede/senggoldong/config"
"github.com/pahmiudahgede/senggoldong/domain"
)
func GetTrashCategories() ([]domain.TrashCategory, error) {
var categories []domain.TrashCategory
if err := config.DB.Find(&categories).Error; err != nil {
return nil, err
}
return categories, nil
}
func GetTrashCategoryDetail(id string) (domain.TrashCategory, error) {
var category domain.TrashCategory
if err := config.DB.Preload("Details").Where("id = ?", id).First(&category).Error; err != nil {
return category, err
}
return category, nil
}
func CreateTrashCategory(category *domain.TrashCategory) error {
if err := config.DB.Create(category).Error; err != nil {
return err
}
return nil
}
func CreateTrashDetail(detail *domain.TrashDetail) error {
if err := config.DB.Create(detail).Error; err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,41 @@
package services
import (
"github.com/pahmiudahgede/senggoldong/domain"
"github.com/pahmiudahgede/senggoldong/internal/repositories"
)
func GetTrashCategories() ([]domain.TrashCategory, error) {
return repositories.GetTrashCategories()
}
func GetTrashCategoryDetail(id string) (domain.TrashCategory, error) {
return repositories.GetTrashCategoryDetail(id)
}
func CreateTrashCategory(name string) (domain.TrashCategory, error) {
category := domain.TrashCategory{Name: name}
err := repositories.CreateTrashCategory(&category)
if err != nil {
return category, err
}
return category, nil
}
func CreateTrashDetail(categoryID, description string, price int) (domain.TrashDetail, error) {
detail := domain.TrashDetail{
CategoryID: categoryID,
Description: description,
Price: price,
}
err := repositories.CreateTrashDetail(&detail)
if err != nil {
return detail, err
}
return detail, nil
}