fix: honour a stated rate whatever the calendar says
Pay-now on a period due next week offered "Rate on the payday" and then found a rate anyway, with only a passive hint to explain why. Two separate problems behind that. The real one: `resolve_price` tested `payday >= today` before it tested the mode, so `manual` was silently ignored for any period not already back-dated. "Pay at the rate we agreed" quietly did not, and a contract pegged to a fixed rate honoured it only on late periods. A stated rate is an instruction rather than a lookup, so it now wins outright and applies to every period. `payday` and `current` keep their old order — for a payday today or ahead there is no history to consult, so `payday` collapses into `current`, which is the only defensible answer for a date that has not happened. The cosmetic one: the dialog's hint said "ignored unless the payday is already in the past", sitting beside a control that plainly appeared to do something — and was about to become wrong anyway, since manual now always applies. It is replaced by a line that names the actual period: either "Payday 2026-09-05 has not passed, so there is no historical rate to look up — this will be priced at the current rate", or "Will convert at what BTC was worth on <date>". The dialog header now shows which payday is being settled, which was not visible at all before. The contract dialogs lose the same stale hint; their label becomes "Pricing" rather than "Price a late payday at", which no longer describes manual mode. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018jy52j9GRZ6XKa1Zt21LLj
This commit is contained in:
parent
3b14db3dff
commit
1584eb337f
5 changed files with 94 additions and 19 deletions
|
|
@ -168,3 +168,37 @@ def test_memo_of_a_sat_contract_has_no_rate():
|
|||
|
||||
def test_memo_without_a_rate_still_states_the_fiat_amount():
|
||||
assert services.payout_memo(eur(label="x"), PAST) == "x — 2026-05-15 · 800 EUR"
|
||||
|
||||
|
||||
# --- an explicit rate is an instruction, not a lookup ----------------------
|
||||
|
||||
|
||||
def test_manual_applies_to_a_payday_today(historical):
|
||||
""" "Pay at the rate we agreed" is as meaningful for a payday now as for
|
||||
one last month — the calendar must not quietly override it."""
|
||||
p = price(eur(pricing_mode=PricingMode.manual, manual_rate=100_000), payday=TODAY)
|
||||
assert (p.source, p.rate) == ("manual", 100_000)
|
||||
assert p.amount == 800_000
|
||||
|
||||
|
||||
def test_manual_applies_to_a_future_payday(historical):
|
||||
p = price(
|
||||
eur(pricing_mode=PricingMode.manual, manual_rate=100_000),
|
||||
payday=date(2026, 12, 1),
|
||||
)
|
||||
assert p.source == "manual"
|
||||
|
||||
|
||||
def test_manual_override_beats_a_future_payday(historical):
|
||||
"""Paying next week's period early, at a stated rate."""
|
||||
p = price(
|
||||
eur(), payday=date(2026, 12, 1), mode=PricingMode.manual, manual_rate=50_000
|
||||
)
|
||||
assert (p.source, p.rate) == ("manual", 50_000)
|
||||
|
||||
|
||||
def test_payday_mode_on_a_future_payday_falls_to_the_live_rate(historical):
|
||||
"""There is no historical rate for a date that has not happened."""
|
||||
p = price(eur(pricing_mode=PricingMode.payday), payday=date(2026, 12, 1))
|
||||
assert p.source == "current"
|
||||
assert historical == []
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue