142 lines
3.6 KiB
Go
142 lines
3.6 KiB
Go
package product
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
model "api-service/internal/models/product"
|
|
"api-service/internal/repository/product"
|
|
)
|
|
|
|
// Service defines the interface for product business logic
|
|
type Service interface {
|
|
CreateProduct(ctx context.Context, req *model.ProductCreateRequest) (*model.ProductResponse, error)
|
|
GetProduct(ctx context.Context, id string) (*model.ProductResponse, error)
|
|
GetAllProducts(ctx context.Context) (*model.ProductsResponse, error)
|
|
UpdateProduct(ctx context.Context, id string, req *model.ProductUpdateRequest) (*model.ProductResponse, error)
|
|
DeleteProduct(ctx context.Context, id string) error
|
|
}
|
|
|
|
// service implements the Service interface
|
|
type service struct {
|
|
repo product.Repository
|
|
}
|
|
|
|
// NewService creates a new product service
|
|
func NewService(repo product.Repository) Service {
|
|
return &service{repo: repo}
|
|
}
|
|
|
|
// CreateProduct creates a new product
|
|
func (s *service) CreateProduct(ctx context.Context, req *model.ProductCreateRequest) (*model.ProductResponse, error) {
|
|
if req.Name == "" {
|
|
return nil, errors.New("product name is required")
|
|
}
|
|
|
|
if req.Price <= 0 {
|
|
return nil, errors.New("product price must be greater than 0")
|
|
}
|
|
|
|
product := &model.Product{
|
|
ID: generateID(),
|
|
Name: req.Name,
|
|
Description: req.Description,
|
|
Price: req.Price,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
err := s.repo.Create(ctx, product)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &model.ProductResponse{
|
|
ID: product.ID,
|
|
Name: product.Name,
|
|
Description: product.Description,
|
|
Price: product.Price,
|
|
CreatedAt: product.CreatedAt,
|
|
UpdatedAt: product.UpdatedAt,
|
|
}, nil
|
|
}
|
|
|
|
// GetProduct retrieves a product by ID
|
|
func (s *service) GetProduct(ctx context.Context, id string) (*model.ProductResponse, error) {
|
|
if id == "" {
|
|
return nil, errors.New("product ID is required")
|
|
}
|
|
|
|
product, err := s.repo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &model.ProductResponse{
|
|
ID: product.ID,
|
|
Name: product.Name,
|
|
Description: product.Description,
|
|
Price: product.Price,
|
|
CreatedAt: product.CreatedAt,
|
|
UpdatedAt: product.UpdatedAt,
|
|
}, nil
|
|
}
|
|
|
|
// GetAllProducts retrieves all products
|
|
func (s *service) GetAllProducts(ctx context.Context) (*model.ProductsResponse, error) {
|
|
products, err := s.repo.GetAll(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &model.ProductsResponse{
|
|
Data: products,
|
|
}, nil
|
|
}
|
|
|
|
// UpdateProduct updates an existing product
|
|
func (s *service) UpdateProduct(ctx context.Context, id string, req *model.ProductUpdateRequest) (*model.ProductResponse, error) {
|
|
if id == "" {
|
|
return nil, errors.New("product ID is required")
|
|
}
|
|
|
|
existingProduct, err := s.repo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
existingProduct.Name = req.Name
|
|
existingProduct.Description = req.Description
|
|
existingProduct.Price = req.Price
|
|
existingProduct.UpdatedAt = time.Now()
|
|
|
|
err = s.repo.Update(ctx, existingProduct)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &model.ProductResponse{
|
|
ID: existingProduct.ID,
|
|
Name: existingProduct.Name,
|
|
Description: existingProduct.Description,
|
|
Price: existingProduct.Price,
|
|
CreatedAt: existingProduct.CreatedAt,
|
|
UpdatedAt: existingProduct.UpdatedAt,
|
|
}, nil
|
|
}
|
|
|
|
// DeleteProduct deletes a product
|
|
func (s *service) DeleteProduct(ctx context.Context, id string) error {
|
|
if id == "" {
|
|
return errors.New("product ID is required")
|
|
}
|
|
|
|
return s.repo.Delete(ctx, id)
|
|
}
|
|
|
|
// Helper functions
|
|
func generateID() string {
|
|
return "prod_" + time.Now().Format("20060102150405")
|
|
}
|