Compare commits
1 commit
cad8cac9a8
...
06324d77c5
| Author | SHA1 | Date | |
|---|---|---|---|
| 06324d77c5 |
6 changed files with 52 additions and 31 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue