Files
miriamgemeinde/services/EventService.js

277 lines
7.3 KiB
JavaScript

const { Event, Institution, EventPlace, ContactPerson, EventType } = require('../models');
const { Op } = require('sequelize');
const moment = require('moment');
class EventService {
/**
* Alle Events abrufen
*/
async getAllEvents() {
try {
const events = await Event.findAll({
include: [
{ model: Institution, as: 'institution' },
{ model: EventPlace, as: 'eventPlace' },
{ model: EventType, as: 'eventType' },
{ model: ContactPerson, as: 'contactPersons', through: { attributes: [] } }
],
order: ['name', 'date', 'time']
});
return events;
} catch (error) {
console.error('Error fetching all events:', error);
throw new Error('EVENTS_FETCH_ERROR');
}
}
/**
* Event anhand ID abrufen
*/
async getEventById(id) {
try {
if (!id || isNaN(parseInt(id))) {
throw new Error('VALIDATION_ERROR: Ungültige ID');
}
const event = await Event.findByPk(id, {
include: [
{ model: Institution, as: 'institution' },
{ model: EventPlace, as: 'eventPlace' },
{ model: EventType, as: 'eventType' },
{ model: ContactPerson, as: 'contactPersons', through: { attributes: [] } }
]
});
if (!event) {
throw new Error('EVENT_NOT_FOUND');
}
return event;
} catch (error) {
console.error('Error fetching event by ID:', error);
throw new Error('EVENT_FETCH_ERROR');
}
}
/**
* Events filtern
*/
async filterEvents(filterData) {
try {
const { id, places, types, display } = filterData;
// Basis-Where-Klausel für zukünftige Events
const where = {
[Op.or]: [
{
date: {
[Op.or]: [
{ [Op.gte]: moment().startOf('day').toDate() },
{ [Op.eq]: null }
]
}
},
{ dayOfWeek: { [Op.gte]: 0 } }
]
};
const order = [
['date', 'ASC'],
['time', 'ASC']
];
// Spezielle Filter
if (id === 'all') {
return await this._getAllFutureEvents(where, order);
}
if (id === 'home') {
return await this._getHomepageEvents(where, order);
}
if (!id && !places && !types) {
return { events: [], places: [], types: [], contactPersons: [] };
}
// Weitere Filter anwenden
if (id) {
where.id = id;
}
if (places && places.length > 0) {
where.event_place_id = {
[Op.in]: places.map(id => parseInt(id))
};
}
if (types && types.length > 0) {
where.eventTypeId = {
[Op.in]: types.map(id => parseInt(id))
};
}
const events = await Event.findAll({
where,
include: [
{ model: Institution, as: 'institution' },
{ model: EventPlace, as: 'eventPlace' },
{ model: EventType, as: 'eventType' },
{ model: ContactPerson, as: 'contactPersons', through: { attributes: [] } }
],
order: order,
});
// Events basierend auf Display-Feldern filtern
const displayFields = display || [];
const filteredEvents = this._filterEventFields(events, displayFields);
return { events: filteredEvents };
} catch (error) {
console.error('Error filtering events:', error);
throw new Error('EVENT_FILTER_ERROR');
}
}
/**
* Event erstellen
*/
async createEvent(eventData) {
try {
const { contactPersonIds, ...eventDataWithoutContacts } = eventData;
// Validierung
if (!eventDataWithoutContacts.name) {
throw new Error('VALIDATION_ERROR: Event-Name ist erforderlich');
}
eventDataWithoutContacts.alsoOnHomepage = eventDataWithoutContacts.alsoOnHomepage ?? 0;
const event = await Event.create(eventDataWithoutContacts);
if (contactPersonIds && contactPersonIds.length > 0) {
await event.setContactPersons(contactPersonIds);
}
return event;
} catch (error) {
console.error('Error creating event:', error);
throw new Error('EVENT_CREATE_ERROR');
}
}
/**
* Event aktualisieren
*/
async updateEvent(id, eventData) {
try {
if (!id || isNaN(parseInt(id))) {
throw new Error('VALIDATION_ERROR: Ungültige ID');
}
const { contactPersonIds, ...eventDataWithoutContacts } = eventData;
const event = await Event.findByPk(id);
if (!event) {
throw new Error('EVENT_NOT_FOUND');
}
await event.update(eventDataWithoutContacts);
if (contactPersonIds !== undefined) {
await event.setContactPersons(contactPersonIds || []);
}
return event;
} catch (error) {
console.error('Error updating event:', error);
throw new Error('EVENT_UPDATE_ERROR');
}
}
/**
* Event löschen
*/
async deleteEvent(id) {
try {
if (!id || isNaN(parseInt(id))) {
throw new Error('VALIDATION_ERROR: Ungültige ID');
}
const event = await Event.findByPk(id);
if (!event) {
throw new Error('EVENT_NOT_FOUND');
}
await event.destroy();
return { message: 'Event erfolgreich gelöscht' };
} catch (error) {
console.error('Error deleting event:', error);
throw new Error('EVENT_DELETE_ERROR');
}
}
/**
* Alle zukünftigen Events abrufen
*/
async _getAllFutureEvents(where, order) {
const events = await Event.findAll({
where,
include: [
{ model: Institution, as: 'institution' },
{ model: EventPlace, as: 'eventPlace' },
{ model: EventType, as: 'eventType' },
{ model: ContactPerson, as: 'contactPersons', through: { attributes: [] } }
],
order: order,
logging: console.log
});
return { events };
}
/**
* Homepage Events abrufen
*/
async _getHomepageEvents(where, order) {
const events = await Event.findAll({
where: {
alsoOnHomepage: 1,
date: { [Op.gte]: moment().startOf('day').toDate() }
},
include: [
{ model: Institution, as: 'institution' },
{ model: EventPlace, as: 'eventPlace' },
{ model: EventType, as: 'eventType' },
{ model: ContactPerson, as: 'contactPersons', through: { attributes: [] } },
],
order: order,
});
return { events };
}
/**
* Event-Felder basierend auf Display-Feldern filtern
*/
_filterEventFields(events, displayFields) {
return events.map(event => {
const filteredEvent = { ...event.toJSON() };
if (!displayFields.includes('name')) delete filteredEvent.name;
if (!displayFields.includes('type')) delete filteredEvent.eventType;
if (!displayFields.includes('place')) delete filteredEvent.eventPlace;
if (!displayFields.includes('description')) delete filteredEvent.description;
if (!displayFields.includes('time')) delete filteredEvent.time;
if (!displayFields.includes('time')) delete filteredEvent.endTime;
if (!displayFields.includes('contactPerson')) delete filteredEvent.contactPersons;
if (!displayFields.includes('day')) delete filteredEvent.dayOfWeek;
if (!displayFields.includes('institution')) delete filteredEvent.institution;
return filteredEvent;
});
}
}
module.exports = new EventService();