feat: Equipment-System, Buchungsbearbeitung, Kundenadresse, LexOffice-Fix
- Vintage Modell hinzugefuegt - Equipment Multi-Select (Neue Buchung + Bearbeitung) - Kundenadresse in Formularen - Bearbeiten-Seite fuer Buchungen - Abbau-Zeiten in Formularen und Uebersicht - Vertrag PDF nur bei Privatkunden - LexOffice Kontakt-Erstellung Fix (BUSINESS) - Zurueck-Pfeil auf Touren-Seite
This commit is contained in:
@@ -13,19 +13,46 @@ export interface CalendarEvent {
|
||||
export class NextcloudCalendarService {
|
||||
private client: any;
|
||||
private initialized: boolean = false;
|
||||
private initPromise: Promise<void> | null = null;
|
||||
|
||||
async initialize() {
|
||||
if (this.initialized) return;
|
||||
// Wenn bereits am Initialisieren, warte auf Abschluss
|
||||
if (this.initPromise) {
|
||||
return this.initPromise;
|
||||
}
|
||||
|
||||
// Wenn bereits initialisiert, fertig
|
||||
if (this.initialized && this.client) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Neue Initialisierung starten
|
||||
this.initPromise = this._doInitialize();
|
||||
|
||||
try {
|
||||
await this.initPromise;
|
||||
} finally {
|
||||
this.initPromise = null;
|
||||
}
|
||||
}
|
||||
|
||||
private async _doInitialize() {
|
||||
const serverUrl = process.env.NEXTCLOUD_URL;
|
||||
const username = process.env.NEXTCLOUD_USERNAME;
|
||||
const password = process.env.NEXTCLOUD_PASSWORD;
|
||||
|
||||
console.log('🔍 Nextcloud credentials check:');
|
||||
console.log(' URL:', serverUrl);
|
||||
console.log(' Username:', username);
|
||||
console.log(' Password length:', password?.length, 'chars');
|
||||
|
||||
if (!serverUrl || !username || !password) {
|
||||
throw new Error('Nextcloud credentials not configured');
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('⏳ Creating Nextcloud CalDAV client...');
|
||||
|
||||
this.client = await createDAVClient({
|
||||
serverUrl: `${serverUrl}/remote.php/dav`,
|
||||
credentials: {
|
||||
@@ -37,10 +64,12 @@ export class NextcloudCalendarService {
|
||||
});
|
||||
|
||||
this.initialized = true;
|
||||
console.log('✅ Nextcloud CalDAV client initialized');
|
||||
} catch (error) {
|
||||
console.log('✅ Nextcloud CalDAV client initialized successfully');
|
||||
} catch (error: any) {
|
||||
console.error('❌ Failed to initialize Nextcloud CalDAV client:', error);
|
||||
throw error;
|
||||
this.initialized = false;
|
||||
this.client = null;
|
||||
throw new Error(`Nextcloud initialization failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,22 +149,33 @@ export class NextcloudCalendarService {
|
||||
throw new Error('No calendars found in Nextcloud');
|
||||
}
|
||||
|
||||
const calendar = calendars[0];
|
||||
// Suche nach "Buchungen" Kalender, sonst verwende ersten
|
||||
let calendar = calendars.find((cal: any) =>
|
||||
cal.displayName?.toLowerCase().includes('buchung')
|
||||
);
|
||||
|
||||
if (!calendar) {
|
||||
console.warn('⚠️ Kein "Buchungen"-Kalender gefunden, verwende:', calendars[0].displayName);
|
||||
calendar = calendars[0];
|
||||
} else {
|
||||
console.log('✅ Verwende Kalender:', calendar.displayName);
|
||||
}
|
||||
|
||||
const event: CalendarEvent = {
|
||||
uid: `savethemoment-booking-${booking.id}`,
|
||||
summary: `${booking.customerName} - ${booking.location?.name || 'Unbekannt'}`,
|
||||
description: `
|
||||
Buchung #${booking.id}
|
||||
Buchung #${booking.bookingNumber || booking.id}
|
||||
Kunde: ${booking.customerName}
|
||||
E-Mail: ${booking.customerEmail}
|
||||
Telefon: ${booking.customerPhone || 'N/A'}
|
||||
Event-Typ: ${booking.eventType}
|
||||
Event-Location: ${booking.eventLocation || booking.eventAddress}
|
||||
Status: ${booking.status}
|
||||
Fotobox: ${booking.photobox?.name || 'Keine Box'}
|
||||
Fotobox: ${booking.photobox?.model || 'Keine Box'}
|
||||
Standort: ${booking.location?.name || 'Unbekannt'}
|
||||
Preis: ${booking.calculatedPrice || 0}€
|
||||
`.trim(),
|
||||
location: booking.location?.address || '',
|
||||
location: `${booking.eventAddress || ''}, ${booking.eventZip || ''} ${booking.eventCity || ''}`.trim(),
|
||||
startDate: new Date(booking.eventDate),
|
||||
endDate: new Date(new Date(booking.eventDate).getTime() + 4 * 60 * 60 * 1000),
|
||||
status: booking.status,
|
||||
@@ -143,10 +183,12 @@ Standort: ${booking.location?.name || 'Unbekannt'}
|
||||
|
||||
try {
|
||||
await this.createEvent(calendar.url, event);
|
||||
console.log('✅ Event in Nextcloud erstellt:', event.summary);
|
||||
return event;
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
if (error.message?.includes('already exists') || error.response?.status === 412) {
|
||||
await this.updateEvent(calendar.url, event);
|
||||
console.log('✅ Event in Nextcloud aktualisiert:', event.summary);
|
||||
return event;
|
||||
}
|
||||
throw error;
|
||||
@@ -162,11 +204,20 @@ Standort: ${booking.location?.name || 'Unbekannt'}
|
||||
throw new Error('No calendars found in Nextcloud');
|
||||
}
|
||||
|
||||
const calendar = calendars[0];
|
||||
// Suche nach "Buchungen" Kalender, sonst verwende ersten
|
||||
let calendar = calendars.find((cal: any) =>
|
||||
cal.displayName?.toLowerCase().includes('buchung')
|
||||
);
|
||||
|
||||
if (!calendar) {
|
||||
calendar = calendars[0];
|
||||
}
|
||||
|
||||
const eventUid = `savethemoment-booking-${bookingId}`;
|
||||
|
||||
try {
|
||||
await this.deleteEvent(calendar.url, eventUid);
|
||||
console.log('✅ Event aus Nextcloud gelöscht:', eventUid);
|
||||
} catch (error) {
|
||||
console.error('Error removing booking from calendar:', error);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user