Refactor filters to use cycle status instead of paid field
Replace paid_filter with cycle_status_filter that filters based on membership fee cycle status (last or current cycle). Update PaymentFilterComponent to use new filter with options All, Paid, Unpaid. Remove membership fee status filter dropdown. Extend filter_members_by_cycle_status/3 to support both paid and unpaid filtering. Update toggle_cycle_view to preserve filter state in URL.
This commit is contained in:
parent
098b3b0a2a
commit
c65b3808bf
10 changed files with 490 additions and 247 deletions
|
|
@ -235,4 +235,134 @@ defmodule MvWeb.MemberLive.Index.MembershipFeeStatusTest do
|
|||
assert result == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "filter_members_by_cycle_status/3" do
|
||||
test "filters paid members in last cycle" do
|
||||
fee_type = create_fee_type(%{interval: :yearly})
|
||||
today = Date.utc_today()
|
||||
last_year_start = Date.new!(today.year - 1, 1, 1)
|
||||
|
||||
# Member with paid last cycle
|
||||
member1 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||
create_cycle(member1, fee_type, %{cycle_start: last_year_start, status: :paid})
|
||||
|
||||
# Member with unpaid last cycle
|
||||
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||
create_cycle(member2, fee_type, %{cycle_start: last_year_start, status: :unpaid})
|
||||
|
||||
members =
|
||||
[member1, member2]
|
||||
|> Enum.map(fn m ->
|
||||
m
|
||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
||||
|> Ash.load!(:membership_fee_type)
|
||||
end)
|
||||
|
||||
filtered = MembershipFeeStatus.filter_members_by_cycle_status(members, :paid, false)
|
||||
|
||||
assert length(filtered) == 1
|
||||
assert List.first(filtered).id == member1.id
|
||||
end
|
||||
|
||||
test "filters unpaid members in last cycle" do
|
||||
fee_type = create_fee_type(%{interval: :yearly})
|
||||
today = Date.utc_today()
|
||||
last_year_start = Date.new!(today.year - 1, 1, 1)
|
||||
|
||||
# Member with paid last cycle
|
||||
member1 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||
create_cycle(member1, fee_type, %{cycle_start: last_year_start, status: :paid})
|
||||
|
||||
# Member with unpaid last cycle
|
||||
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||
create_cycle(member2, fee_type, %{cycle_start: last_year_start, status: :unpaid})
|
||||
|
||||
members =
|
||||
[member1, member2]
|
||||
|> Enum.map(fn m ->
|
||||
m
|
||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
||||
|> Ash.load!(:membership_fee_type)
|
||||
end)
|
||||
|
||||
filtered = MembershipFeeStatus.filter_members_by_cycle_status(members, :unpaid, false)
|
||||
|
||||
assert length(filtered) == 1
|
||||
assert List.first(filtered).id == member2.id
|
||||
end
|
||||
|
||||
test "filters paid members in current cycle" do
|
||||
fee_type = create_fee_type(%{interval: :yearly})
|
||||
today = Date.utc_today()
|
||||
current_year_start = Date.new!(today.year, 1, 1)
|
||||
|
||||
# Member with paid current cycle
|
||||
member1 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||
create_cycle(member1, fee_type, %{cycle_start: current_year_start, status: :paid})
|
||||
|
||||
# Member with unpaid current cycle
|
||||
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||
create_cycle(member2, fee_type, %{cycle_start: current_year_start, status: :unpaid})
|
||||
|
||||
members =
|
||||
[member1, member2]
|
||||
|> Enum.map(fn m ->
|
||||
m
|
||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
||||
|> Ash.load!(:membership_fee_type)
|
||||
end)
|
||||
|
||||
filtered = MembershipFeeStatus.filter_members_by_cycle_status(members, :paid, true)
|
||||
|
||||
assert length(filtered) == 1
|
||||
assert List.first(filtered).id == member1.id
|
||||
end
|
||||
|
||||
test "filters unpaid members in current cycle" do
|
||||
fee_type = create_fee_type(%{interval: :yearly})
|
||||
today = Date.utc_today()
|
||||
current_year_start = Date.new!(today.year, 1, 1)
|
||||
|
||||
# Member with paid current cycle
|
||||
member1 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||
create_cycle(member1, fee_type, %{cycle_start: current_year_start, status: :paid})
|
||||
|
||||
# Member with unpaid current cycle
|
||||
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||
create_cycle(member2, fee_type, %{cycle_start: current_year_start, status: :unpaid})
|
||||
|
||||
members =
|
||||
[member1, member2]
|
||||
|> Enum.map(fn m ->
|
||||
m
|
||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
||||
|> Ash.load!(:membership_fee_type)
|
||||
end)
|
||||
|
||||
filtered = MembershipFeeStatus.filter_members_by_cycle_status(members, :unpaid, true)
|
||||
|
||||
assert length(filtered) == 1
|
||||
assert List.first(filtered).id == member2.id
|
||||
end
|
||||
|
||||
test "returns all members when filter is nil" do
|
||||
fee_type = create_fee_type(%{interval: :yearly})
|
||||
member1 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||
|
||||
members =
|
||||
[member1, member2]
|
||||
|> Enum.map(fn m ->
|
||||
m
|
||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
||||
|> Ash.load!(:membership_fee_type)
|
||||
end)
|
||||
|
||||
# filter_unpaid_members should still work for backwards compatibility
|
||||
filtered = MembershipFeeStatus.filter_unpaid_members(members, false)
|
||||
|
||||
# Both members have no cycles, so both should be filtered out
|
||||
assert length(filtered) == 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue