package service import ( "context" "git.gocasts.ir/ebhomengo/niki/domain/shoppingbasket/entity" "git.gocasts.ir/ebhomengo/niki/pkg/logger" richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" "git.gocasts.ir/ebhomengo/niki/types" "time" ) type Repository interface { AddItem(ctx context.Context, userID types.ID, item entity.Item) error GetCart(ctx context.Context, userID types.ID) (entity.Cart, error) DeleteItem(ctx context.Context, cartID, itemID types.ID) error UpdateQuantity(ctx context.Context, cartID, itemID types.ID, quantity int) error DeleteCart(ctx context.Context, cartID, userID types.ID) error UpdateStatus(ctx context.Context, cartID types.ID, status entity.CartStatus) error } type Service struct { validate Validate repo Repository } func New(val Validate, repo Repository) Service { return Service{validate: val, repo: repo} } func (s Service) AddToBasket(ctx context.Context, req AddToCartRequest) error { const op = "shoppingbasketapp.service.AddToBasket" if err := s.validate.ValidateAddToCart(req); err != nil { logger.L().Error("shoppingbasket-service-AddToBasket", "error", err) return err } return s.repo.AddItem(ctx, req.UserID, entity.Item{ ProductID: req.ProductID, Quantity: req.Quantity, Price: req.Price, Name: req.Name, AddedAt: time.Now().UTC(), }) } func (s Service) GetCart(ctx context.Context, userID types.ID) (GetCartResponse, error) { const op = "shoppingbasketapp.service.GetCart" if userID < 1 { logger.L().Error("shoppingbasket-service-GetCart", "error", "user id must be greater than 1") return GetCartResponse{}, richerror.New(op).WithKind(richerror.KindInvalid).WithMessage("invalid user id") } res, err := s.repo.GetCart(ctx, userID) if err != nil { logger.L().Error("shoppingbasket-service-GetCart", "error", err) return GetCartResponse{}, richerror.New(op).WithErr(err) } return GetCartResponse{ ID: res.ID, UserID: res.UserID, Items: res.Items, TotalPrice: res.TotalPrice, Status: string(res.Status), CreatedAt: res.CreatedAt, ExpireAt: res.ExpireAt, }, nil } func (s Service) RemoveFromCart(ctx context.Context, req RemoveFromCartRequest) error { const op = "shoppingbaskerapp.service.RemoveFromCart" if err := s.validate.ValidateRemoveFromCart(req); err != nil { logger.L().Error("shoppingbasket-service-RemoveFromCart", "error", err) return err } return s.repo.DeleteItem(ctx, req.CartID, req.ItemID) } func (s Service) UpdateQuantity(ctx context.Context, req UpdateQuantityRequest) error { const op = "shoppingbaskerapp.service.UpdateQuantity" if err := s.validate.ValidateUpdateQuantity(req); err != nil { logger.L().Error("shoppingbasket-service-UpdateQuantity", "error", err) return err } if req.Quantity == 0 { return s.repo.DeleteItem(ctx, req.CartID, req.ItemID) } return s.repo.UpdateQuantity(ctx, req.CartID, req.ItemID, req.Quantity) } func (s Service) ClearCart(ctx context.Context, cartID, userID types.ID) error { const op = "shoppingbaskerapp.service.ClearCart" if userID < 1 { logger.L().Error("shoppingbasket-service-ClearCart", "error", "user id must be greater than 1") return richerror.New(op).WithKind(richerror.KindInvalid). WithMessage("invalid user id") } return s.repo.DeleteCart(ctx, cartID, userID) } func (s Service) UpdateCartStatus(ctx context.Context, cartID types.ID, status entity.CartStatus) error { const op = "shoppingbaskerapp.service.ClearCart" if !status.IsValid() { return richerror.New(op).WithKind(richerror.KindInvalid).WithMessage("invalid status") } return s.repo.UpdateStatus(ctx, cartID, status) }