payroll/tests
Padreug e77f431d47 fix: resuming an auto-paused contract no longer discards the backlog
Found by tracing what happens when a back-dated backfill contract cannot
fetch a historical rate. The failure handling itself was fine — period 0
fails, the backlog halts so nothing settles out of order, five ledger rows
record the reason, no money moves, and the contract auto-pauses once the
retry budget is spent. The recovery was not.

The operator fixes the cause (switches to a stated rate, or to current),
clicks Resume, and periods_done jumps 0 -> 6: every unpaid payday silently
written off, contract back to looking healthy, employee never paid. The
confirm dialog even asserted the missed paydays "are written off" — true of
one kind of pause and a lie about the other.

Two features colliding. "Do not backfill a deliberate pause" is right when
the operator paused: the pause *was* the decision not to pay. It is wrong
when payroll paused, because nobody decided anything — the money is still
owed and the operator has just removed whatever blocked it.

Contracts now carry `paused_reason`, set only when payroll pauses them and
cleared by a deliberate pause. Resume infers from it, and an explicit
`catch_up` still overrides either way. The console asks a different question
for each, quoting the reason, and flags a payroll-paused contract in the
table so the distinction is visible before anyone clicks.

Verified end to end: five failing ticks leave periods_done at 0 and pause
with "period 0 (2026-08-01) failed 5 times: no historical EUR rate
available for 2026-08-01"; resuming after switching to a manual rate keeps
the position at 0, and the next tick settles all seven owed periods.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018jy52j9GRZ6XKa1Zt21LLj
2026-08-31 23:02:45 +02:00
..
__init__.py feat: recurring payout scheduler 2026-08-31 13:45:40 +02:00
conftest.py feat: name the applied rate in the payout memo 2026-08-31 21:55:49 +02:00
test_export.py feat: CSV export and employee payslip view 2026-08-31 13:53:12 +02:00
test_lifecycle.py fix: resuming an auto-paused contract no longer discards the backlog 2026-08-31 23:02:45 +02:00
test_payout.py feat: price a back-dated period at the day it was due 2026-08-31 21:42:00 +02:00
test_pricing.py fix: honour a stated rate whatever the calendar says 2026-08-31 22:14:46 +02:00
test_rates.py feat: historical BTC rate lookup 2026-08-31 21:39:18 +02:00
test_schedule.py feat: schedule preview and off-cycle payouts 2026-08-31 13:51:20 +02:00