// service/event_service.go package service import ( "api_bb/internal/models" "api_bb/internal/repository" "api_bb/pkg/logger" "fmt" "time" "go.uber.org/zap" ) type EventService interface { CreateEvent(event *models.Event) error GetEventByID(id uint) (*models.Event, error) GetAllEvents() ([]models.Event, error) UpdateEvent(event *models.Event) error DeleteEvent(id uint) error GetEventsByType(eventType models.EventType) ([]models.Event, error) GetUpcomingEvents() ([]models.Event, error) GetEventsByDateRange(startDate, endDate time.Time) ([]models.Event, error) UpdateParticipantsCount(eventID uint) error ToggleRegistrationStatus(eventID uint, registrationOpen bool) error } type eventService struct { eventRepo repository.EventRepository registrationRepo repository.EventRegistrationRepository logger logger.LoggerInterface } func NewEventService( eventRepo repository.EventRepository, registrationRepo repository.EventRegistrationRepository, log logger.LoggerInterface, ) EventService { serviceLogger := log.With(zap.String("service", "event")) return &eventService{ eventRepo: eventRepo, registrationRepo: registrationRepo, logger: serviceLogger, } } // CreateEvent создает новое событие func (s *eventService) CreateEvent(event *models.Event) error { s.logger.Info("Creating new event", zap.String("title", event.Title), zap.String("type", string(event.Type)), zap.Time("date", event.Date), ) if err := s.eventRepo.Create(event); err != nil { s.logger.Error("Failed to create event", zap.String("title", event.Title), zap.Error(err), ) return fmt.Errorf("failed to create event: %w", err) } s.logger.Info("Event created successfully", zap.Uint("event_id", event.ID), zap.String("title", event.Title), ) return nil } // GetEventByID возвращает событие по ID func (s *eventService) GetEventByID(id uint) (*models.Event, error) { s.logger.Debug("Getting event by ID", zap.Uint("event_id", id)) event, err := s.eventRepo.FindByID(id) if err != nil { s.logger.Warn("Event not found", zap.Uint("event_id", id), zap.Error(err), ) return nil, fmt.Errorf("event not found: %w", err) } s.logger.Debug("Event retrieved successfully", zap.Uint("event_id", id), zap.String("title", event.Title), ) return event, nil } // GetAllEvents возвращает все события func (s *eventService) GetAllEvents() ([]models.Event, error) { s.logger.Debug("Getting all events") events, err := s.eventRepo.FindAll() if err != nil { s.logger.Error("Failed to get events", zap.Error(err)) return nil, fmt.Errorf("failed to get events: %w", err) } s.logger.Debug("Events retrieved successfully", zap.Int("count", len(events)), ) return events, nil } // UpdateEvent обновляет событие func (s *eventService) UpdateEvent(event *models.Event) error { s.logger.Info("Updating event", zap.Uint("event_id", event.ID), zap.String("title", event.Title), ) // Проверяем существование события existingEvent, err := s.eventRepo.FindByID(event.ID) if err != nil { s.logger.Warn("Event not found for update", zap.Uint("event_id", event.ID), zap.Error(err), ) return fmt.Errorf("event not found") } // Сохраняем неизменяемые поля event.CreatedAt = existingEvent.CreatedAt event.UpdatedAt = time.Now() if err := s.eventRepo.Update(event); err != nil { s.logger.Error("Failed to update event", zap.Uint("event_id", event.ID), zap.Error(err), ) return fmt.Errorf("failed to update event: %w", err) } s.logger.Info("Event updated successfully", zap.Uint("event_id", event.ID), ) return nil } // DeleteEvent удаляет событие func (s *eventService) DeleteEvent(id uint) error { s.logger.Info("Deleting event", zap.Uint("event_id", id)) // Проверяем существование события _, err := s.eventRepo.FindByID(id) if err != nil { s.logger.Warn("Event not found for deletion", zap.Uint("event_id", id), zap.Error(err), ) return fmt.Errorf("event not found") } if err := s.eventRepo.Delete(id); err != nil { s.logger.Error("Failed to delete event", zap.Uint("event_id", id), zap.Error(err), ) return fmt.Errorf("failed to delete event: %w", err) } s.logger.Info("Event deleted successfully", zap.Uint("event_id", id), ) return nil } // GetEventsByType возвращает события по типу func (s *eventService) GetEventsByType(eventType models.EventType) ([]models.Event, error) { s.logger.Debug("Getting events by type", zap.String("type", string(eventType))) events, err := s.eventRepo.FindByType(eventType) if err != nil { s.logger.Error("Failed to get events by type", zap.String("type", string(eventType)), zap.Error(err), ) return nil, fmt.Errorf("failed to get events by type: %w", err) } s.logger.Debug("Events by type retrieved successfully", zap.String("type", string(eventType)), zap.Int("count", len(events)), ) return events, nil } // GetUpcomingEvents возвращает предстоящие события func (s *eventService) GetUpcomingEvents() ([]models.Event, error) { s.logger.Debug("Getting upcoming events") events, err := s.eventRepo.FindUpcoming() if err != nil { s.logger.Error("Failed to get upcoming events", zap.Error(err)) return nil, fmt.Errorf("failed to get upcoming events: %w", err) } s.logger.Debug("Upcoming events retrieved successfully", zap.Int("count", len(events)), ) return events, nil } // GetEventsByDateRange возвращает события в диапазоне дат func (s *eventService) GetEventsByDateRange(startDate, endDate time.Time) ([]models.Event, error) { s.logger.Debug("Getting events by date range", zap.Time("start_date", startDate), zap.Time("end_date", endDate), ) events, err := s.eventRepo.FindByDateRange(startDate, endDate) if err != nil { s.logger.Error("Failed to get events by date range", zap.Time("start_date", startDate), zap.Time("end_date", endDate), zap.Error(err), ) return nil, fmt.Errorf("failed to get events by date range: %w", err) } s.logger.Debug("Events by date range retrieved successfully", zap.Time("start_date", startDate), zap.Time("end_date", endDate), zap.Int("count", len(events)), ) return events, nil } // UpdateParticipantsCount обновляет количество участников события func (s *eventService) UpdateParticipantsCount(eventID uint) error { s.logger.Debug("Updating participants count", zap.Uint("event_id", eventID)) count, err := s.registrationRepo.CountByEventID(eventID) if err != nil { s.logger.Error("Failed to count event registrations", zap.Uint("event_id", eventID), zap.Error(err), ) return fmt.Errorf("failed to count registrations: %w", err) } if err := s.eventRepo.UpdateParticipantsCount(eventID, int(count)); err != nil { s.logger.Error("Failed to update participants count", zap.Uint("event_id", eventID), zap.Int64("count", count), zap.Error(err), ) return fmt.Errorf("failed to update participants count: %w", err) } s.logger.Debug("Participants count updated successfully", zap.Uint("event_id", eventID), zap.Int64("count", count), ) return nil } // ToggleRegistrationStatus переключает статус регистрации на событие func (s *eventService) ToggleRegistrationStatus(eventID uint, registrationOpen bool) error { s.logger.Info("Toggling registration status", zap.Uint("event_id", eventID), zap.Bool("registration_open", registrationOpen), ) if err := s.eventRepo.UpdateRegistrationStatus(eventID, registrationOpen); err != nil { s.logger.Error("Failed to toggle registration status", zap.Uint("event_id", eventID), zap.Bool("registration_open", registrationOpen), zap.Error(err), ) return fmt.Errorf("failed to toggle registration status: %w", err) } s.logger.Info("Registration status updated successfully", zap.Uint("event_id", eventID), zap.Bool("registration_open", registrationOpen), ) return nil }