Helpers/scripts/_belegversand_setup.applescript aktualisiert

Erweiterungen der Funktionalität auf die Bedürfnisse von DATEV:
Belegversand.conf siehe jetzt so aus:

## Benutzer-Einstellungen - bitte individuell anpassen.
## Eine Kurz-Doku findest du in der Datei README-Belegversand.md

APP_VERSION=1.5
MAIL_TO_DEFAULT=echiriadis@netcologne.de
MAIL_CC_TO_DEFAULT=aischa.abdulaziz@gmail.de
MAIL_SUBJECT_PREFIX=Unterlagen

## Versandmodus: true = ein ZIP-Archiv (optional mit Passwort),
##               false = Belege einzeln anhängen (z.B. für DATEV)
ZIP_ARCHIVE=false
ZIP_PASSWORD_DEFAULT=

## Maximale Mailgröße in MB. Größere Sendungen werden auf mehrere Mails verteilt.
MAX_MAIL_SIZE_MB=20

## Erlaubte Dateitypen, durch Komma getrennt. Andere Belege werden
## vor dem Versand gemeldet (bitte vorher in PDF konvertieren).
SUPPORTED_FILE_TYPES_FOR_SENDING=pdf, tif, tiff

LOG_SENT_GROUP_NAME=Versendet
WRITE_DEBUG_LOG=true
SHOW_README=false
MAILBODY_FOLDER_NAME=mail_vorlagen
MAILBODY_RECORD_NAME=belegversand
SENT_TAG_FOR_DOCS=gesendet
PATH_TO_DRYRUN_PREVIEW=/tmp/DT-Belegversand-preview.txt

## Die folgenden Werte werden von der Software geschrieben.
## Bitte nur manuell editieren, wenn du weisst, was du tust!

