From ecddf55331ecf370400dcbdcd2b6fa54cce3a6ea Mon Sep 17 00:00:00 2001 From: Moritz Date: Thu, 11 Dec 2025 20:21:20 +0100 Subject: [PATCH] docs: fix CalendarCycles documentation to match actual implementation --- lib/mv/membership_fees/calendar_cycles.ex | 64 ++++++++++++++++------- 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/lib/mv/membership_fees/calendar_cycles.ex b/lib/mv/membership_fees/calendar_cycles.ex index 5e25432..8a4ef24 100644 --- a/lib/mv/membership_fees/calendar_cycles.ex +++ b/lib/mv/membership_fees/calendar_cycles.ex @@ -50,14 +50,47 @@ defmodule Mv.MembershipFees.CalendarCycles do ## Parameters - - `date` - The date for which to find the cycle start (used as default if `reference_date` not provided) + - `date` - Ignored in this 3-argument version (kept for API consistency) - `interval` - The interval type (`:monthly`, `:quarterly`, `:half_yearly`, `:yearly`) - - `reference_date` - The reference date to use for calculation (defaults to `date`) + - `reference_date` - The date used to determine which cycle to calculate ## Returns The start date of the cycle containing the reference date. + ## Examples + + iex> Mv.MembershipFees.CalendarCycles.calculate_cycle_start(~D[2024-03-15], :monthly, ~D[2024-05-20]) + ~D[2024-05-01] + + iex> Mv.MembershipFees.CalendarCycles.calculate_cycle_start(~D[2024-03-15], :quarterly, ~D[2024-05-20]) + ~D[2024-04-01] + """ + @spec calculate_cycle_start(Date.t(), interval(), Date.t()) :: Date.t() + def calculate_cycle_start(_date, interval, reference_date) do + case interval do + :monthly -> monthly_cycle_start(reference_date) + :quarterly -> quarterly_cycle_start(reference_date) + :half_yearly -> half_yearly_cycle_start(reference_date) + :yearly -> yearly_cycle_start(reference_date) + end + end + + @doc """ + Calculates the start date of the cycle that contains the given date. + + This is a convenience function that calls `calculate_cycle_start/3` with `date` as both + the input and reference date. + + ## Parameters + + - `date` - The date used to determine which cycle to calculate + - `interval` - The interval type (`:monthly`, `:quarterly`, `:half_yearly`, `:yearly`) + + ## Returns + + The start date of the cycle containing the given date. + ## Examples iex> Mv.MembershipFees.CalendarCycles.calculate_cycle_start(~D[2024-03-15], :monthly) @@ -71,20 +104,7 @@ defmodule Mv.MembershipFees.CalendarCycles do iex> Mv.MembershipFees.CalendarCycles.calculate_cycle_start(~D[2024-12-15], :yearly) ~D[2024-01-01] - - iex> Mv.MembershipFees.CalendarCycles.calculate_cycle_start(~D[2024-03-15], :monthly, ~D[2024-05-20]) - ~D[2024-05-01] """ - @spec calculate_cycle_start(Date.t(), interval(), Date.t()) :: Date.t() - def calculate_cycle_start(_date, interval, reference_date) do - case interval do - :monthly -> monthly_cycle_start(reference_date) - :quarterly -> quarterly_cycle_start(reference_date) - :half_yearly -> half_yearly_cycle_start(reference_date) - :yearly -> yearly_cycle_start(reference_date) - end - end - @spec calculate_cycle_start(Date.t(), interval()) :: Date.t() def calculate_cycle_start(date, interval) do calculate_cycle_start(date, interval, date) @@ -203,7 +223,13 @@ defmodule Mv.MembershipFees.CalendarCycles do end @doc """ - Checks if the cycle was just completed (ended before or on the given date, but is the most recent completed cycle). + Checks if the cycle is the last completed cycle. + + A cycle is considered the last completed cycle if: + - The cycle has ended (cycle_end < today) + - The next cycle has not ended yet (today <= next_end) + + In other words: `cycle_end < today <= next_end` ## Parameters @@ -213,7 +239,7 @@ defmodule Mv.MembershipFees.CalendarCycles do ## Returns - `true` if the cycle ended before or on the given date and is the last completed cycle, `false` otherwise. + `true` if the cycle is the last completed cycle, `false` otherwise. ## Examples @@ -230,11 +256,11 @@ defmodule Mv.MembershipFees.CalendarCycles do def last_completed_cycle?(cycle_start, interval, today) do cycle_end = calculate_cycle_end(cycle_start, interval) - # Cycle must have ended (before or on the given date) + # Cycle must have ended (cycle_end < today) case Date.compare(today, cycle_end) do :gt -> # Check if this is the most recent completed cycle - # by verifying that the next cycle hasn't ended yet + # by verifying that the next cycle hasn't ended yet (today <= next_end) next_start = next_cycle_start(cycle_start, interval) next_end = calculate_cycle_end(next_start, interval)