277 lines
7.3 KiB
JavaScript
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();
|