Commit Graph
49 Commits
Author SHA1 Message Date
Marcel PeterkauandClaude Opus 5 f80b17c443 Keep dunning a bounced debit out of the direct-debit track
Once the direct debit bounced and the board sent the Rücklastschrift reminder,
the claim is expected as a transfer by the deadline that letter states. Three
places still treated it as a claim the mandate covers, and the housekeeper's was
the one the board kept running into: after the reminder's deadline lapsed, the
finding went back to "Lastschrift überfällig -- Einzug prüfen, eine postalische
Mahnung ist hier nicht vorgesehen", for a claim that had just been dunned.

The rule now asks whether the claim was dunned before treating it as one for the
direct debit. If it was, it continues in the ordinary dunning sequence: the
running deadline shows as the usual "Frist läuft noch" note, and once that has
passed the next dunning level comes due. The SEPA-specific pending-reminder
detour that used to cover the deadline window is gone with it -- the ordinary
path reports the same thing.

The SEPA run now skips a dunned claim as well, instead of quietly collecting the
money the letter asked the member to transfer (which can bounce a second time,
with a second fee). The skip is reported like the incomplete mandates are, so
nothing disappears from the run without saying why; the dialog's wording is no
longer specific to mandates.

And a dunning mail asks for a transfer even from a member with an active
mandate. The shipped template spells the bank details out, but the ready-made
{{payment.instructions}} paragraph, offered by the template editor for exactly
this mail, told them "wir ziehen den Betrag ein, du musst nichts weiter tun" --
in the letter demanding payment.

Reverting the sent reminder is what puts the claim back into the direct-debit
run; the read of "dunned" is a sent reminder, not a draft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 00:16:26 +02:00
Marcel PeterkauandClaude Opus 5 31c1646571 Tell members which reference to put on a transfer
A data-review mail that lists the payment frequency but not how to pay leaves the
board matching anonymous transfers by hand. The mail now closes with the
reference to quote -- member number and full name, joined only where both exist
so a missing half cannot leave a dangling dash. Both are offered because either
identifies the payment on its own: a member who has forgotten their number falls
back on the name, and two members sharing a name are told apart by the number.

The note about the shortened IBAN moved out of the fixed template text into
{{data.iban_hint}}, filled only for members whose bank details are actually
listed -- it used to explain a masked IBAN to members who pay by transfer and see
no IBAN at all. It sits directly under the record as a parenthesised footnote,
which also keeps the dropped line from leaving a blank one behind.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:08:40 +02:00
Marcel PeterkauandClaude Opus 5 9e9bb7d668 Ask every member to check the data the club stores about them
The club has to keep its member data current, and until now that meant writing
to each member by hand. "Datenüberprüfung anfragen" in the members tab sends one
mail per member, each listing that member's own record: number, name, nickname,
birth date, contact data, address, status, member since, payment frequency, and
the bank details only for members who have any.

Two decisions the record itself forced:

A field with no value is printed as "(nicht hinterlegt)" rather than left out.
The point of the mail is to have gaps filled in, and a missing line is a gap
nobody sees.

The IBAN is masked down to its country code and last four digits. That is enough
to recognise the account, and it keeps a full account number out of a mail the
club sends to dozens of people at once.

Every member is listed as a recipient, with the live memberships that have an
address preselected -- a member who resigned at year's end may still need to
confirm their address, so the board can add them by hand. Members without an
address are skipped and reported instead of failing the run.

Delivery reuses the existing mail machinery: the configured delivery mode, one
SMTP/IMAP connection for the whole run, an archive copy in the member file, a
"data_review_email_sent" event, and the read-only guard before anything is
rendered. A member whose mail fails is reported as a warning and the run
continues -- one bad address must not stop a mailing to the whole club halfway
through. Because the run cannot be taken back, the recipient count is confirmed
once more before it starts.

