diff --git a/lib/membership/member.ex b/lib/membership/member.ex index 1fd2812..7f30833 100644 --- a/lib/membership/member.ex +++ b/lib/membership/member.ex @@ -647,10 +647,13 @@ defmodule Mv.Membership.Member do false end end) - |> Enum.sort_by(fn cycle -> - interval = Map.get(cycle, :membership_fee_type).interval - Mv.MembershipFees.CalendarCycles.calculate_cycle_end(cycle.cycle_start, interval) - end, {:desc, Date}) + |> Enum.sort_by( + fn cycle -> + interval = Map.get(cycle, :membership_fee_type).interval + Mv.MembershipFees.CalendarCycles.calculate_cycle_end(cycle.cycle_start, interval) + end, + {:desc, Date} + ) |> List.first() else nil diff --git a/lib/membership_fees/changes/validate_same_interval.ex b/lib/membership_fees/changes/validate_same_interval.ex index 0d067ce..7bfbeee 100644 --- a/lib/membership_fees/changes/validate_same_interval.ex +++ b/lib/membership_fees/changes/validate_same_interval.ex @@ -83,8 +83,7 @@ defmodule Mv.MembershipFees.Changes.ValidateSameInterval do defp get_intervals(current_type_id, new_type_id) do alias Mv.MembershipFees.MembershipFeeType - case {Ash.get(MembershipFeeType, current_type_id), - Ash.get(MembershipFeeType, new_type_id)} do + case {Ash.get(MembershipFeeType, current_type_id), Ash.get(MembershipFeeType, new_type_id)} do {{:ok, current_type}, {:ok, new_type}} -> {:ok, current_type.interval, new_type.interval} @@ -116,4 +115,3 @@ defmodule Mv.MembershipFees.Changes.ValidateSameInterval do defp format_interval(:yearly), do: "yearly" defp format_interval(interval), do: to_string(interval) end - diff --git a/lib/membership_fees/membership_fee_cycle.ex b/lib/membership_fees/membership_fee_cycle.ex index 6a101e9..b437ead 100644 --- a/lib/membership_fees/membership_fee_cycle.ex +++ b/lib/membership_fees/membership_fee_cycle.ex @@ -56,6 +56,7 @@ defmodule Mv.MembershipFees.MembershipFeeCycle do description "Mark cycle as paid" require_atomic? false accept [:notes] + change fn changeset, _context -> Ash.Changeset.force_change_attribute(changeset, :status, :paid) end @@ -65,6 +66,7 @@ defmodule Mv.MembershipFees.MembershipFeeCycle do description "Mark cycle as suspended" require_atomic? false accept [:notes] + change fn changeset, _context -> Ash.Changeset.force_change_attribute(changeset, :status, :suspended) end @@ -74,6 +76,7 @@ defmodule Mv.MembershipFees.MembershipFeeCycle do description "Mark cycle as unpaid (for error correction)" require_atomic? false accept [:notes] + change fn changeset, _context -> Ash.Changeset.force_change_attribute(changeset, :status, :unpaid) end diff --git a/test/membership/member_cycle_calculations_test.exs b/test/membership/member_cycle_calculations_test.exs index 8dcaeed..19b2a7f 100644 --- a/test/membership/member_cycle_calculations_test.exs +++ b/test/membership/member_cycle_calculations_test.exs @@ -118,6 +118,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do # Current cycle cycle_start = CalendarCycles.calculate_cycle_start(today, :yearly) + create_cycle(member, fee_type, %{ cycle_start: cycle_start, status: :paid @@ -179,6 +180,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do # Current cycle cycle_start = CalendarCycles.calculate_cycle_start(today, :yearly) + create_cycle(member, fee_type, %{ cycle_start: cycle_start, status: :unpaid @@ -186,8 +188,10 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do # Future cycle (if we're not at the end of the year) next_year = today.year + 1 + if today.month < 12 or today.day < 31 do next_year_start = Date.new!(next_year, 1, 1) + create_cycle(member, fee_type, %{ cycle_start: next_year_start, status: :unpaid @@ -265,6 +269,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do }) cycle_start = CalendarCycles.calculate_cycle_start(today, :yearly) + create_cycle(member, fee_type, %{ cycle_start: cycle_start, status: :unpaid @@ -279,4 +284,3 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do end end end - diff --git a/test/membership/member_type_change_integration_test.exs b/test/membership/member_type_change_integration_test.exs index 7b23cf8..8ea151c 100644 --- a/test/membership/member_type_change_integration_test.exs +++ b/test/membership/member_type_change_integration_test.exs @@ -116,11 +116,12 @@ defmodule Mv.Membership.MemberTypeChangeIntegrationTest do :ok end - _current_cycle = create_cycle(member, yearly_type1, %{ - cycle_start: current_cycle_start, - status: :unpaid, - amount: Decimal.new("100.00") - }) + _current_cycle = + create_cycle(member, yearly_type1, %{ + cycle_start: current_cycle_start, + status: :unpaid, + amount: Decimal.new("100.00") + }) # Change membership fee type (same interval, different amount) assert {:ok, _updated_member} = @@ -138,6 +139,7 @@ defmodule Mv.Membership.MemberTypeChangeIntegrationTest do MembershipFeeCycle |> Ash.Query.filter(member_id == ^member.id and cycle_start == ^past_cycle_start) |> Ash.read_one!() + assert past_cycle_after.status == :paid assert Decimal.equal?(past_cycle_after.amount, Decimal.new("100.00")) assert past_cycle_after.membership_fee_type_id == yearly_type1.id @@ -157,7 +159,10 @@ defmodule Mv.Membership.MemberTypeChangeIntegrationTest do # Verify old cycle with old type doesn't exist anymore old_current_cycles = MembershipFeeCycle - |> Ash.Query.filter(member_id == ^member.id and cycle_start == ^current_cycle_start and membership_fee_type_id == ^yearly_type1.id) + |> Ash.Query.filter( + member_id == ^member.id and cycle_start == ^current_cycle_start and + membership_fee_type_id == ^yearly_type1.id + ) |> Ash.read!() assert Enum.empty?(old_current_cycles) @@ -279,10 +284,12 @@ defmodule Mv.Membership.MemberTypeChangeIntegrationTest do Process.sleep(100) # Create cycles: one in the past (unpaid, ended), one current (unpaid, not ended) - past_cycle_start = CalendarCycles.calculate_cycle_start( - Date.add(today, -365), - :yearly - ) + past_cycle_start = + CalendarCycles.calculate_cycle_start( + Date.add(today, -365), + :yearly + ) + current_cycle_start = CalendarCycles.calculate_cycle_start(today, :yearly) # Past cycle (unpaid) - should remain unchanged (cycle_start < today) @@ -297,11 +304,12 @@ defmodule Mv.Membership.MemberTypeChangeIntegrationTest do :ok end - past_cycle = create_cycle(member, yearly_type1, %{ - cycle_start: past_cycle_start, - status: :unpaid, - amount: Decimal.new("100.00") - }) + past_cycle = + create_cycle(member, yearly_type1, %{ + cycle_start: past_cycle_start, + status: :unpaid, + amount: Decimal.new("100.00") + }) # Current cycle (unpaid) - should be regenerated (cycle_start >= today) # Delete existing cycle if it exists (from auto-generation) @@ -315,11 +323,12 @@ defmodule Mv.Membership.MemberTypeChangeIntegrationTest do :ok end - _current_cycle = create_cycle(member, yearly_type1, %{ - cycle_start: current_cycle_start, - status: :unpaid, - amount: Decimal.new("100.00") - }) + _current_cycle = + create_cycle(member, yearly_type1, %{ + cycle_start: current_cycle_start, + status: :unpaid, + amount: Decimal.new("100.00") + }) # Change membership fee type assert {:ok, _updated_member} = @@ -351,7 +360,10 @@ defmodule Mv.Membership.MemberTypeChangeIntegrationTest do # Verify old cycle with old type doesn't exist anymore old_current_cycles = MembershipFeeCycle - |> Ash.Query.filter(member_id == ^member.id and cycle_start == ^current_cycle_start and membership_fee_type_id == ^yearly_type1.id) + |> Ash.Query.filter( + member_id == ^member.id and cycle_start == ^current_cycle_start and + membership_fee_type_id == ^yearly_type1.id + ) |> Ash.read!() assert Enum.empty?(old_current_cycles) @@ -439,4 +451,3 @@ defmodule Mv.Membership.MemberTypeChangeIntegrationTest do end end end - diff --git a/test/membership_fees/changes/validate_same_interval_test.exs b/test/membership_fees/changes/validate_same_interval_test.exs index 7b7a433..af777fa 100644 --- a/test/membership_fees/changes/validate_same_interval_test.exs +++ b/test/membership_fees/changes/validate_same_interval_test.exs @@ -70,6 +70,7 @@ defmodule Mv.MembershipFees.Changes.ValidateSameIntervalTest do refute changeset.valid? assert %{errors: errors} = changeset + assert Enum.any?(errors, fn error -> error.field == :membership_fee_type_id and error.message =~ "yearly" and @@ -79,7 +80,8 @@ defmodule Mv.MembershipFees.Changes.ValidateSameIntervalTest do test "allows first assignment of membership fee type" do yearly_type = create_fee_type(%{interval: :yearly}) - member = create_member(%{}) # No fee type assigned + # No fee type assigned + member = create_member(%{}) changeset = member