BELEGE_ROOT_UUID=CBCEA210-6C76-4DB5-9195-2295354C6080
README_UUID=D5B05DFD-710E-4577-9808-E544741F2049
This commit is contained in:
2026-10-12 20:18:02 +00:00
parent 62ee4f4648
commit 7a6a7751f6
+228 -98
View File
@@ -1,5 +1,5 @@
(*
_belegversand_setup.scpt – Version 1.4
_belegversand_setup.scpt – Version 1.5
Rolle dieses Scripts
--------------------
Dieses Script hat eine Doppelfunktion:
@@ -14,9 +14,11 @@ Dieses Script hat eine Doppelfunktion:
- README-Datei anlegen/aktualisieren
- Mailbody-Datei anlegen/aktualisieren
- globale /Versendet_Outsider-Gruppe anlegen
- Gruppe /Originale für umgewandelte Fotos anlegen
Zielstruktur in DEVONthink
--------------------------
DB-Wurzel
├── Originale (Original-Fotos nach PDF-Umwandlung per Smart Rule)
├── Versendet_Outsider
│ ├── !Ergebnis
│ ├── sentlog_outsiders
@@ -35,6 +37,25 @@ Version 1.4:
-----------
- MAIL_CC_TO_DEFAULT in Config hinzugefügt
- Globale Versendet_Outsider-Gruppe wird automatisch angelegt
Version 1.5:
-----------
- Neue Config-Schlüssel:
ZIP_ARCHIVE, MAX_MAIL_SIZE_MB, SUPPORTED_FILE_TYPES_FOR_SENDING
- Setup fragt den Versandmodus ab (ZIP oder Einzeldateien);
ZIP-Passwort wird nur noch im ZIP-Modus abgefragt
- Fix: Jahres-/Monatsordner werden nicht mehr doppelt angelegt,
wenn sie bereits existieren
- Fix: Keine verschachtelte Gruppe Belege/Belege mehr, wenn die
ausgewählte Hauptgruppe bereits "Belege" heißt
- Fix: Jahresordner-Loggruppe nutzt den gewählten Namen
(LOG_SENT_GROUP_NAME) statt fest "Versendet"
- Aufgeräumt: doppelter debugInfoText-Block und überflüssige
basePath-Zuweisung entfernt
- Neu: Gruppe /Originale auf DB-Wurzel-Ebene (außerhalb der Belege,
damit die Smart Rule ihre eigenen Originale nicht erneut erfasst)
- Neu: Anleitung für die Smart Rule "Fotos → PDF" als Hinweisdialog
am Ende des Setups und im README (Smart Rules lassen sich per
AppleScript nicht anlegen)
*)
-- Name der DEVONthink-Konfigurationsgruppe.
property configGroupName : "_config"
@@ -52,7 +73,7 @@ property requiredConfigKey : "BELEGE_ROOT_UUID="
-- Name des eigentlichen Hauptscripts.
property mainScriptName : "_belegversand.scpt"
-- Versionsinformation für README und Hinweise.
property appVersion : "1.4"
property appVersion : "1.5"
property basePath : "Library/Application Scripts/com.devon-technologies.think/Menu/Belegversand"
-- Default-Werte für die Erstkonfiguration.
property defaultMailTo : "steuer@name.de"
@@ -63,6 +84,14 @@ property defaultSentTagForDocs : "gesendet"
property defaultWriteDebugLog : "false"
property defaultShowReadme : "true"
property defaultDryRunPreviewPath : "/tmp/DT-Belegversand-preview.txt"
-- Neu in 1.5
property defaultZipArchive : "true"
property defaultMaxMailSizeMB : "20"
property defaultSupportedFileTypes : "pdf, tif, tiff"
-- Gruppe für Original-Fotos nach der PDF-Umwandlung (auf DB-Wurzel-Ebene)
property originalsGroupName : "Originale"
-- Monatsordner im Jahreszyklus
property monthNames : {"01_Januar", "02_Februar", "03_März", "04_April", "05_Mai", "06_Juni", "07_Juli", "08_August", "09_September", "10_Oktober", "11_November", "12_Dezember"}
(*
runSiblingScript(scriptFileName)
@@ -99,8 +128,6 @@ Versucht zuerst:
- plain text
und fällt bei Bedarf zurück auf:
- content
Dieser Handler wird genutzt, um den Inhalt bestehender Config-Dateien
zu prüfen bzw. zu lesen.
*)
on recordText(theRecord)
tell application id "DNtp"
@@ -123,9 +150,6 @@ end recordText
isGroupByRecord(theRecord)
--------------------------
Prüft, ob ein DEVONthink-Record eine Gruppe ist.
Wird in der Einrichtung verwendet, um sicherzustellen,
dass die Belege-Hauptgruppe wirklich eine Gruppe/Ordnerstruktur ist
und nicht versehentlich ein Einzelobjekt wie ein Bild oder PDF.
*)
on isGroupByRecord(theRecord)
tell application id "DNtp"
@@ -144,12 +168,6 @@ mit einem bestimmten Namen.
Rückgabe:
- den gefundenen Record
- oder missing value
Verwendung:
- _config finden
- belegversand.conf finden
- README finden
- mail_vorlagen finden
- Mailbody-Textrecord finden
*)
on findChildByName(parentRecord, childName)
tell application id "DNtp"
@@ -172,6 +190,7 @@ Beispiele:
- _config
- mail_vorlagen
- Versendet_Outsider
- Jahres- und Monatsordner
*)
on getOrCreateChildGroup(parentRecord, groupName)
set existingGroup to my findChildByName(parentRecord, groupName)
@@ -186,9 +205,6 @@ getOrCreateTextRecord(parentRecord, recordName, initialText)
------------------------------------------------------------
Sucht unter parentRecord einen Textrecord mit gegebenem Namen.
Falls er nicht existiert, wird er mit initialText angelegt.
Verwendung:
- belegversand.conf
- Mailbody-Datei
*)
on getOrCreateTextRecord(parentRecord, recordName, initialText)
set existingRecord to my findChildByName(parentRecord, recordName)
@@ -202,8 +218,6 @@ end getOrCreateTextRecord
getOrCreateMarkdownRecord(parentRecord, recordName, initialText)
----------------------------------------------------------------
Wie getOrCreateTextRecord, aber für Markdown-Records.
Verwendung:
- README-Belegversand
*)
on getOrCreateMarkdownRecord(parentRecord, recordName, initialText)
set existingRecord to my findChildByName(parentRecord, recordName)
@@ -217,25 +231,25 @@ end getOrCreateMarkdownRecord
buildConfigText(...)
--------------------
Baut den vollständigen Inhalt der Konfigurationsdatei belegversand.conf.
Aufbau:
- zuerst die für User relativ ungefährlichen / vorgesehenen Einstellungen
- dann ein erklärender Hinweisblock
- darunter die technischen Werte, die vom Script geschrieben werden
und möglichst nicht manuell verändert werden sollten
Wichtig:
--------
Die Konfigurationsdatei ist bewusst als einfacher key=value-Text aufgebaut.
Die Parser im Hauptscript lesen nur Zeilen, die wirklich mit KEY= beginnen.
Freie Kommentar- oder Trennerzeilen sind daher unproblematisch.
Kommentarzeilen (##) sind daher unproblematisch und dienen als Kurzhilfe.
*)
on buildConfigText(mailToDefault, mailCcToDefault, subjectPrefix, zipPasswordDefault, logSentGroupName, belegeRootUUID, writeDebugLogValue, showReadmeValue, readmeUUID, mailBodyFolderName, mailBodyRecordName, sentTagForDocs, dryRunPreviewPath)
on buildConfigText(mailToDefault, mailCcToDefault, subjectPrefix, zipArchiveValue, zipPasswordDefault, maxMailSizeMB, supportedFileTypes, logSentGroupName, belegeRootUUID, writeDebugLogValue, showReadmeValue, readmeUUID, mailBodyFolderName, mailBodyRecordName, sentTagForDocs, dryRunPreviewPath)
return "## Benutzer-Einstellungen - bitte individuell anpassen." & return & ¬
"## Eine Kurz-Doku findest du in der Datei README-Belegversand.md" & return & return & ¬
"APP_VERSION=" & appVersion & return & ¬
"MAIL_TO_DEFAULT=" & mailToDefault & return & ¬
"MAIL_CC_TO_DEFAULT=" & mailCcToDefault & return & ¬
"MAIL_SUBJECT_PREFIX=" & subjectPrefix & return & ¬
"ZIP_PASSWORD_DEFAULT=" & zipPasswordDefault & return & ¬
"MAIL_SUBJECT_PREFIX=" & subjectPrefix & return & return & ¬
"## Versandmodus: true = ein ZIP-Archiv (optional mit Passwort)," & return & ¬
"## false = Belege einzeln anhängen (z.B. für DATEV)" & return & ¬
"ZIP_ARCHIVE=" & zipArchiveValue & return & ¬
"ZIP_PASSWORD_DEFAULT=" & zipPasswordDefault & return & return & ¬
"## Maximale Mailgröße in MB. Größere Sendungen werden auf mehrere Mails verteilt." & return & ¬
"MAX_MAIL_SIZE_MB=" & maxMailSizeMB & return & return & ¬
"## Erlaubte Dateitypen, durch Komma getrennt. Andere Belege werden" & return & ¬
"## vor dem Versand gemeldet (bitte vorher in PDF konvertieren)." & return & ¬
"SUPPORTED_FILE_TYPES_FOR_SENDING=" & supportedFileTypes & return & return & ¬
"LOG_SENT_GROUP_NAME=" & logSentGroupName & return & ¬
"WRITE_DEBUG_LOG=" & writeDebugLogValue & return & ¬
"SHOW_README=" & showReadmeValue & return & ¬
@@ -272,9 +286,38 @@ on buildReadmeText()
"1. Belege in DEVONthink auswählen" & return & ¬
"2. Scripts → START aufrufen" & return & ¬
"3. Dialog folgen → Versand vorbereiten" & return & return & ¬
"## Versandmodus" & return & return & ¬
"- `ZIP_ARCHIVE=true`: alle Belege in einem ZIP-Archiv (optional mit Passwort)" & return & ¬
"- `ZIP_ARCHIVE=false`: Belege einzeln angehängt (z.B. für DATEV)" & return & ¬
"- Ohne ZIP gehen die Belege unverschlüsselt raus (nur TLS beim Transport)." & return & ¬
"- Nur Dateitypen aus `SUPPORTED_FILE_TYPES_FOR_SENDING` werden versendet." & return & ¬
" Fotos (JPG/HEIC/PNG) vorher in PDF umwandeln – am besten automatisch (siehe unten)." & return & return & ¬
"## Fotos automatisch in PDF umwandeln (Smart Rule)" & return & return & ¬
"Smart Rules lassen sich nicht per Script anlegen – bitte einmalig von Hand einrichten:" & return & return & my buildSmartRuleSteps("Belege") & return & ¬
"Hinweise:" & return & return & ¬
"- Die Gruppe `" & originalsGroupName & "` liegt bewusst auf oberster Ebene, also außerhalb der Belege. So erfasst die Regel ihre eigenen Originale nicht erneut." & return & ¬
"- Smart Rules gehören zur DEVONthink-Installation, nicht zur Datenbank. Auf einem weiteren Mac muss die Regel dort erneut angelegt werden." & return & ¬
"- Mit einem einzelnen Test-Foto prüfen, ob danach das PDF in der Belege-Gruppe und das Foto in `" & originalsGroupName & "` liegt." & return & return & ¬
"Hinweis: Detaillierte Dokumentation immer im Repository (siehe oben)."
end buildReadmeText
(*
buildSmartRuleSteps(belegeGroupName)
------------------------------------
Schritt-für-Schritt-Anleitung für die Smart Rule "Fotos → PDF".
Wird im README und im Abschlussdialog des Setups verwendet.
Die Bezeichnungen der Menüs/Aktionen können je nach DEVONthink-Version
leicht abweichen.
*)
on buildSmartRuleSteps(belegeGroupName)
return "1. In DEVONthink eine neue intelligente Regel (Smart Rule) anlegen." & return & ¬
"2. Name: z.B. „Belege: Fotos → PDF“." & return & ¬
"3. Suchen in: Gruppe „" & belegeGroupName & "“ (inkl. Untergruppen)." & return & ¬
"4. Bedingung: Art ist Bild." & return & ¬
"5. Ausführen: beim Importieren (optional zusätzlich: beim Hinzufügen)." & return & ¬
"6. Aktion: in durchsuchbares PDF umwandeln (OCR) – oder, falls OCR nicht verfügbar: in PDF konvertieren." & return & ¬
"7. Aktion: Original verschieben nach Gruppe „" & originalsGroupName & "“." & return
end buildSmartRuleSteps
(*
buildDefaultMailBodyText()
--------------------------
Erzeugt den Standardtext für die Mailbody-Datei.
@@ -349,42 +392,51 @@ on isNovemberOrDecember()
return (currentMonth = 11 or currentMonth = 12)
end isNovemberOrDecember
(*
createYearCycleInGroup(parentGroup, yearString)
-----------------------------------------------
createYearCycleInGroup(parentGroup, yearString, logGroupName)
-------------------------------------------------------------
Erstellt einen Jahresordner (z.B. "2026") unter parentGroup
und erzeugt die Monatsordner (01_Januar bis 12_Dezember) darin.
und erzeugt die Monatsordner (01_Januar bis 12_Dezember) darin,
dazu die Loggruppe (LOG_SENT_GROUP_NAME) und "Provisionsabrechnungen".
Bereits vorhandene Ordner werden wiederverwendet, nicht dupliziert.
(DEVONthink legt bei "create record" sonst stillschweigend Duplikate an.)
*)
on createYearCycleInGroup(parentGroup, yearString)
set monthNames to {"01_Januar", "02_Februar", "03_März", "04_April", "05_Mai", "06_Juni", "07_Juli", "08_August", "09_September", "10_Oktober", "11_November", "12_Dezember"}
on createYearCycleInGroup(parentGroup, yearString, logGroupName)
set yearGroupRecord to my getOrCreateChildGroup(parentGroup, yearString)
tell application id "DNtp"
set yearGroupRecord to create record with {name:yearString, type:group} in parentGroup
-- Monatsordner erstellen
repeat with monthName in monthNames
try
create record with {name:monthName, type:group} in yearGroupRecord
on error
-- Falls Ordner bereits existiert, einfach weitermachen
end try
end repeat
-- Versendet-Ordner am Ende hinzufügen
try
create record with {name:"Versendet", type:group} in yearGroupRecord
on error
-- Falls Ordner bereits existiert, einfach weitermachen
end try
-- Provisionsabrechnungen-Ordner hinzufügen
try
create record with {name:"Provisionsabrechnungen", type:group} in yearGroupRecord
on error
-- Falls Ordner bereits existiert, einfach weitermachen
end try
end tell
repeat with monthName in my monthNames
my getOrCreateChildGroup(yearGroupRecord, monthName as text)
end repeat
my getOrCreateChildGroup(yearGroupRecord, logGroupName)
my getOrCreateChildGroup(yearGroupRecord, "Provisionsabrechnungen")
end createYearCycleInGroup
(*
yearCycleStatus(belegeRootRecord, belegeRootName, yearString)
-------------------------------------------------------------
Prüft, ob der Jahreszyklus für ein Jahr bereits existiert.
Rückgabe:
- "missing" : Jahresordner (oder Gruppe Belege) fehlt
- "partial" : Jahresordner vorhanden, aber Monatsordner fehlen
- "complete" : Jahresordner mit allen 12 Monatsordnern vorhanden
*)
on yearCycleStatus(belegeRootRecord, belegeRootName, yearString)
if belegeRootName is "Belege" then
set belegeGroup to belegeRootRecord
else
set belegeGroup to my findChildByName(belegeRootRecord, "Belege")
if belegeGroup is missing value then return "missing"
end if
set yearGroup to my findChildByName(belegeGroup, yearString)
if yearGroup is missing value then return "missing"
repeat with monthName in my monthNames
if my findChildByName(yearGroup, monthName as text) is missing value then return "partial"
end repeat
return "complete"
end yearCycleStatus
(*
run
---
Haupteinstiegspunkt des Setup-Scripts.
@@ -395,7 +447,13 @@ on run
set sel to selection
if sel is {} then
display dialog "Bitte zuerst ein Objekt in der gewuenschten DEVONthink-Datenbank auswählen." buttons {"OK"} default button "OK"
display dialog "Belegversand – nichts ausgewählt" & return & return & ¬
"Bitte wähle in DEVONthink zuerst etwas in der Datenbank aus, mit der du arbeiten möchtest – am einfachsten die Gruppe „Belege“ oder einen beliebigen Beleg darin." & return & return & ¬
"Warum?" & return & ¬
"Das Script erkennt an deiner Auswahl, um welche Datenbank es geht, und sucht dort nach der Konfiguration (_config/belegversand.conf):" & return & return & ¬
"• Konfiguration gefunden → der Belegversand startet." & return & ¬
"• Keine Konfiguration → die Ersteinrichtung startet." & return & return & ¬
"Danach das Script einfach noch einmal aufrufen." buttons {"OK"} default button "OK" with title "Belegversand " & appVersion
return
end if
@@ -410,6 +468,9 @@ on run
return
end if
-- ─────────────────────────────────────────────
-- Ersteinrichtung: Belege-Hauptgruppe bestimmen
-- ─────────────────────────────────────────────
tell application id "DNtp"
set sel to selection
if sel is not {} then
@@ -431,10 +492,20 @@ on run
end if
end tell
set setupIntroText to "In dieser Datenbank ist der Belegversand noch nicht eingerichtet." & return & return & ¬
"Die Einrichtung legt an:" & return & ¬
"• _config – Konfiguration, README und Mail-Vorlagen" & return & ¬
"• Versendet_Outsider – Log für Belege außerhalb von Jahresordnern" & return & ¬
"• optional: Jahresordner mit Monatsordnern (01_Januar … 12_Dezember)" & return & return & ¬
"Bestehende Belege werden dabei nicht verändert." & return & return
if selectedIsGroup and selectedName is "Belege" then
display dialog "Es wurde noch keine gültige Konfiguration für den Belegversand gefunden." & return & return & "Die Einrichtung wird jetzt mit der bereits ausgewählten Belege-Hauptgruppe gestartet." buttons {"OK"} default button "OK"
display dialog setupIntroText & ¬
"Als Belege-Hauptgruppe wird die bereits ausgewählte Gruppe „Belege“ verwendet." buttons {"Abbrechen", "Einrichtung starten"} default button "Einrichtung starten" cancel button "Abbrechen" with title "Belegversand " & appVersion & " – Einrichtung"
else
display dialog "Es wurde noch keine gültige Konfiguration für den Belegversand gefunden." & return & return & "Bitte jetzt die Belege-Hauptgruppe auswählen und anschließend mit OK fortfahren." buttons {"OK"} default button "OK"
display dialog setupIntroText & ¬
"Wähle jetzt in DEVONthink die Belege-Hauptgruppe aus – also die Gruppe, in der alle Belege und Quittungen liegen (üblicherweise „Belege“)." & return & return & ¬
"Lass diesen Dialog dabei offen und klicke erst danach auf „Weiter“." buttons {"Abbrechen", "Weiter"} default button "Weiter" cancel button "Abbrechen" with title "Belegversand " & appVersion & " – Einrichtung"
end if
tell application id "DNtp"
@@ -476,45 +547,60 @@ on run
if confirmChoice is "Abbrechen" then return
end if
set yearCycleChoice to button returned of (display dialog "Soll ein Ordner Belege mit Jahresordner und Monatszyklen angelegt werden?" buttons {"Nein", "Ja"} default button "Ja")
-- Jahreszyklus: erst prüfen, was schon da ist, dann passend fragen
set currentYear to my getCurrentYear()
set yearsToCheck to {currentYear}
if my isNovemberOrDecember() then set end of yearsToCheck to (((currentYear as integer) + 1) as text)
set dbRootRecord to my getTopParentGroup(belegeRootRecord)
set allComplete to true
repeat with y in yearsToCheck
if my yearCycleStatus(belegeRootRecord, belegeRootName, y as text) is not "complete" then set allComplete to false
end repeat
set currentYearStatus to my yearCycleStatus(belegeRootRecord, belegeRootName, currentYear)
if yearCycleChoice is "Ja" then
set existingBelegeGroup to my findChildByName(belegeRootRecord, "Belege")
if existingBelegeGroup is missing value then
tell application id "DNtp"
set belageGroup to create record with {name:"Belege", type:group} in belegeRootRecord
set belegeRootUUID to uuid of belageGroup as rich text
end tell
if allComplete then
-- Alles vorhanden: keine Frage nötig. Der Zyklus läuft trotzdem
-- (still), damit die Loggruppe mit dem gewählten Namen existiert.
set yearCycleChoice to "Ja"
else if currentYearStatus is "missing" then
set yearCycleChoice to button returned of (display dialog "Soll ein Ordner Belege mit Jahresordner und Monatszyklen angelegt werden?" buttons {"Nein", "Ja"} default button "Ja" with title "Belegversand " & appVersion & " – Einrichtung")
else
set yearCycleChoice to button returned of (display dialog "Jahresordner " & currentYear & " ist bereits vorhanden." & return & return & ¬
"Vorhandene Monatsordner bleiben unverändert." & return & ¬
"Fehlende Monatsordner werden ergänzt." buttons {"Überspringen", "Ergänzen"} default button "Ergänzen" with title "Belegversand " & appVersion & " – Einrichtung")
if yearCycleChoice is "Ergänzen" then
set yearCycleChoice to "Ja"
else
tell application id "DNtp"
set belegeRootUUID to uuid of existingBelegeGroup as rich text
end tell
end if
set currentYear to my getCurrentYear()
tell application id "DNtp"
set belageGroup to my findChildByName(belegeRootRecord, "Belege")
end tell
my createYearCycleInGroup(belageGroup, currentYear)
if my isNovemberOrDecember() then
set nextYear to (currentYear as integer) + 1
my createYearCycleInGroup(belageGroup, (nextYear as text))
set yearCycleChoice to "Nein"
end if
end if
set dbRootRecord to my getTopParentGroup(belegeRootRecord)
tell application id "DNtp"
set dbRootName to name of dbRootRecord as rich text
end tell
-- ─────────────────────────────────────────────
-- Benutzer-Einstellungen abfragen
-- ─────────────────────────────────────────────
set mailToDefault to text returned of (display dialog "Standard-Empfängeradresse:" default answer defaultMailTo)
set mailCcToDefault to text returned of (display dialog "Standard-CC-Adresse (optional):" default answer "")
set subjectPrefix to text returned of (display dialog "Standard-Betreff-Präfix:" default answer defaultSubjectPrefix)
set zipPasswordDefault to text returned of (display dialog "Standard-ZIP-Passwort (optional):" default answer defaultZipPassword with hidden answer)
set zipChoice to button returned of (display dialog "Wie sollen die Belege verschickt werden?" & return & return & ¬
"ZIP-Archiv: alle Belege in einem (optional passwortgeschützten) ZIP." & return & return & ¬
"Einzeldateien: jeder Beleg als eigener Anhang – z.B. für DATEV." & return & return & ¬
"(Später jederzeit in der belegversand.conf über ZIP_ARCHIVE änderbar.)" buttons {"Einzeldateien", "ZIP-Archiv"} default button "ZIP-Archiv")
if zipChoice is "ZIP-Archiv" then
set zipArchiveValue to "true"
set zipPasswordDefault to text returned of (display dialog "Standard-ZIP-Passwort (optional):" default answer defaultZipPassword with hidden answer)
else
set zipArchiveValue to "false"
set zipPasswordDefault to ""
end if
set logSentGroupName to text returned of (display dialog "Name der Versand-Loggruppe:" default answer defaultLogSentGroupName)
set dbgChoice to button returned of (display dialog "Debug-Logging standardmäßig aktivieren?" buttons {"Nein", "Ja"} default button "Nein")
@@ -529,13 +615,46 @@ on run
set mailBodyRecordName to defaultMailBodyRecordName
set sentTagForDocs to defaultSentTagForDocs
set dryRunPreviewPath to defaultDryRunPreviewPath
set maxMailSizeMB to defaultMaxMailSizeMB
set supportedFileTypes to defaultSupportedFileTypes
-- ─────────────────────────────────────────────
-- Jahres-/Monatsstruktur (erst jetzt, damit der
-- gewählte Loggruppen-Name verwendet werden kann)
-- ─────────────────────────────────────────────
if yearCycleChoice is "Ja" then
-- Heißt die gewählte Gruppe schon "Belege", direkt verwenden –
-- sonst entstünde Belege/Belege.
if belegeRootName is "Belege" then
set belegeGroup to belegeRootRecord
else
set belegeGroup to my getOrCreateChildGroup(belegeRootRecord, "Belege")
end if
tell application id "DNtp"
set belegeRootUUID to uuid of belegeGroup as rich text
set belegeRootName to name of belegeGroup as rich text
end tell
set currentYear to my getCurrentYear()
my createYearCycleInGroup(belegeGroup, currentYear, logSentGroupName)
if my isNovemberOrDecember() then
set nextYear to (currentYear as integer) + 1
my createYearCycleInGroup(belegeGroup, (nextYear as text), logSentGroupName)
end if
end if
-- ─────────────────────────────────────────────
-- _config-Struktur anlegen und Dateien schreiben
-- ─────────────────────────────────────────────
set configGroupRecord to my getOrCreateChildGroup(dbRootRecord, configGroupName)
set readmeRecord to my getOrCreateMarkdownRecord(configGroupRecord, readmeRecordName, my buildReadmeText())
set mailBodyFolderRecord to my getOrCreateChildGroup(configGroupRecord, mailBodyFolderName)
set mailBodyRecord to my getOrCreateTextRecord(mailBodyFolderRecord, mailBodyRecordName, my buildDefaultMailBodyText())
set outsiderLogGroupRecord to my getOrCreateChildGroup(dbRootRecord, "Versendet_Outsider")
set originalsGroupRecord to my getOrCreateChildGroup(dbRootRecord, originalsGroupName)
tell application id "DNtp"
set readmeUUID to uuid of readmeRecord as rich text
@@ -543,7 +662,7 @@ on run
end tell
set configRecord to my getOrCreateTextRecord(configGroupRecord, configRecordName, "")
set configText to my buildConfigText(mailToDefault, mailCcToDefault, subjectPrefix, zipPasswordDefault, logSentGroupName, belegeRootUUID, writeDebugLogValue, showReadmeValue, readmeUUID, mailBodyFolderName, mailBodyRecordName, sentTagForDocs, dryRunPreviewPath)
set configText to my buildConfigText(mailToDefault, mailCcToDefault, subjectPrefix, zipArchiveValue, zipPasswordDefault, maxMailSizeMB, supportedFileTypes, logSentGroupName, belegeRootUUID, writeDebugLogValue, showReadmeValue, readmeUUID, mailBodyFolderName, mailBodyRecordName, sentTagForDocs, dryRunPreviewPath)
tell application id "DNtp"
try
@@ -576,19 +695,19 @@ on run
set debugInfoText to ""
end if
if writeDebugLogValue is "true" then
set debugInfoText to return & return & "Debug-Log: /tmp/DT-Belegversand-debug.log"
if zipArchiveValue is "true" then
set modeInfoText to "ZIP-Archiv"
else
set debugInfoText to ""
set modeInfoText to "Einzeldateien"
end if
-- Absolute Basis-Path für Script-Kompilierung
set basePath to (do shell script "echo ~") & basePath
display dialog "Belegversand wurde eingerichtet." & return & return & ¬
"Datenbank-Wurzel: " & dbRootName & return & ¬
"Belege-Gruppe: " & belegeRootName & return & ¬
"BELEGE_ROOT_UUID: " & belegeRootUUID & return & return & ¬
"Versandmodus: " & modeInfoText & return & ¬
"Max. Mailgröße: " & maxMailSizeMB & " MB" & return & ¬
"Erlaubte Dateitypen: " & supportedFileTypes & return & return & ¬
"Config-Gruppe: " & configGroupName & return & ¬
"CONFIG_GROUP_UUID: " & configGroupUUID & return & ¬
"Config-Datei: " & configRecordName & return & ¬
@@ -600,7 +719,18 @@ on run
"Mailbody-Datei: " & mailBodyRecordName & return & ¬
"MAILBODY_UUID: " & mailBodyUUID & return & return & ¬
"Globale Log-Gruppe (Outsider): Versendet_Outsider" & return & ¬
"OUTSIDER_LOG_UUID: " & outsiderLogGroupUUID & debugInfoText buttons {"OK"} default button "OK"
"OUTSIDER_LOG_UUID: " & outsiderLogGroupUUID & return & return & ¬
"Gruppe für Original-Fotos: " & originalsGroupName & debugInfoText buttons {"OK"} default button "OK"
-- ─────────────────────────────────────────────
-- Empfehlung: Smart Rule für Fotos → PDF
-- (lässt sich per AppleScript nicht anlegen)
-- ─────────────────────────────────────────────
display dialog "Empfehlung: Fotos automatisch in PDF umwandeln" & return & return & ¬
"Versendet werden nur PDF- und TIFF-Dateien. Damit Fotos von Quittungen (JPG, HEIC, PNG) gar nicht erst stören, kann DEVONthink sie beim Import automatisch umwandeln." & return & return & ¬
"Diese Regel lässt sich nicht per Script anlegen – bitte einmalig selbst einrichten:" & return & return & my buildSmartRuleSteps(belegeRootName) & return & ¬
"Tipp: Mit einem einzelnen Test-Foto prüfen, ob danach das PDF bei den Belegen und das Foto in „" & originalsGroupName & "“ liegt." & return & return & ¬
"Diese Anleitung steht auch im README (_config/README-Belegversand)." buttons {"OK"} default button "OK" with title "Belegversand " & appVersion & " – Empfehlung"
end timeout
end run