Job-Kalender Termine mit externen Kalendern synchronisieren: Unterschied zwischen den Versionen

Aus GEVITAS
Wechseln zu: Navigation, Suche
(Termin-Daten aus dem JobKalender (MAufJob) einlesen)
Zeile 23: Zeile 23:
 
Dazu kann dieser SQL-Script verwendet werden:
 
Dazu kann dieser SQL-Script verwendet werden:
 
   
 
   
  select MAufJob.LFDNR, MAufJob.AUFTRNR, MAufJob.DATUM, MAufJob.DATUMBIS, MAufJob.UHRZEITVON, MAufJob.UHRZEITBIS, MAufJob.PERSONEN,
+
  select
  MAufJob.text, MAufJob.ORT, MAufJob.ERFDAT, MAufJob.ERFUSER,
+
  MAufJob.BETREFF,MAufJob.ADRKURZNAME, MAufJob.AENDDAT, MAufJob.AENDUSER,
+
-- Primary Key, Unique index:
  MAufJob.TERMINART, MAufJob.ID_STRING, MAufJob.TERMSTATUS, MAufJob.TERMIN_GANZTAEGIG, MAufJob.Changed, MAufJob.TerminTyp,
+
MAufJob.LFDNR, MAufJob.ID_STRING,
  MAufJob.Anzahl, MAufJob.OBERGRUPPE, MAufJob.GRUPPE, MAufJob.UNTGRUPPE, MAufJob.ARTNR, MAufJob.MENGENTERMIN,
+
  MAufJob.ZU_MAUFJOB_LFDNR, MAufJob.BeauftragungsArt, MAufJob.JobCalChanged, MAufJob.BemerkungIntern, MAufJob.BemerkungExtern,
+
-- Datum/Uhrzeit von-bis:
  MAufJob.VeranstOrt, MAufJob.VeranstRaum, MAufJob.CLOUD_EVENT_ID,
+
MAufJob.DATUM, MAufJob.DATUMBIS, MAufJob.UHRZEITVON, MAufJob.UHRZEITBIS,
 +
 
 +
-- Person-Kurzname lt. Pers.Stammdaten:
 +
MAufJob.PERSONEN,
 +
 +
-- Gehört zu AuftrNr (kann auch 0 sein!):
 +
  MAufJob.AUFTRNR,
 +
 +
-- Betreff, Text, Ort:
 +
  MAufJob.BETREFF, MAufJob.text, MAufJob.ORT,
 +
 
 +
-- Wenn Termin für Kunde: Kurzname lt. Stammdaten "Adr"
 +
MAufJob.ADRKURZNAME,
 +
 
 +
  MAufJob.TerminArt, MAufJob.TermStatus, MAufJob.TerminTyp,
 +
 
 +
-- Ganztägiger Termin 0/1
 +
MAufJob.TERMIN_GANZTAEGIG,
 +
 +
-- Geändert 0/1:
 +
MAufJob.Changed,
 +
 +
-- Anzahl bei Mengenterminen:
 +
MAufJob.Anzahl, MAufJob.MENGENTERMIN,
 +
   
 +
-- Artikel-Daten, wenn Termin einen Artikelbezug hat:
 +
MAufJob.OBERGRUPPE, MAufJob.GRUPPE, MAufJob.UNTGRUPPE, MAufJob.ARTNR,  
 +
 
 +
  MAufJob.ZU_MAUFJOB_LFDNR,
 +
MAufJob.BeauftragungsArt, MAufJob.JobCalChanged, MAufJob.BemerkungIntern, MAufJob.BemerkungExtern,
 +
  MAufJob.VeranstOrt, MAufJob.VeranstRaum,  
 +
 +
-- Verweis auf Externes Kalender-Item varchar(512):
 +
MAufJob.CLOUD_EVENT_ID,
 +
 +
 +
MAufJob.ERFDAT, MAufJob.ERFUSER,
 +
MAufJob.AENDDAT, MAufJob.AENDUSER,
 +
 
  MAUFKO.VERANSTNAME, MAUFKO.BEARBEITER,
 
  MAUFKO.VERANSTNAME, MAUFKO.BEARBEITER,
  Pers.PERSNR, Pers.KURZZEICHEN, Pers.VORNAME, Pers.NACHNAME, Pers.SPRACHE, Pers.SyncStatus, Pers.SyncAddress
+
 +
-- Personen/Ressourcen-Daten aus den Stammdaten:
 +
  Pers.PERSNR, Pers.KURZZEICHEN, Pers.VORNAME, Pers.NACHNAME, Pers.SPRACHE, Pers.SyncStatus, Pers.SyncAddress,
 +
 
  from MAufJob MAufJob
 
  from MAufJob MAufJob
  left outer join pers Pers on Pers.KURZZEICHEN=MAufJob.PERSONEN
+
  left outer join Pers Pers on Pers.KURZZEICHEN=MAufJob.PERSONEN
  left outer join maufko MAUFKO on MAUFKO.AUFTRNR=MAufJob.AUFTRNR
