"""Prorating helpers for first-period and last-period depreciation. When an asset starts mid-month, the first period charges only a fraction of the full period_amount. Three conventions: - 'full_month': always charge full month (no proration) - 'days_365': pro-rate by actual days / 365 - 'days_period': pro-rate by actual days in period / total days in period """ from datetime import date from typing import Literal ProrateConvention = Literal['full_month', 'days_365', 'days_period'] def prorate_factor(*, period_start: date, period_end: date, asset_start: date, convention: ProrateConvention = 'days_period') -> float: """Return a 0..1 factor for how much of `period`'s depreciation applies to an asset that started on `asset_start`.""" if convention == 'full_month': return 1.0 if asset_start <= period_start: return 1.0 if asset_start > period_end: return 0.0 actual_days = (period_end - asset_start).days + 1 if convention == 'days_365': return actual_days / 365.0 if convention == 'days_period': period_days = (period_end - period_start).days + 1 return actual_days / period_days raise ValueError(f"Unknown convention: {convention}")