Subject and text come from a new "Datenüberprüfung" template, editable like the
others, with {{data.sheet}} for the whole record and a {{#data}} block for a
layout of the board's own.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:05:38 +02:00
Marcel PeterkauandClaude Opus 5 ae53c168fd 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>
2026-08-28 21:26:40 +02:00
Marcel PeterkauandClaude Opus 5 be042949a2 Keep CCMA usable when the member store is mounted read-only
The encrypted volume holding the member data can be mounted without write
access, but starting against such a store failed: the housekeeper takes a lock
file before doing anything, so its startup pass died with a PermissionError and
took the whole start with it.

The store is now probed with an actual write once at startup -- permissions,
mount options and filesystem state all matter, and only an attempt covers them
together -- and a read-only store opens as a read-only session. The housekeeper
is skipped rather than attempted, every write inside the repository goes through
one guard that reports ReadOnlyStoreError (a RepositoryError, so the dialogs
already handle it) instead of letting an OS error surface, and the services that
archive into the member file check before they start sending or rendering.

The session says so permanently: a warning banner above the tabs, "NUR LESEN" in
the window title and status bar, and refused actions explaining why. Program
settings still save -- they live in the user's config directory -- while the
store-backed ones are skipped with a notice. "Erneut prüfen" picks up a volume
that was remounted writable without restarting.

A store that was never initialized still fails, but says that creating one needs
write access.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 21:10:31 +02:00
Marcel PeterkauandClaude Opus 5 aa0c16347b Send new members a welcome mail that doubles as their first invoice
Accepting a member left the board writing the "welcome, you are a member from
the 1st, and this is what it costs" mail by hand. The member file now offers it
directly: it greets the member, names the membership number and the start of the
membership, and lists every claim that is still open -- admission fee and first
contribution -- with a payment hint that adapts to whether a direct debit
mandate is active.

"Mitglied seit" rejects future dates, so a member accepted this month cannot
carry their actual start date yet; {{membership.start_date}} therefore falls
back to the 1st of the month following the acceptance decision. Individual
claims can be deselected before sending, the finished mail can be previewed,
and the result is archived in the member file like every other generated mail.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 20:49:08 +02:00
Marcel PeterkauandClaude Opus 5 d6cd58a788 Render every outgoing e-mail from an editable text template
The wording of the dunning and SEPA pre-notification mails was hard-coded in
Python, so adjusting a single sentence required a new release. Both texts now
live in plain text templates that ship as 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 and a deleted
one is restored from the shipped default.

A template carries its subject in the first line and the body after a blank
line. Placeholders use the same {{ ... }} syntax as the document templates and
share their member/organization values, so a name means the same thing in a
letter and in the mail that carries it. Unknown placeholders are rejected while
editing instead of during a send run, a line holding nothing but placeholders
that render empty is dropped, and {{#claims}} ... {{/claims}} repeats per entry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 20:49:08 +02:00
Marcel PeterkauandClaude Sonnet 5 c68e8b7d6a Document the configurable e-mail delivery and Sent-folder copy features
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 04:34:34 +02:00
Marcel PeterkauandClaude Sonnet 5 2ce764b007 Document the SEPA export multi-select feature
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 03:51:52 +02:00
Marcel PeterkauandClaude Sonnet 5 d87a57775e Document the SEPA overdue-during-active-Mahnung fix
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 03:45:49 +02:00
Marcel PeterkauandClaude Sonnet 5 0641285681 Document the housekeeper overdue-severity and ended-member reminder fixes
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 03:32:07 +02:00
Marcel PeterkauandClaude Sonnet 5 4ecdf87d05 Document the multi-item/Rücklastschrift reminder feature and reminder editing
Catches up the changelog for the reminder items table, the configurable
Mahnungen policy in Options, and today's ability to edit reminders (incl.
undoing an already-sent one).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 03:13:23 +02:00
Marcel PeterkauandClaude Sonnet 5 46795fc110 Reword the single-member housekeeper changelog entry so the PR carries a real diff
A prior push mixup (feature/member-contribution-overrides' origin ref had
briefly advanced to include this branch's own "Document the single-member
housekeeper run feature" commit) meant that commit's changelog line already
rode along into dev through PR #17 -- without the actual feature code, which
only exists here. CI's PR gate expects CHANGELOG.json to differ from dev, but
the merged text was already byte-identical, so this branch's PR couldn't pass.
Rewording the entry (adding the actual "Mitgliedsakte" entry point) keeps it
accurate and gives this branch a real changelog diff again.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 03:12:44 +02:00
Marcel PeterkauandClaude Sonnet 5 c07bdff04e Document the single-member housekeeper run feature
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 00:58:10 +02:00
Marcel PeterkauandClaude Sonnet 5 1e29cc1e3d Document allocation prefill and membership fee override features
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 00:58:10 +02:00
Marcel PeterkauandClaude Sonnet 5 44228dd7dd Document the payment allocation amount prefill in the changelog
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 00:57:32 +02:00
Marcel PeterkauandClaude Sonnet 5 52904a29b4 Document the table/pane usability tuning and GnuCash import improvements
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 23:56:51 +02:00
Marcel PeterkauandClaude Sonnet 5 ad5aeb74b6 Document the housekeeper dunning/SEPA rule rework in the changelog
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 23:03:04 +02:00
Marcel PeterkauandClaude Sonnet 5 e7a18b5cde Document claim deletion, donations, and payment allocation in the changelog
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 23:02:18 +02:00
Marcel Peterkau 5bacc005f6 Merge branch 'dev' into feature/payment-frequency-per-member 2026-07-30 17:40:45 +00:00
Marcel Peterkau 7a0cdbc04e feat: add application date to members 2026-07-30 19:35:48 +02:00
Marcel Peterkau c3cdf71506 feat: add per-member payment frequencies 2026-07-30 19:17:26 +02:00
Marcel Peterkau 54cb413eff docs: add member numbering strategy to changelog 2026-07-30 19:08:11 +02:00
Marcel Peterkau f14011efdc docs: describe SEPA and reminder mail features 2026-07-30 18:51:57 +02:00
Marcel Peterkau 9942e7aa22 fix: improve member list defaults and highlighting 2026-07-24 18:14:49 +02:00
Marcel Peterkau dbae0ce29c docs: add upcoming 0.2.0 changelog 2026-07-22 23:15:21 +02:00
Marcel Peterkau 9944652dfb Refresh first release changelog 2026-06-27 10:41:06 +02:00
Marcel Peterkau efb45630df docs: simplify initial changelog 2026-06-21 22:54:55 +02:00
Marcel Peterkau 576220ccd5 refactor: remove template timestamp aliases 2026-06-21 22:44:09 +02:00
Marcel Peterkau 3c842f29a3 feat: add template creation timestamps 2026-06-21 22:41:53 +02:00
Marcel Peterkau c58072fe45 feat: repeat claim items in document tables 2026-06-21 22:33:24 +02:00
Marcel Peterkau 6c7bf63280 feat: add member address and SEPA data 2026-06-21 22:14:45 +02:00
Marcel Peterkau 0622a22794 feat: add OpenDocument PDF templates 2026-06-21 22:10:16 +02:00
Marcel Peterkau b34135b34a feat: unify claim activity view 2026-06-21 21:51:47 +02:00
Marcel Peterkau 2c89732228 fix: align splash progress fill 2026-06-21 21:44:38 +02:00
Marcel Peterkau e6200f4a02 feat: pace startup housekeeper runs 2026-06-21 21:42:38 +02:00
Marcel Peterkau fc042f6711 feat: style timed splash progress 2026-06-21 18:51:31 +02:00
Marcel Peterkau e1d2b87ca1 feat: configure minimum splash duration 2026-06-21 18:48:08 +02:00
Marcel Peterkau dadcdb8b4a feat: use branded splash background 2026-06-21 18:44:27 +02:00
Marcel Peterkau e6d2f77d1e feat: add staged reminder workflow 2026-06-21 18:40:54 +02:00
Marcel Peterkau e7962f77e1 refactor: localize UI labels and store filenames 2026-06-21 18:25:58 +02:00
Marcel Peterkau 80d4d5ef90 feat: add itemized claims and payments 2026-06-21 18:20:55 +02:00
Marcel Peterkau c717d6806b feat: allow deleting housekeeper tasks 2026-06-21 18:09:04 +02:00
Marcel Peterkau 3e9f347435 feat: show housekeeper task details 2026-06-21 17:59:49 +02:00
Marcel Peterkau 7596e47981 fix: preflight member records before rules 2026-06-21 17:54:09 +02:00
Marcel Peterkau 55bc3b666e fix: tolerate damaged contribution files 2026-06-21 17:50:56 +02:00
Marcel Peterkau 4bc1a8a200 feat: add scriptable housekeeper rule engine 2026-06-21 17:43:04 +02:00
Marcel Peterkau e63abbae81 fix: tolerate invalid member dates in views 2026-06-21 16:49:51 +02:00
Marcel Peterkau dfd5b1192b feat: initialize CCMA member administration 2026-06-21 16:46:15 +02:00