+
  left outer join MAufKo MAUFKO on MAUFKO.AUFTRNR=MAufJob.AUFTRNR
 
   
 
   
 
  -- Nur TerminTyp 3=Arbeitszeit-Termine:
 
  -- Nur TerminTyp 3=Arbeitszeit-Termine:

Version vom 16. Februar 2026, 21:01 Uhr

1 Allgemeines

Hier wird beschrieben, wie man Termine aus dem JobKalender mit einem externen System synchronisieren kann.

Dabei wird davon ausgegangen, dass der JobKalender das führende System ist. Das bedeutet:

  • Für einen Termin gibt es drei Synchronisations-Momente:
    • Termin wurde angelegt
    • Termin wurde geändert. Das kann der Zeitraum, die Ressource/Person, der Text usw. sein.
    • Termin wurde gelöscht
  • Auftrags-Termine werden ausschließlich im JobKalender angelegt, geändert oder gelöscht.

Basis der Beschreibung ist das Zusatz-Modul GooCal, das Termine aus dem JobKalender mit Google©-Kalendern synchronisiert.


2 Ablauf einer Synchronisation

Zur Erinnerung: Daten werden hier nur in eine Richtung synchronisiert, nämlich vom JobKalender zum externen Kalender!


2.1 Termin-Daten aus dem JobKalender (MAufJob) einlesen

Dazu kann dieser SQL-Script verwendet werden:

select

-- Primary Key, Unique index:
MAufJob.LFDNR, MAufJob.ID_STRING,

-- Datum/Uhrzeit von-bis:
MAufJob.DATUM, MAufJob.DATUMBIS, MAufJob.UHRZEITVON, MAufJob.UHRZEITBIS,
-- Person-Kurzname lt. Pers.Stammdaten:
MAufJob.PERSONEN,

-- Gehört zu AuftrNr (kann auch 0 sein!):
MAufJob.AUFTRNR,

-- Betreff, Text, Ort:
MAufJob.BETREFF, MAufJob.text, MAufJob.ORT,
-- Wenn Termin für Kunde: Kurzname lt. Stammdaten "Adr"
MAufJob.ADRKURZNAME,
MAufJob.TerminArt, MAufJob.TermStatus, MAufJob.TerminTyp,
-- Ganztägiger Termin 0/1
MAufJob.TERMIN_GANZTAEGIG,

-- Geändert 0/1:
MAufJob.Changed,

-- Anzahl bei Mengenterminen:
MAufJob.Anzahl, MAufJob.MENGENTERMIN,

-- Artikel-Daten, wenn Termin einen Artikelbezug hat:
MAufJob.OBERGRUPPE, MAufJob.GRUPPE, MAufJob.UNTGRUPPE, MAufJob.ARTNR, 
MAufJob.ZU_MAUFJOB_LFDNR,
MAufJob.BeauftragungsArt, MAufJob.JobCalChanged, MAufJob.BemerkungIntern, MAufJob.BemerkungExtern,
MAufJob.VeranstOrt, MAufJob.VeranstRaum, 

-- Verweis auf Externes Kalender-Item varchar(512):
MAufJob.CLOUD_EVENT_ID,


MAufJob.ERFDAT, MAufJob.ERFUSER,
MAufJob.AENDDAT, MAufJob.AENDUSER,

MAUFKO.VERANSTNAME, MAUFKO.BEARBEITER,

-- Personen/Ressourcen-Daten aus den Stammdaten:
Pers.PERSNR, Pers.KURZZEICHEN, Pers.VORNAME, Pers.NACHNAME, Pers.SPRACHE, Pers.SyncStatus, Pers.SyncAddress,

from MAufJob MAufJob
left outer join Pers Pers on Pers.KURZZEICHEN=MAufJob.PERSONEN
left outer join MAufKo MAUFKO on MAUFKO.AUFTRNR=MAufJob.AUFTRNR

-- Nur TerminTyp 3=Arbeitszeit-Termine:
where MAufJob.TerminTyp=3

-- Nur Personen/Ressourcen mit Kennzeichen > 0: 1=Google 2=Outlook/Exchange
-- Das wird in den Personen-Stammdaten in REFLEX so festgelegt.
and ( Pers.SyncStatus = 1 or Pers.KURZZEICHEN is null )

-- Nur wenn in den Personen-Stammdaten eine Synch-Adresse steht:
and Pers.SyncAddress > 
  
-- Auch überlappende Termine (wie in der Dispo):
and ( (MAufJob.DATUM <= 'DatumVon'
       AND
	(MAufJob.DATUMBIS >= 'DatumVon'
    )

-- Nur Termine mit diesem Status:
-- 1=Zugesagt, Bestätigt 4=Angefragt 6=Bestellung (Überhang)
and ( MAufJob.TERMSTATUS=1 or MAufJob.TERMSTATUS=4 or MAufJob.TERMSTATUS=6)
order by MAufJob.DATUM

2.2 Externe Kalender-Einträge einlesen

Daten aus dem Google-Kalender, Exchange o.ä im Zeitraum von DatumVon bis DatumBis (DatumVon + Anzahl Tage) in den Speicher einlesen und dort untersuchen:

2.3 Daten verarbeiten

2.3.1 Kalender-Einträge durchlaufen und ggf. löschen:

  • Den Key (z.B. "EventID") des Termins in der Tabelle MAufJob.CLOUD_EVENT_ID suchen.
  • Wenn der dort nicht (mehr) gespeichert ist: Kalender-Item löschen!

2.3.2 Tabelle MAufJob durchlaufen und ggf. neu einfügen

  • Mit dem o.a. select die Termindaten einlesen.
  • Wichtig sind - neben den Inhaltsfelder des Termins - diese Felder:
MAufJob.LFDNR
Eindeutige ID (Integer not null) eines Termins in der REFLEX-Datenbank.
MAufJob.CLOUD_EVENT_ID
Eindeutige ID (String null) eines Termins im externen Kalender.
  • Wenn in MAufJob.CLOUD_EVENT_ID kein Eintrag steht: Kalender-Item einfügen!
  • Kalender-Item (Eintrag) Felder:
    • Summary: Betreff
    • Description: Beschreibung, üblicherweise aus Terminart, VA-Name, VA-Ort, VA-Raum usw.
    • Location: Ort
    • Email
    • StartTime (Datum + Uhrzeit)
    • EndTime (Datum + Uhrzeit)
  • Die API des Kalenders muss dabei die ID des Kalender-Eintrags zurückliefern.
  • Diese ID muss das Synch-Programm in MAufJob.CLOUD_EVENT_ID speichern:
 update MAUFJOB set CLOUD_EVENT_ID=@GlobalAppointmentID where LFDNR=N
  • Der Ordner-Name in Outlook/Exchange muss in MAufJob.OrdnerName varchar(255) gespeichert werden.


2.3.3 Tabelle MAufJob durchlaufen, bei Änderungen/Unterschieden Kalender-Item updaten

  • MAufJob.CLOUD_EVENT_ID das Kalender-Item einlesen, die Einträge miteinander vergleichen
  • Üblicherweise hat ein Kalender-Eintrag diese Felder:
    • Summary: Betreff
    • Description: Beschreibung, üblicherweise aus Terminart, VA-Name, VA-Ort, VA-Raum usw.
    • Location: Ort
    • Email
    • StartTime (Datum + Uhrzeit)
    • EndTime (Datum + Uhrzeit)
  • Wenn es irgendwo einen Unterschied gibt: Kalender-Item entsprechend updaten!


3 Termin-Item in Outlook/Exchange

Item-Properties:

Subject         -> Betreff           (String)
Body            -> Termin Text       (String)
Start           -> Termin Anfang     (Datum/Uhrzeit als DateTime)
Duration        -> Termin Dauer in Minuten  (Integer)
End             -> Termin Ende       (Datum/Uhrzeit als DateTime)
Location        -> Ort               (String)
CreationTime    -> Termin wurde an diesem Datum und Uhrzeit angelegt (Datum/Uhrzeit als String!)

BusyStatus      -> Termin Option [Anzeige als]: (Mögliche Werte: 0, 1, 2, 3 => (Numerische Werte als String!!!)
                      0 => Frei
                      1 => Mit Vorbehalt / Unter Vorbehalt
                      2 => Beschäftig / Gebucht
                      3 => Abwesend

ReminderPlaySound          -> Auskunft (true, false), ob ein Termin mit einem Sound versehen ist (Boolean)
ReminderSet                -> Gibt Auskunft (true, false), ob ein Termin mit einer Erinnerung versehen ist (Boolean)
ReminderMinutesBeforeStart -> Zeigt in Minuten (Numerische Werte als String!) die Erinnerung des Termins
                              (also z.B. 30 bedeutet, dass die Erinnerung 30 Minuten von dem Anfangs des Termin aktiv wird)
AllDayEvent                -> True, wenn auch Enddatum angegeben, dann über mehrere Tage!

GlobalAppointmentID         -> Eindeutige ID des Termins.

4 Voraussetzungen

Die ID des Kalender-Termins darf max. 512 Zeichen groß sein. Sie wird zum Abgleich in der Tabelle MAufJob im Feld CLOUD_EVENT_ID varchar(512) gespeichert. In Outlook/Exchance ist dies das Felds Item.GlobalAppointmentID. Anders als reguläre Entry IDs ändert sich die GlobalAppointmentID nicht beim Verschieben in andere Ordner/Speicher oder beim Export/Import!


Der Ordner-Name in Outlook/Exchange darf max. 255 Zeichen groß sein. Er wird in MAufJob.OrdnerName varchar(255) gespeichert.

5 Links

JobKalender

Datenbank-Beschreibung zum Job-Kalender