From 8f6accd2c31699464a7ed3ad397c939a15ca2f3c Mon Sep 17 00:00:00 2001 From: Randy Olson Date: Tue, 13 Oct 2026 23:26:13 -0700 Subject: [PATCH] Correct sponsorship annual value docs for ended contracts The docs said an ended contract's annual value is zero, but ended contracts often keep a non-zero annual value. Describe annual_value as what a running contract pays a year and point readers at end to tell running contracts from ended ones. Refs #11. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 8 ++++++++ docs/guides/what-a-save-holds.md | 3 ++- src/fmsave/_save.py | 5 +++-- src/fmsave/models/finances.py | 9 ++++++--- tests/fixtures/career.py | 2 +- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de7c83d..67c043f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ This project follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Fixed + +- The `Sponsorship.annual_value` and `sponsorships()` docs no longer say an ended contract's annual value is zero. Ended contracts often keep a non-zero annual value, so filter on `end` to find running contracts. + +Refs #11. + ## [0.5.10] - 2026-10-10 ### Fixed diff --git a/docs/guides/what-a-save-holds.md b/docs/guides/what-a-save-holds.md index f58dd3c..e271ff1 100644 --- a/docs/guides/what-a-save-holds.md +++ b/docs/guides/what-a-save-holds.md @@ -25,7 +25,8 @@ only adaptability. `managed_clubs()` is the club you run, and is empty between jobs. `finances()` is monthly figures per club, in the save's own unit. `sponsorships()` includes historical contracts, so a row -does not necessarily describe current income. `stadiums()` holds capacities and ownership; +does not necessarily describe current income: an ended contract can keep a non-zero annual +value, so filter on `end` against the save's date. `stadiums()` holds capacities and ownership; names are available for only some grounds. Club data still has limits. The meaning of a zero corporate-facilities rating and some diff --git a/src/fmsave/_save.py b/src/fmsave/_save.py index c8f489c..dc4849a 100644 --- a/src/fmsave/_save.py +++ b/src/fmsave/_save.py @@ -1460,8 +1460,9 @@ def sponsorships(self) -> Table[Sponsorship]: The clubs are the ones `finances()` keeps a series for, in the same order, and each club's contracts keep the order the save stores them in. **The list keeps contracts that - have ended**, whose `annual_value` is zero, so a club's current sponsorship income is the - sum of `annual_value` over the rows whose `end` is after the save's date. + have ended**, and an ended contract's `annual_value` is often non-zero, so a club's + current sponsorship income is the sum of `annual_value` over the rows whose `end` is + after the save's date, not over every row. Every `type` code is UNKNOWN: the save groups its sponsorships into about twenty kinds and no displayed label has pinned one of those codes. Money is a whole number in the diff --git a/src/fmsave/models/finances.py b/src/fmsave/models/finances.py index 5743871..b87013e 100644 --- a/src/fmsave/models/finances.py +++ b/src/fmsave/models/finances.py @@ -92,9 +92,12 @@ class Sponsorship: kind: What kind of sponsorship it is; every code is UNKNOWN (unconfirmed). start: The day the contract starts. end: The day it ends. - total_value: The contract's whole value, which is the annual value times its whole - years on about 19 contracts in 20. - annual_value: What it pays a year; zero on a contract that has ended. + total_value: The contract's whole value. On most running contracts it is the annual + value times the contract's whole years. + annual_value: What a running contract pays a year. A contract that has ended can + still carry a non-zero annual value, often equal to its total value, so neither a + zero nor a non-zero value says whether the contract is still running; compare + `end` with the save's date for that. unknown: Numeric fields with no known meaning (unconfirmed). """ diff --git a/tests/fixtures/career.py b/tests/fixtures/career.py index dae02f4..d1c7563 100644 --- a/tests/fixtures/career.py +++ b/tests/fixtures/career.py @@ -235,7 +235,7 @@ class ExampleClub: ) FINANCE_MONTH_COUNT = len(FINANCE_MONTH_VALUES) -# Sponsor contracts. A is running, B ended two years before the clock and so carries no annual +# Sponsor contracts. A is running, B ended two years before the clock and carries no annual # value, and C is Example Athletic's one running contract. SPONSOR_A = { "sponsor_type": 4,