Merge branch 'dev' into feature/read-only-store

dev gained the editable mail templates, which live in the store like everything
else -- so they follow the same read-only rules: the options dialog skips saving
them, save_mail_template() reports the store instead of a raw PermissionError,
and a store that cannot keep its own copy simply renders from the shipped
default.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Marcel Peterkau
2026-08-28 21:26:40 +02:00
co-authored by Claude Opus 5
24 changed files with 2276 additions and 168 deletions
+24
View File
@@ -183,6 +183,30 @@ marker may share the last cell. CCMA removes both markers and clones the whole
row, including its formatting, once per item. With no items, the template row
is removed. A loop that is not closed in the same row is rejected.
## Mail templates
Every e-mail CCMA sends -- the welcome mail with its first invoice, dunning mails
and SEPA pre-notifications -- is rendered from a plain text template. The shipped
defaults are copied into the store's `templates/mail/` directory on first start
and can be edited there or under Optionen -> E-Mail-Vorlagen. An existing file is
never overwritten; a deleted one is restored from the shipped default.
A template holds the subject in its first line and the message body after a blank
line:
```
Betreff: {{reminder.name}} {{claim.title}}
Hallo {{member.first_name}},
...
```
Placeholders use the same `{{ ... }}` syntax as the document templates. Which ones
are available depends on the mail; the options dialog lists them per template and
rejects unknown ones when saving. A line that contains nothing but placeholders
which render empty (an optional hint, an empty list) is dropped, and
`{{#claims}} ... {{/claims}}` repeats its content once per claim.
## Read-only stores
The member store may be mounted read-only -- the encrypted volume holding the