fix: fixing product
This commit is contained in:
parent
f449b40270
commit
674a1e1c50
|
@ -69,6 +69,7 @@ func InitDatabase() {
|
||||||
&domain.RequestItem{},
|
&domain.RequestItem{},
|
||||||
&domain.Product{},
|
&domain.Product{},
|
||||||
&domain.ProductImage{},
|
&domain.ProductImage{},
|
||||||
|
&domain.Store{},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error: Failed to auto migrate domain:", err)
|
log.Fatal("Error: Failed to auto migrate domain:", err)
|
||||||
|
|
|
@ -5,6 +5,8 @@ import "time"
|
||||||
type Product struct {
|
type Product struct {
|
||||||
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
|
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
|
||||||
UserID string `gorm:"type:uuid;not null" json:"user_id"`
|
UserID string `gorm:"type:uuid;not null" json:"user_id"`
|
||||||
|
StoreID string `gorm:"type:uuid;not null" json:"store_id"`
|
||||||
|
Store Store `gorm:"foreignKey:StoreID" json:"store"`
|
||||||
ProductTitle string `gorm:"not null" json:"product_title"`
|
ProductTitle string `gorm:"not null" json:"product_title"`
|
||||||
ProductImages []ProductImage `gorm:"foreignKey:ProductID;constraint:OnDelete:CASCADE;" json:"product_images"`
|
ProductImages []ProductImage `gorm:"foreignKey:ProductID;constraint:OnDelete:CASCADE;" json:"product_images"`
|
||||||
TrashDetailID string `gorm:"type:uuid;not null" json:"trash_detail_id"`
|
TrashDetailID string `gorm:"type:uuid;not null" json:"trash_detail_id"`
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Store struct {
|
||||||
|
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
|
||||||
|
UserID string `gorm:"type:uuid;not null" json:"user_id"`
|
||||||
|
User User `gorm:"foreignKey:UserID" json:"user"`
|
||||||
|
StoreName string `gorm:"not null;unique" json:"store_name"`
|
||||||
|
StoreLogo string `json:"store_logo"`
|
||||||
|
StoreBanner string `json:"store_banner"`
|
||||||
|
StoreDesc string `gorm:"type:text" json:"store_desc"`
|
||||||
|
Follower int `gorm:"default:0" json:"follower"`
|
||||||
|
StoreRating float64 `gorm:"default:0" json:"store_rating"`
|
||||||
|
CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// type StoreFinance struct {
|
||||||
|
// ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
|
||||||
|
// StoreID string `gorm:"type:uuid;not null" json:"store_id"`
|
||||||
|
// TotalRevenue int64 `gorm:"default:0" json:"total_revenue"`
|
||||||
|
// TotalExpenses int64 `gorm:"default:0" json:"total_expenses"`
|
||||||
|
// NetProfit int64 `gorm:"default:0" json:"net_profit"`
|
||||||
|
// OrdersCount int `gorm:"default:0" json:"orders_count"`
|
||||||
|
// CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
|
||||||
|
// UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type Order struct {
|
||||||
|
// ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
|
||||||
|
// StoreID string `gorm:"type:uuid;not null" json:"store_id"`
|
||||||
|
// UserID string `gorm:"type:uuid;not null" json:"user_id"`
|
||||||
|
// TotalPrice int64 `gorm:"not null" json:"total_price"`
|
||||||
|
// OrderStatus string `gorm:"not null" json:"order_status"`
|
||||||
|
// ShippingStatus string `gorm:"not null" json:"shipping_status"`
|
||||||
|
// PaymentStatus string `gorm:"not null" json:"payment_status"`
|
||||||
|
// CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
|
||||||
|
// UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type OrderDetail struct {
|
||||||
|
// ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
|
||||||
|
// OrderID string `gorm:"type:uuid;not null" json:"order_id"`
|
||||||
|
// ProductID string `gorm:"type:uuid;not null" json:"product_id"`
|
||||||
|
// Quantity int `gorm:"not null" json:"quantity"`
|
||||||
|
// UnitPrice int64 `gorm:"not null" json:"unit_price"`
|
||||||
|
// TotalPrice int64 `gorm:"not null" json:"total_price"`
|
||||||
|
// CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
|
||||||
|
// UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type Shipping struct {
|
||||||
|
// ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
|
||||||
|
// OrderID string `gorm:"type:uuid;not null" json:"order_id"`
|
||||||
|
// ShippingDate time.Time `gorm:"default:current_timestamp" json:"shipping_date"`
|
||||||
|
// ShippingCost int64 `gorm:"not null" json:"shipping_cost"`
|
||||||
|
// TrackingNo string `gorm:"not null" json:"tracking_no"`
|
||||||
|
// ShippingStatus string `gorm:"not null" json:"shipping_status"`
|
||||||
|
// CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
|
||||||
|
// UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type Cancellation struct {
|
||||||
|
// ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
|
||||||
|
// OrderID string `gorm:"type:uuid;not null" json:"order_id"`
|
||||||
|
// Reason string `gorm:"type:text" json:"reason"`
|
||||||
|
// CancelledAt time.Time `gorm:"default:current_timestamp" json:"cancelled_at"`
|
||||||
|
// CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
|
||||||
|
// UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type Return struct {
|
||||||
|
// ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
|
||||||
|
// OrderID string `gorm:"type:uuid;not null" json:"order_id"`
|
||||||
|
// Reason string `gorm:"type:text" json:"reason"`
|
||||||
|
// ReturnedAt time.Time `gorm:"default:current_timestamp" json:"returned_at"`
|
||||||
|
// CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
|
||||||
|
// UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
|
||||||
|
// }
|
|
@ -4,7 +4,7 @@ import "errors"
|
||||||
|
|
||||||
type ProductResponseWithSoldDTO struct {
|
type ProductResponseWithSoldDTO struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
UserID string `json:"user_id"`
|
StoreID string `json:"store_id"`
|
||||||
ProductTitle string `json:"product_title"`
|
ProductTitle string `json:"product_title"`
|
||||||
ProductImages []ProductImageDTO `json:"product_images"`
|
ProductImages []ProductImageDTO `json:"product_images"`
|
||||||
TrashDetail TrashDetailResponseDTO `json:"trash_detail"`
|
TrashDetail TrashDetailResponseDTO `json:"trash_detail"`
|
||||||
|
@ -18,7 +18,7 @@ type ProductResponseWithSoldDTO struct {
|
||||||
|
|
||||||
type ProductResponseWithoutSoldDTO struct {
|
type ProductResponseWithoutSoldDTO struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
UserID string `json:"user_id"`
|
StoreID string `json:"store_id"`
|
||||||
ProductTitle string `json:"product_title"`
|
ProductTitle string `json:"product_title"`
|
||||||
ProductImages []ProductImageDTO `json:"product_images"`
|
ProductImages []ProductImageDTO `json:"product_images"`
|
||||||
TrashDetail TrashDetailResponseDTO `json:"trash_detail"`
|
TrashDetail TrashDetailResponseDTO `json:"trash_detail"`
|
||||||
|
@ -31,7 +31,7 @@ type ProductResponseWithoutSoldDTO struct {
|
||||||
|
|
||||||
type ProductResponseDTO struct {
|
type ProductResponseDTO struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
UserID string `json:"user_id"`
|
StoreID string `json:"store_id"`
|
||||||
ProductTitle string `json:"product_title"`
|
ProductTitle string `json:"product_title"`
|
||||||
ProductImages []ProductImageDTO `json:"product_images"`
|
ProductImages []ProductImageDTO `json:"product_images"`
|
||||||
TrashDetail TrashDetailResponseDTO `json:"trash_detail"`
|
TrashDetail TrashDetailResponseDTO `json:"trash_detail"`
|
||||||
|
@ -53,6 +53,7 @@ type TrashDetailResponseDTO struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateProductRequestDTO struct {
|
type CreateProductRequestDTO struct {
|
||||||
|
StoreID string `json:"storeid" validate:"required,uuid"`
|
||||||
ProductTitle string `json:"product_title" validate:"required,min=3,max=255"`
|
ProductTitle string `json:"product_title" validate:"required,min=3,max=255"`
|
||||||
ProductImages []string `json:"product_images" validate:"required,min=1,dive,url"`
|
ProductImages []string `json:"product_images" validate:"required,min=1,dive,url"`
|
||||||
TrashDetailID string `json:"trash_detail_id" validate:"required,uuid"`
|
TrashDetailID string `json:"trash_detail_id" validate:"required,uuid"`
|
||||||
|
@ -63,7 +64,7 @@ type CreateProductRequestDTO struct {
|
||||||
|
|
||||||
type CreateProductResponseDTO struct {
|
type CreateProductResponseDTO struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
UserID string `json:"user_id"`
|
StoreID string `json:"store_id"`
|
||||||
ProductTitle string `json:"product_title"`
|
ProductTitle string `json:"product_title"`
|
||||||
ProductImages []string `json:"product_images"`
|
ProductImages []string `json:"product_images"`
|
||||||
TrashDetail TrashDetailResponseDTO `json:"trash_detail"`
|
TrashDetail TrashDetailResponseDTO `json:"trash_detail"`
|
||||||
|
@ -84,8 +85,9 @@ type UpdateProductRequestDTO struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateSalePrice(marketPrice, salePrice int64) error {
|
func ValidateSalePrice(marketPrice, salePrice int64) error {
|
||||||
if salePrice > marketPrice {
|
|
||||||
return errors.New("sale price cannot be greater than market price")
|
if salePrice > marketPrice*2 {
|
||||||
|
return errors.New("sale price cannot be more than twice the market price")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package dto
|
||||||
|
|
||||||
|
type StoreResponseDTO struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
StoreName string `json:"store_name"`
|
||||||
|
StoreLogo string `json:"store_logo"`
|
||||||
|
StoreBanner string `json:"store_banner"`
|
||||||
|
StoreDesc string `json:"store_desc"`
|
||||||
|
Follower int `json:"follower"`
|
||||||
|
StoreRating float64 `json:"store_rating"`
|
||||||
|
CreatedAt string `json:"created_at"`
|
||||||
|
UpdatedAt string `json:"updated_at"`
|
||||||
|
}
|
|
@ -109,7 +109,12 @@ func AppRouter(app *fiber.App) {
|
||||||
// # product post by pengepul
|
// # product post by pengepul
|
||||||
api.Get("/post/products", middleware.RoleRequired(utils.RolePengepul), controllers.GetAllProducts)
|
api.Get("/post/products", middleware.RoleRequired(utils.RolePengepul), controllers.GetAllProducts)
|
||||||
api.Get("/post/product/:productid", middleware.RoleRequired(utils.RolePengepul), controllers.GetProductByID)
|
api.Get("/post/product/:productid", middleware.RoleRequired(utils.RolePengepul), controllers.GetProductByID)
|
||||||
|
api.Get("/view/product/:storeid", middleware.RoleRequired(utils.RolePengepul), controllers.GetProductsByStore)
|
||||||
api.Post("/post/addproduct", middleware.RoleRequired(utils.RolePengepul), controllers.CreateProduct)
|
api.Post("/post/addproduct", middleware.RoleRequired(utils.RolePengepul), controllers.CreateProduct)
|
||||||
api.Put("/post/product/:productid", middleware.RoleRequired(utils.RolePengepul), controllers.UpdateProduct)
|
api.Put("/post/product/:productid", middleware.RoleRequired(utils.RolePengepul), controllers.UpdateProduct)
|
||||||
api.Delete("/delete/product/:productid", middleware.RoleRequired(utils.RolePengepul), controllers.DeleteProduct)
|
api.Delete("/delete/product/:productid", middleware.RoleRequired(utils.RolePengepul), controllers.DeleteProduct)
|
||||||
|
|
||||||
|
// # marketplace
|
||||||
|
api.Get("/store/marketplace", middleware.RoleRequired(utils.RolePengepul), controllers.GetStoresByUserID)
|
||||||
|
api.Get("/store/marketplace/:storeid", middleware.RoleRequired(utils.RolePengepul), controllers.GetStoreByID)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,12 @@ func GetAllProducts(c *fiber.Ctx) error {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
limit := c.QueryInt("limit", 0)
|
storeID := c.Query("storeID", "")
|
||||||
|
|
||||||
|
limit := c.QueryInt("limit", 10)
|
||||||
page := c.QueryInt("page", 1)
|
page := c.QueryInt("page", 1)
|
||||||
|
|
||||||
if limit < 0 || page <= 0 {
|
if limit <= 0 || page <= 0 {
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
fiber.StatusBadRequest,
|
fiber.StatusBadRequest,
|
||||||
"Invalid pagination parameters",
|
"Invalid pagination parameters",
|
||||||
|
@ -28,7 +30,17 @@ func GetAllProducts(c *fiber.Ctx) error {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
products, err := services.GetProductsByUserID(userID, limit, page)
|
var products []dto.ProductResponseWithSoldDTO
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if storeID != "" {
|
||||||
|
|
||||||
|
products, err = services.GetProductsByStoreID(storeID, limit, page)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
products, err = services.GetProductsByUserID(userID, limit, page)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||||
fiber.StatusInternalServerError,
|
fiber.StatusInternalServerError,
|
||||||
|
@ -45,11 +57,11 @@ func GetAllProducts(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetProductByID(c *fiber.Ctx) error {
|
func GetProductByID(c *fiber.Ctx) error {
|
||||||
userID, ok := c.Locals("userID").(string)
|
storeID, ok := c.Locals("userID").(string)
|
||||||
if !ok || userID == "" {
|
if !ok || storeID == "" {
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
|
||||||
fiber.StatusUnauthorized,
|
fiber.StatusUnauthorized,
|
||||||
"Unauthorized: user ID is missing",
|
"Unauthorized: store ID is missing",
|
||||||
nil,
|
nil,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -63,7 +75,7 @@ func GetProductByID(c *fiber.Ctx) error {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
product, err := services.GetProductByIDAndUserID(productID, userID)
|
product, err := services.GetProductByIDAndStoreID(productID, storeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
||||||
fiber.StatusNotFound,
|
fiber.StatusNotFound,
|
||||||
|
@ -79,8 +91,46 @@ func GetProductByID(c *fiber.Ctx) error {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetProductsByStore(c *fiber.Ctx) error {
|
||||||
|
storeID := c.Params("storeid")
|
||||||
|
if storeID == "" {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusBadRequest,
|
||||||
|
"Store ID is required",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
limit := c.QueryInt("limit", 10)
|
||||||
|
page := c.QueryInt("page", 1)
|
||||||
|
|
||||||
|
if limit <= 0 || page <= 0 {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusBadRequest,
|
||||||
|
"Invalid pagination parameters",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
products, err := services.GetProductsByStoreID(storeID, limit, page)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusNotFound,
|
||||||
|
"Store not found",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusOK,
|
||||||
|
"Products fetched successfully",
|
||||||
|
products,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
func CreateProduct(c *fiber.Ctx) error {
|
func CreateProduct(c *fiber.Ctx) error {
|
||||||
var input dto.CreateProductRequestDTO
|
var input dto.CreateProductRequestDTO
|
||||||
|
|
||||||
if err := c.BodyParser(&input); err != nil {
|
if err := c.BodyParser(&input); err != nil {
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
fiber.StatusBadRequest,
|
fiber.StatusBadRequest,
|
||||||
|
@ -98,6 +148,14 @@ func CreateProduct(c *fiber.Ctx) error {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if input.StoreID == "" {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusBadRequest,
|
||||||
|
"Store ID is required in the body",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
product, err := services.CreateProduct(input, userID)
|
product, err := services.CreateProduct(input, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(fiber.StatusUnprocessableEntity).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusUnprocessableEntity).JSON(utils.FormatResponse(
|
||||||
|
@ -115,14 +173,7 @@ func CreateProduct(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateProduct(c *fiber.Ctx) error {
|
func UpdateProduct(c *fiber.Ctx) error {
|
||||||
var input dto.UpdateProductRequestDTO
|
productID := c.Params("productid")
|
||||||
if err := c.BodyParser(&input); err != nil {
|
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
|
||||||
fiber.StatusBadRequest,
|
|
||||||
"Invalid request payload",
|
|
||||||
nil,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
userID, ok := c.Locals("userID").(string)
|
userID, ok := c.Locals("userID").(string)
|
||||||
if !ok || userID == "" {
|
if !ok || userID == "" {
|
||||||
|
@ -133,7 +184,6 @@ func UpdateProduct(c *fiber.Ctx) error {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
productID := c.Params("productid")
|
|
||||||
if productID == "" {
|
if productID == "" {
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
fiber.StatusBadRequest,
|
fiber.StatusBadRequest,
|
||||||
|
@ -142,7 +192,24 @@ func UpdateProduct(c *fiber.Ctx) error {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
product, err := services.UpdateProduct(productID, userID, input)
|
var input dto.UpdateProductRequestDTO
|
||||||
|
if err := c.BodyParser(&input); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusBadRequest,
|
||||||
|
"Invalid request payload",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dto.GetValidator().Struct(input); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusBadRequest,
|
||||||
|
"Invalid product data",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedProduct, err := services.UpdateProduct(productID, input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(fiber.StatusUnprocessableEntity).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusUnprocessableEntity).JSON(utils.FormatResponse(
|
||||||
fiber.StatusUnprocessableEntity,
|
fiber.StatusUnprocessableEntity,
|
||||||
|
@ -154,19 +221,12 @@ func UpdateProduct(c *fiber.Ctx) error {
|
||||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||||
fiber.StatusOK,
|
fiber.StatusOK,
|
||||||
"Product updated successfully",
|
"Product updated successfully",
|
||||||
product,
|
updatedProduct,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteProduct(c *fiber.Ctx) error {
|
func DeleteProduct(c *fiber.Ctx) error {
|
||||||
productID := c.Params("productid")
|
productID := c.Params("productid")
|
||||||
if productID == "" {
|
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
|
||||||
fiber.StatusBadRequest,
|
|
||||||
"Product ID is required",
|
|
||||||
nil,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
userID, ok := c.Locals("userID").(string)
|
userID, ok := c.Locals("userID").(string)
|
||||||
if !ok || userID == "" {
|
if !ok || userID == "" {
|
||||||
|
@ -177,18 +237,19 @@ func DeleteProduct(c *fiber.Ctx) error {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
err := services.DeleteProduct(productID, userID)
|
if productID == "" {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusBadRequest,
|
||||||
|
"Product ID is required",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
err := services.DeleteProduct(productID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err.Error() == "product not found or not authorized to delete" {
|
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
||||||
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
fiber.StatusNotFound,
|
||||||
fiber.StatusNotFound,
|
"Product not found or unable to delete",
|
||||||
"Product not found: mungkin idnya salah",
|
|
||||||
nil,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
|
||||||
fiber.StatusInternalServerError,
|
|
||||||
"Failed to delete product: "+err.Error(),
|
|
||||||
nil,
|
nil,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/internal/services"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetStoreByID(c *fiber.Ctx) error {
|
||||||
|
storeID := c.Params("storeid")
|
||||||
|
if storeID == "" {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusBadRequest,
|
||||||
|
"Store ID is required",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
store, err := services.GetStoreByID(storeID)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusNotFound,
|
||||||
|
"Store not found",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusOK,
|
||||||
|
"Store fetched successfully",
|
||||||
|
store,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetStoresByUserID(c *fiber.Ctx) error {
|
||||||
|
userID, ok := c.Locals("userID").(string)
|
||||||
|
if !ok || userID == "" {
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusUnauthorized,
|
||||||
|
"Unauthorized: user ID is missing",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
stores, err := services.GetStoresByUserID(userID, limit, page)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusInternalServerError,
|
||||||
|
"Failed to fetch stores",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusOK,
|
||||||
|
"Stores fetched successfully",
|
||||||
|
stores,
|
||||||
|
))
|
||||||
|
}
|
|
@ -6,6 +6,18 @@ import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func GetProductsByStoreID(storeID string, limit, offset int) ([]domain.Product, error) {
|
||||||
|
var products []domain.Product
|
||||||
|
query := config.DB.Preload("ProductImages").Preload("TrashDetail").Where("store_id = ?", storeID)
|
||||||
|
|
||||||
|
if limit > 0 {
|
||||||
|
query = query.Limit(limit).Offset(offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := query.Find(&products).Error
|
||||||
|
return products, err
|
||||||
|
}
|
||||||
|
|
||||||
func GetProductsByUserID(userID string, limit, offset int) ([]domain.Product, error) {
|
func GetProductsByUserID(userID string, limit, offset int) ([]domain.Product, error) {
|
||||||
var products []domain.Product
|
var products []domain.Product
|
||||||
query := config.DB.Preload("ProductImages").Preload("TrashDetail").Where("user_id = ?", userID)
|
query := config.DB.Preload("ProductImages").Preload("TrashDetail").Where("user_id = ?", userID)
|
||||||
|
@ -18,10 +30,10 @@ func GetProductsByUserID(userID string, limit, offset int) ([]domain.Product, er
|
||||||
return products, err
|
return products, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetProductByIDAndUserID(productID, userID string) (domain.Product, error) {
|
func GetProductByIDAndStoreID(productID, storeID string) (domain.Product, error) {
|
||||||
var product domain.Product
|
var product domain.Product
|
||||||
err := config.DB.Preload("ProductImages").Preload("TrashDetail").
|
err := config.DB.Preload("ProductImages").Preload("TrashDetail").
|
||||||
Where("id = ? AND user_id = ?", productID, userID).
|
Where("id = ? AND store_id = ?", productID, storeID).
|
||||||
First(&product).Error
|
First(&product).Error
|
||||||
|
|
||||||
return product, err
|
return product, err
|
||||||
|
@ -34,8 +46,18 @@ func GetProductByID(productID string) (domain.Product, error) {
|
||||||
return product, err
|
return product, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsValidStoreID(storeID string) bool {
|
||||||
|
var count int64
|
||||||
|
err := config.DB.Model(&domain.Store{}).Where("id = ?", storeID).Count(&count).Error
|
||||||
|
if err != nil || count == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func CreateProduct(product *domain.Product, images []domain.ProductImage) error {
|
func CreateProduct(product *domain.Product, images []domain.ProductImage) error {
|
||||||
err := config.DB.Transaction(func(tx *gorm.DB) error {
|
|
||||||
|
return config.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
|
||||||
if err := tx.Create(product).Error; err != nil {
|
if err := tx.Create(product).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -45,23 +67,20 @@ func CreateProduct(product *domain.Product, images []domain.ProductImage) error
|
||||||
for i := range images {
|
for i := range images {
|
||||||
images[i].ProductID = product.ID
|
images[i].ProductID = product.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tx.Create(&images).Error; err != nil {
|
if err := tx.Create(&images).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateProduct(product *domain.Product, images []domain.ProductImage) error {
|
func UpdateProduct(product *domain.Product, images []domain.ProductImage) error {
|
||||||
return config.DB.Transaction(func(tx *gorm.DB) error {
|
return config.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
|
||||||
if err := tx.Model(&domain.Product{}).Where("id = ?", product.ID).Updates(product).Error; err != nil {
|
if err := tx.Save(product).Error; err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := tx.Where("product_id = ?", product.ID).Delete(&domain.ProductImage{}).Error; err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +88,11 @@ func UpdateProduct(product *domain.Product, images []domain.ProductImage) error
|
||||||
for i := range images {
|
for i := range images {
|
||||||
images[i].ProductID = product.ID
|
images[i].ProductID = product.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := tx.Where("product_id = ?", product.ID).Delete(&domain.ProductImage{}).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := tx.Create(&images).Error; err != nil {
|
if err := tx.Create(&images).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -78,7 +102,7 @@ func UpdateProduct(product *domain.Product, images []domain.ProductImage) error
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteProduct(productID, userID string) (int64, error) {
|
func DeleteProduct(productID string) error {
|
||||||
result := config.DB.Where("id = ? AND user_id = ?", productID, userID).Delete(&domain.Product{})
|
|
||||||
return result.RowsAffected, result.Error
|
return config.DB.Where("id = ?", productID).Delete(&domain.Product{}).Error
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pahmiudahgede/senggoldong/config"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetStoreByID(storeID string) (domain.Store, error) {
|
||||||
|
var store domain.Store
|
||||||
|
err := config.DB.Where("id = ?", storeID).First(&store).Error
|
||||||
|
return store, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetStoresByUserID(userID string, limit, offset int) ([]domain.Store, error) {
|
||||||
|
var stores []domain.Store
|
||||||
|
query := config.DB.Where("user_id = ?", userID)
|
||||||
|
|
||||||
|
if limit > 0 {
|
||||||
|
query = query.Limit(limit).Offset(offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := query.Find(&stores).Error
|
||||||
|
return stores, err
|
||||||
|
}
|
|
@ -9,6 +9,18 @@ import (
|
||||||
"github.com/pahmiudahgede/senggoldong/utils"
|
"github.com/pahmiudahgede/senggoldong/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func GetProductsByStoreID(storeID string, limit, page int) ([]dto.ProductResponseWithSoldDTO, error) {
|
||||||
|
|
||||||
|
offset := (page - 1) * limit
|
||||||
|
|
||||||
|
products, err := repositories.GetProductsByStoreID(storeID, limit, offset)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapProductsToDTO(products), nil
|
||||||
|
}
|
||||||
|
|
||||||
func GetProductsByUserID(userID string, limit, page int) ([]dto.ProductResponseWithSoldDTO, error) {
|
func GetProductsByUserID(userID string, limit, page int) ([]dto.ProductResponseWithSoldDTO, error) {
|
||||||
offset := (page - 1) * limit
|
offset := (page - 1) * limit
|
||||||
products, err := repositories.GetProductsByUserID(userID, limit, offset)
|
products, err := repositories.GetProductsByUserID(userID, limit, offset)
|
||||||
|
@ -16,6 +28,10 @@ func GetProductsByUserID(userID string, limit, page int) ([]dto.ProductResponseW
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return mapProductsToDTO(products), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapProductsToDTO(products []domain.Product) []dto.ProductResponseWithSoldDTO {
|
||||||
var productResponses []dto.ProductResponseWithSoldDTO
|
var productResponses []dto.ProductResponseWithSoldDTO
|
||||||
for _, product := range products {
|
for _, product := range products {
|
||||||
var images []dto.ProductImageDTO
|
var images []dto.ProductImageDTO
|
||||||
|
@ -25,7 +41,7 @@ func GetProductsByUserID(userID string, limit, page int) ([]dto.ProductResponseW
|
||||||
|
|
||||||
productResponses = append(productResponses, dto.ProductResponseWithSoldDTO{
|
productResponses = append(productResponses, dto.ProductResponseWithSoldDTO{
|
||||||
ID: product.ID,
|
ID: product.ID,
|
||||||
UserID: product.UserID,
|
StoreID: product.StoreID,
|
||||||
ProductTitle: product.ProductTitle,
|
ProductTitle: product.ProductTitle,
|
||||||
ProductImages: images,
|
ProductImages: images,
|
||||||
TrashDetail: dto.TrashDetailResponseDTO{
|
TrashDetail: dto.TrashDetailResponseDTO{
|
||||||
|
@ -41,12 +57,11 @@ func GetProductsByUserID(userID string, limit, page int) ([]dto.ProductResponseW
|
||||||
UpdatedAt: utils.FormatDateToIndonesianFormat(product.UpdatedAt),
|
UpdatedAt: utils.FormatDateToIndonesianFormat(product.UpdatedAt),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
return productResponses
|
||||||
return productResponses, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetProductByIDAndUserID(productID, userID string) (dto.ProductResponseWithSoldDTO, error) {
|
func GetProductByIDAndStoreID(productID, storeID string) (dto.ProductResponseWithSoldDTO, error) {
|
||||||
product, err := repositories.GetProductByIDAndUserID(productID, userID)
|
product, err := repositories.GetProductByIDAndStoreID(productID, storeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dto.ProductResponseWithSoldDTO{}, err
|
return dto.ProductResponseWithSoldDTO{}, err
|
||||||
}
|
}
|
||||||
|
@ -58,7 +73,7 @@ func GetProductByIDAndUserID(productID, userID string) (dto.ProductResponseWithS
|
||||||
|
|
||||||
return dto.ProductResponseWithSoldDTO{
|
return dto.ProductResponseWithSoldDTO{
|
||||||
ID: product.ID,
|
ID: product.ID,
|
||||||
UserID: product.UserID,
|
StoreID: product.StoreID,
|
||||||
ProductTitle: product.ProductTitle,
|
ProductTitle: product.ProductTitle,
|
||||||
ProductImages: images,
|
ProductImages: images,
|
||||||
TrashDetail: dto.TrashDetailResponseDTO{
|
TrashDetail: dto.TrashDetailResponseDTO{
|
||||||
|
@ -80,8 +95,20 @@ func CreateProduct(input dto.CreateProductRequestDTO, userID string) (dto.Create
|
||||||
return dto.CreateProductResponseDTO{}, err
|
return dto.CreateProductResponseDTO{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trashDetail, err := repositories.GetTrashDetailByID(input.TrashDetailID)
|
||||||
|
if err != nil {
|
||||||
|
return dto.CreateProductResponseDTO{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
marketPrice := int64(trashDetail.Price)
|
||||||
|
|
||||||
|
if err := dto.ValidateSalePrice(marketPrice, input.SalePrice); err != nil {
|
||||||
|
return dto.CreateProductResponseDTO{}, err
|
||||||
|
}
|
||||||
|
|
||||||
product := &domain.Product{
|
product := &domain.Product{
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
|
StoreID: input.StoreID,
|
||||||
ProductTitle: input.ProductTitle,
|
ProductTitle: input.ProductTitle,
|
||||||
TrashDetailID: input.TrashDetailID,
|
TrashDetailID: input.TrashDetailID,
|
||||||
SalePrice: input.SalePrice,
|
SalePrice: input.SalePrice,
|
||||||
|
@ -98,14 +125,14 @@ func CreateProduct(input dto.CreateProductRequestDTO, userID string) (dto.Create
|
||||||
return dto.CreateProductResponseDTO{}, err
|
return dto.CreateProductResponseDTO{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
trashDetail, err := repositories.GetTrashDetailByID(product.TrashDetailID)
|
trashDetail, err = repositories.GetTrashDetailByID(product.TrashDetailID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dto.CreateProductResponseDTO{}, err
|
return dto.CreateProductResponseDTO{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return dto.CreateProductResponseDTO{
|
return dto.CreateProductResponseDTO{
|
||||||
ID: product.ID,
|
ID: product.ID,
|
||||||
UserID: product.UserID,
|
StoreID: product.StoreID,
|
||||||
ProductTitle: product.ProductTitle,
|
ProductTitle: product.ProductTitle,
|
||||||
ProductImages: input.ProductImages,
|
ProductImages: input.ProductImages,
|
||||||
TrashDetail: dto.TrashDetailResponseDTO{
|
TrashDetail: dto.TrashDetailResponseDTO{
|
||||||
|
@ -121,65 +148,61 @@ func CreateProduct(input dto.CreateProductRequestDTO, userID string) (dto.Create
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateProduct(productID, userID string, input dto.UpdateProductRequestDTO) (dto.ProductResponseDTO, error) {
|
func UpdateProduct(productID string, input dto.UpdateProductRequestDTO) (dto.CreateProductResponseDTO, error) {
|
||||||
if err := dto.GetValidator().Struct(input); err != nil {
|
|
||||||
return dto.ProductResponseDTO{}, err
|
product, err := repositories.GetProductByID(productID)
|
||||||
|
if err != nil {
|
||||||
|
return dto.CreateProductResponseDTO{}, errors.New("product not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
product := &domain.Product{
|
product.ProductTitle = input.ProductTitle
|
||||||
ID: productID,
|
product.TrashDetailID = input.TrashDetailID
|
||||||
UserID: userID,
|
product.SalePrice = input.SalePrice
|
||||||
ProductTitle: input.ProductTitle,
|
product.Quantity = input.Quantity
|
||||||
TrashDetailID: input.TrashDetailID,
|
product.ProductDescribe = input.ProductDescribe
|
||||||
SalePrice: input.SalePrice,
|
|
||||||
Quantity: input.Quantity,
|
|
||||||
ProductDescribe: input.ProductDescribe,
|
|
||||||
}
|
|
||||||
|
|
||||||
var images []domain.ProductImage
|
var images []domain.ProductImage
|
||||||
for _, imageURL := range input.ProductImages {
|
for _, imageURL := range input.ProductImages {
|
||||||
images = append(images, domain.ProductImage{ImageURL: imageURL})
|
images = append(images, domain.ProductImage{ImageURL: imageURL})
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := repositories.UpdateProduct(product, images); err != nil {
|
if err := repositories.UpdateProduct(&product, images); err != nil {
|
||||||
return dto.ProductResponseDTO{}, err
|
return dto.CreateProductResponseDTO{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedProduct, err := repositories.GetProductByID(productID)
|
trashDetail, err := repositories.GetTrashDetailByID(product.TrashDetailID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dto.ProductResponseDTO{}, err
|
return dto.CreateProductResponseDTO{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var productImages []dto.ProductImageDTO
|
return dto.CreateProductResponseDTO{
|
||||||
for _, img := range updatedProduct.ProductImages {
|
ID: product.ID,
|
||||||
productImages = append(productImages, dto.ProductImageDTO{ImageURL: img.ImageURL})
|
StoreID: product.StoreID,
|
||||||
}
|
ProductTitle: product.ProductTitle,
|
||||||
|
ProductImages: input.ProductImages,
|
||||||
return dto.ProductResponseDTO{
|
|
||||||
ID: updatedProduct.ID,
|
|
||||||
UserID: updatedProduct.UserID,
|
|
||||||
ProductTitle: updatedProduct.ProductTitle,
|
|
||||||
ProductImages: productImages,
|
|
||||||
TrashDetail: dto.TrashDetailResponseDTO{
|
TrashDetail: dto.TrashDetailResponseDTO{
|
||||||
ID: updatedProduct.TrashDetail.ID,
|
ID: trashDetail.ID,
|
||||||
Description: updatedProduct.TrashDetail.Description,
|
Description: trashDetail.Description,
|
||||||
Price: updatedProduct.TrashDetail.Price,
|
Price: trashDetail.Price,
|
||||||
},
|
},
|
||||||
SalePrice: updatedProduct.SalePrice,
|
SalePrice: product.SalePrice,
|
||||||
Quantity: updatedProduct.Quantity,
|
Quantity: product.Quantity,
|
||||||
ProductDescribe: updatedProduct.ProductDescribe,
|
ProductDescribe: product.ProductDescribe,
|
||||||
CreatedAt: utils.FormatDateToIndonesianFormat(updatedProduct.CreatedAt),
|
CreatedAt: utils.FormatDateToIndonesianFormat(product.CreatedAt),
|
||||||
UpdatedAt: utils.FormatDateToIndonesianFormat(updatedProduct.UpdatedAt),
|
UpdatedAt: utils.FormatDateToIndonesianFormat(product.UpdatedAt),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteProduct(productID, userID string) error {
|
func DeleteProduct(productID string) error {
|
||||||
rowsAffected, err := repositories.DeleteProduct(productID, userID)
|
|
||||||
|
_, err := repositories.GetProductByID(productID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
return errors.New("product not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := repositories.DeleteProduct(productID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if rowsAffected == 0 {
|
|
||||||
return errors.New("product not found or not authorized to delete")
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pahmiudahgede/senggoldong/dto"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetStoreByID(storeID string) (dto.StoreResponseDTO, error) {
|
||||||
|
store, err := repositories.GetStoreByID(storeID)
|
||||||
|
if err != nil {
|
||||||
|
return dto.StoreResponseDTO{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto.StoreResponseDTO{
|
||||||
|
ID: store.ID,
|
||||||
|
UserID: store.UserID,
|
||||||
|
StoreName: store.StoreName,
|
||||||
|
StoreLogo: store.StoreLogo,
|
||||||
|
StoreBanner: store.StoreBanner,
|
||||||
|
StoreDesc: store.StoreDesc,
|
||||||
|
Follower: store.Follower,
|
||||||
|
StoreRating: store.StoreRating,
|
||||||
|
CreatedAt: utils.FormatDateToIndonesianFormat(store.CreatedAt),
|
||||||
|
UpdatedAt: utils.FormatDateToIndonesianFormat(store.UpdatedAt),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetStoresByUserID(userID string, limit, page int) ([]dto.StoreResponseDTO, error) {
|
||||||
|
offset := (page - 1) * limit
|
||||||
|
stores, err := repositories.GetStoresByUserID(userID, limit, offset)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var storeResponses []dto.StoreResponseDTO
|
||||||
|
for _, store := range stores {
|
||||||
|
storeResponses = append(storeResponses, dto.StoreResponseDTO{
|
||||||
|
ID: store.ID,
|
||||||
|
UserID: store.UserID,
|
||||||
|
StoreName: store.StoreName,
|
||||||
|
StoreLogo: store.StoreLogo,
|
||||||
|
StoreBanner: store.StoreBanner,
|
||||||
|
StoreDesc: store.StoreDesc,
|
||||||
|
Follower: store.Follower,
|
||||||
|
StoreRating: store.StoreRating,
|
||||||
|
CreatedAt: utils.FormatDateToIndonesianFormat(store.CreatedAt),
|
||||||
|
UpdatedAt: utils.FormatDateToIndonesianFormat(store.UpdatedAt),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return storeResponses, nil
|
||||||
|
}
|
Loading…
Reference in New Issue