185 lines
4 KiB
Go
185 lines
4 KiB
Go
package service
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.juancwu.dev/juancwu/budgit/internal/event"
|
|
"git.juancwu.dev/juancwu/budgit/internal/model"
|
|
"git.juancwu.dev/juancwu/budgit/internal/repository"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type ShoppingListService struct {
|
|
listRepo repository.ShoppingListRepository
|
|
itemRepo repository.ListItemRepository
|
|
eventBus *event.Broker
|
|
}
|
|
|
|
func NewShoppingListService(listRepo repository.ShoppingListRepository, itemRepo repository.ListItemRepository, eventBus *event.Broker) *ShoppingListService {
|
|
return &ShoppingListService{
|
|
listRepo: listRepo,
|
|
itemRepo: itemRepo,
|
|
eventBus: eventBus,
|
|
}
|
|
}
|
|
|
|
// List methods
|
|
func (s *ShoppingListService) CreateList(spaceID, name string) (*model.ShoppingList, error) {
|
|
name = strings.TrimSpace(name)
|
|
if name == "" {
|
|
return nil, fmt.Errorf("list name cannot be empty")
|
|
}
|
|
|
|
now := time.Now()
|
|
list := &model.ShoppingList{
|
|
ID: uuid.NewString(),
|
|
SpaceID: spaceID,
|
|
Name: name,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
err := s.listRepo.Create(list)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
s.eventBus.Publish(spaceID, "list_created", nil)
|
|
|
|
return list, nil
|
|
}
|
|
|
|
func (s *ShoppingListService) GetListsForSpace(spaceID string) ([]*model.ShoppingList, error) {
|
|
return s.listRepo.GetBySpaceID(spaceID)
|
|
}
|
|
|
|
func (s *ShoppingListService) GetList(listID string) (*model.ShoppingList, error) {
|
|
return s.listRepo.GetByID(listID)
|
|
}
|
|
|
|
func (s *ShoppingListService) UpdateList(listID, name string) (*model.ShoppingList, error) {
|
|
name = strings.TrimSpace(name)
|
|
if name == "" {
|
|
return nil, fmt.Errorf("list name cannot be empty")
|
|
}
|
|
|
|
list, err := s.listRepo.GetByID(listID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
list.Name = name
|
|
|
|
err = s.listRepo.Update(list)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return list, nil
|
|
}
|
|
|
|
func (s *ShoppingListService) DeleteList(listID string) error {
|
|
// Need spaceID to publish event
|
|
list, err := s.listRepo.GetByID(listID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// First delete all items in the list
|
|
err = s.itemRepo.DeleteByListID(listID)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete items in list: %w", err)
|
|
}
|
|
// Then delete the list itself
|
|
err = s.listRepo.Delete(listID)
|
|
if err == nil {
|
|
s.eventBus.Publish(list.SpaceID, "list_deleted", nil)
|
|
}
|
|
return err
|
|
}
|
|
|
|
// Item methods
|
|
func (s *ShoppingListService) AddItemToList(listID, name, createdBy string) (*model.ListItem, error) {
|
|
name = strings.TrimSpace(name)
|
|
if name == "" {
|
|
return nil, fmt.Errorf("item name cannot be empty")
|
|
}
|
|
|
|
now := time.Now()
|
|
item := &model.ListItem{
|
|
ID: uuid.NewString(),
|
|
ListID: listID,
|
|
Name: name,
|
|
IsChecked: false,
|
|
CreatedBy: createdBy,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
err := s.itemRepo.Create(item)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Get Space ID
|
|
list, err := s.listRepo.GetByID(listID)
|
|
if err == nil {
|
|
s.eventBus.Publish(list.SpaceID, "item_added", nil)
|
|
}
|
|
|
|
return item, nil
|
|
}
|
|
|
|
func (s *ShoppingListService) GetItem(itemID string) (*model.ListItem, error) {
|
|
return s.itemRepo.GetByID(itemID)
|
|
}
|
|
|
|
func (s *ShoppingListService) GetItemsForList(listID string) ([]*model.ListItem, error) {
|
|
return s.itemRepo.GetByListID(listID)
|
|
}
|
|
|
|
func (s *ShoppingListService) UpdateItem(itemID, name string, isChecked bool) (*model.ListItem, error) {
|
|
name = strings.TrimSpace(name)
|
|
if name == "" {
|
|
return nil, fmt.Errorf("item name cannot be empty")
|
|
}
|
|
|
|
item, err := s.itemRepo.GetByID(itemID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
item.Name = name
|
|
item.IsChecked = isChecked
|
|
|
|
err = s.itemRepo.Update(item)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Get Space ID via List
|
|
list, err := s.listRepo.GetByID(item.ListID)
|
|
if err == nil {
|
|
s.eventBus.Publish(list.SpaceID, "item_updated", nil)
|
|
}
|
|
|
|
return item, nil
|
|
}
|
|
|
|
func (s *ShoppingListService) DeleteItem(itemID string) error {
|
|
item, err := s.itemRepo.GetByID(itemID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = s.itemRepo.Delete(itemID)
|
|
if err == nil {
|
|
list, err := s.listRepo.GetByID(item.ListID)
|
|
if err == nil {
|
|
s.eventBus.Publish(list.SpaceID, "item_deleted", nil)
|
|
}
|
|
}
|
|
return err
|
|
}
|