Complete Permissions for Groups, Membership Fees, and User Role Assignment closes #404 #405
7 changed files with 96 additions and 54 deletions
|
|
@ -4,7 +4,7 @@
|
||||||
**Feature:** Groups Management
|
**Feature:** Groups Management
|
||||||
**Version:** 1.0
|
**Version:** 1.0
|
||||||
**Last Updated:** 2025-01-XX
|
**Last Updated:** 2025-01-XX
|
||||||
**Status:** Architecture Design - Ready for Implementation
|
**Status:** ✅ Implemented (authorization: see [roles-and-permissions-architecture.md](./roles-and-permissions-architecture.md))
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -412,12 +412,14 @@ lib/
|
||||||
|
|
||||||
## Authorization
|
## Authorization
|
||||||
|
|
||||||
|
**Status:** ✅ Implemented. Group and MemberGroup resource policies and PermissionSets are in place. See [roles-and-permissions-architecture.md](./roles-and-permissions-architecture.md) for the full permission matrix and policy patterns.
|
||||||
|
|
||||||
### Permission Model (MVP)
|
### Permission Model (MVP)
|
||||||
|
|
||||||
**Resource:** `groups`
|
**Resource:** `Group` (and `MemberGroup`)
|
||||||
|
|
||||||
**Actions:**
|
**Actions:**
|
||||||
- `read` - View groups (all users with member read permission)
|
- `read` - View groups (all permission sets)
|
||||||
- `create` - Create groups (admin only)
|
- `create` - Create groups (admin only)
|
||||||
- `update` - Edit groups (admin only)
|
- `update` - Edit groups (admin only)
|
||||||
- `destroy` - Delete groups (admin only)
|
- `destroy` - Delete groups (admin only)
|
||||||
|
|
|
||||||
|
|
@ -334,20 +334,18 @@ lib/
|
||||||
|
|
||||||
### Permission System Integration
|
### Permission System Integration
|
||||||
|
|
||||||
**See:** [roles-and-permissions-architecture.md](./roles-and-permissions-architecture.md)
|
**Status:** ✅ Implemented. See [roles-and-permissions-architecture.md](./roles-and-permissions-architecture.md) for the full permission matrix and policy patterns.
|
||||||
|
|
||||||
**Required Permissions:**
|
**PermissionSets (lib/mv/authorization/permission_sets.ex):**
|
||||||
|
|
||||||
- `MembershipFeeType.create/update/destroy` - Admin only
|
- **MembershipFeeType:** All permission sets can read (:all); only admin has create/update/destroy (:all).
|
||||||
- `MembershipFeeType.read` - Admin, Treasurer, Board
|
- **MembershipFeeCycle:** All can read (:all); read_only has read only; normal_user and admin have read + create + update + destroy (:all).
|
||||||
- `MembershipFeeCycle.update` (status changes) - Admin, Treasurer
|
- **Manual "Regenerate Cycles" (UI):** The "Regenerate Cycles" button in the member detail view is shown to users who have MembershipFeeCycle create permission (normal_user and admin). Regeneration runs with system actor; UI access is gated by `can_create_cycle`.
|
||||||
- `MembershipFeeCycle.read` - Admin, Treasurer, Board, Own member
|
|
||||||
|
|
||||||
**Policy Patterns:**
|
**Resource Policies:**
|
||||||
|
|
||||||
- Use existing HasPermission check
|
- **MembershipFeeType** (`lib/membership_fees/membership_fee_type.ex`): `authorizers: [Ash.Policy.Authorizer]`, single policy with `HasPermission` for read/create/update/destroy.
|
||||||
- Leverage existing roles (Admin, Kassenwart)
|
- **MembershipFeeCycle** (`lib/membership_fees/membership_fee_cycle.ex`): Same pattern; update includes mark_as_paid, mark_as_suspended, mark_as_unpaid.
|
||||||
- Member can read own cycles (linked via member_id)
|
|
||||||
|
|
||||||
### LiveView Integration
|
### LiveView Integration
|
||||||
|
|
||||||
|
|
@ -357,7 +355,7 @@ lib/
|
||||||
2. MembershipFeeCycle table component (member detail view)
|
2. MembershipFeeCycle table component (member detail view)
|
||||||
- Implemented as `MvWeb.MemberLive.Show.MembershipFeesComponent`
|
- Implemented as `MvWeb.MemberLive.Show.MembershipFeesComponent`
|
||||||
- Displays all cycles in a table with status management
|
- Displays all cycles in a table with status management
|
||||||
- Allows changing cycle status, editing amounts, and regenerating cycles
|
- Allows changing cycle status, editing amounts, and manually regenerating cycles (normal_user and admin)
|
||||||
3. Settings form section (admin)
|
3. Settings form section (admin)
|
||||||
4. Member list column (membership fee status)
|
4. Member list column (membership fee status)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -958,7 +958,6 @@ msgid "Last name"
|
||||||
msgstr "Nachname"
|
msgstr "Nachname"
|
||||||
|
|
||||||
#: lib/mv_web/components/core_components.ex
|
#: lib/mv_web/components/core_components.ex
|
||||||
#: lib/mv_web/live/member_live/form.ex
|
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Keine"
|
msgstr "Keine"
|
||||||
|
|
@ -1670,6 +1669,7 @@ msgstr "Profil"
|
||||||
|
|
||||||
#: lib/mv_web/live/role_live/form.ex
|
#: lib/mv_web/live/role_live/form.ex
|
||||||
#: lib/mv_web/live/role_live/show.ex
|
#: lib/mv_web/live/role_live/show.ex
|
||||||
|
#: lib/mv_web/live/user_live/form.ex
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Role"
|
msgid "Role"
|
||||||
msgstr "Rolle"
|
msgstr "Rolle"
|
||||||
|
|
@ -1965,11 +1965,6 @@ msgstr "Bezahlstatus"
|
||||||
msgid "Reset"
|
msgid "Reset"
|
||||||
msgstr "Zurücksetzen"
|
msgstr "Zurücksetzen"
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "Only administrators can regenerate cycles"
|
|
||||||
msgstr "Nur Administrator*innen können Zyklen regenerieren"
|
|
||||||
|
|
||||||
#: lib/mv_web/live/global_settings_live.ex
|
#: lib/mv_web/live/global_settings_live.ex
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid " (Field: %{field})"
|
msgid " (Field: %{field})"
|
||||||
|
|
@ -2302,3 +2297,18 @@ msgstr "Unbekannte Spalte '%{header}' wird ignoriert. Falls dies ein Datenfeld i
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Only administrators or the linked user can change the email for members linked to users"
|
msgid "Only administrators or the linked user can change the email for members linked to users"
|
||||||
msgstr "Nur Administrator*innen oder die verknüpfte Benutzer*in können die E-Mail von Mitgliedern ändern, die mit Benutzer*innen verknüpft sind."
|
msgstr "Nur Administrator*innen oder die verknüpfte Benutzer*in können die E-Mail von Mitgliedern ändern, die mit Benutzer*innen verknüpft sind."
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Select role..."
|
||||||
|
msgstr "Keine auswählen"
|
||||||
|
|
||||||
|
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "You are not allowed to perform this action."
|
||||||
|
msgstr "Du hast keine Berechtigung, diese Aktion auszuführen."
|
||||||
|
|
||||||
|
#: lib/mv_web/live/member_live/form.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Select a membership fee type"
|
||||||
|
msgstr "Mitgliedsbeitragstyp auswählen"
|
||||||
|
|
|
||||||
|
|
@ -959,7 +959,6 @@ msgid "Last name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/core_components.ex
|
#: lib/mv_web/components/core_components.ex
|
||||||
#: lib/mv_web/live/member_live/form.ex
|
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1671,6 +1670,7 @@ msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/role_live/form.ex
|
#: lib/mv_web/live/role_live/form.ex
|
||||||
#: lib/mv_web/live/role_live/show.ex
|
#: lib/mv_web/live/role_live/show.ex
|
||||||
|
#: lib/mv_web/live/user_live/form.ex
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Role"
|
msgid "Role"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1966,11 +1966,6 @@ msgstr ""
|
||||||
msgid "Reset"
|
msgid "Reset"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "Only administrators can regenerate cycles"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/mv_web/live/global_settings_live.ex
|
#: lib/mv_web/live/global_settings_live.ex
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid " (Field: %{field})"
|
msgid " (Field: %{field})"
|
||||||
|
|
@ -2303,3 +2298,18 @@ msgstr ""
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Only administrators or the linked user can change the email for members linked to users"
|
msgid "Only administrators or the linked user can change the email for members linked to users"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Select role..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "You are not allowed to perform this action."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/member_live/form.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Select a membership fee type"
|
||||||
|
msgstr ""
|
||||||
|
|
|
||||||
|
|
@ -959,7 +959,6 @@ msgid "Last name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/core_components.ex
|
#: lib/mv_web/components/core_components.ex
|
||||||
#: lib/mv_web/live/member_live/form.ex
|
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1671,6 +1670,7 @@ msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/role_live/form.ex
|
#: lib/mv_web/live/role_live/form.ex
|
||||||
#: lib/mv_web/live/role_live/show.ex
|
#: lib/mv_web/live/role_live/show.ex
|
||||||
|
#: lib/mv_web/live/user_live/form.ex
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Role"
|
msgid "Role"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1966,11 +1966,6 @@ msgstr ""
|
||||||
msgid "Reset"
|
msgid "Reset"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "Only administrators can regenerate cycles"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/mv_web/live/global_settings_live.ex
|
#: lib/mv_web/live/global_settings_live.ex
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid " (Field: %{field})"
|
msgid " (Field: %{field})"
|
||||||
|
|
@ -2303,3 +2298,18 @@ msgstr "Unknown column '%{header}' will be ignored. If this is a custom field, c
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Only administrators or the linked user can change the email for members linked to users"
|
msgid "Only administrators or the linked user can change the email for members linked to users"
|
||||||
msgstr "Only administrators or the linked user can change the email for members linked to users"
|
msgstr "Only administrators or the linked user can change the email for members linked to users"
|
||||||
|
|
||||||
|
#: lib/mv_web/live/user_live/form.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Select role..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "You are not allowed to perform this action."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/member_live/form.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Select a membership fee type"
|
||||||
|
msgstr ""
|
||||||
|
|
|
||||||
|
|
@ -134,8 +134,8 @@ defmodule MvWeb.Helpers.MembershipFeeHelpersTest do
|
||||||
# Load cycles with membership_fee_type relationship
|
# Load cycles with membership_fee_type relationship
|
||||||
member =
|
member =
|
||||||
member
|
member
|
||||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
|> Ash.load!([membership_fee_cycles: [:membership_fee_type]], actor: actor)
|
||||||
|> Ash.load!(:membership_fee_type)
|
|> Ash.load!(:membership_fee_type, actor: actor)
|
||||||
|
|
||||||
# Use a fixed date in 2024 to ensure 2023 is last completed
|
# Use a fixed date in 2024 to ensure 2023 is last completed
|
||||||
today = ~D[2024-06-15]
|
today = ~D[2024-06-15]
|
||||||
|
|
@ -180,8 +180,8 @@ defmodule MvWeb.Helpers.MembershipFeeHelpersTest do
|
||||||
# Load cycles and fee type (will be empty)
|
# Load cycles and fee type (will be empty)
|
||||||
member =
|
member =
|
||||||
member
|
member
|
||||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
|> Ash.load!([membership_fee_cycles: [:membership_fee_type]], actor: actor)
|
||||||
|> Ash.load!(:membership_fee_type)
|
|> Ash.load!(:membership_fee_type, actor: actor)
|
||||||
|
|
||||||
last_cycle = MembershipFeeHelpers.get_last_completed_cycle(member, Date.utc_today())
|
last_cycle = MembershipFeeHelpers.get_last_completed_cycle(member, Date.utc_today())
|
||||||
assert last_cycle == nil
|
assert last_cycle == nil
|
||||||
|
|
@ -245,8 +245,8 @@ defmodule MvWeb.Helpers.MembershipFeeHelpersTest do
|
||||||
# Load cycles with membership_fee_type relationship
|
# Load cycles with membership_fee_type relationship
|
||||||
member =
|
member =
|
||||||
member
|
member
|
||||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
|> Ash.load!([membership_fee_cycles: [:membership_fee_type]], actor: actor)
|
||||||
|> Ash.load!(:membership_fee_type)
|
|> Ash.load!(:membership_fee_type, actor: actor)
|
||||||
|
|
||||||
result = MembershipFeeHelpers.get_current_cycle(member, today)
|
result = MembershipFeeHelpers.get_current_cycle(member, today)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -127,10 +127,12 @@ defmodule MvWeb.MemberLive.Index.MembershipFeeStatusTest do
|
||||||
create_cycle(member, fee_type, %{cycle_start: ~D[2023-01-01], status: :unpaid})
|
create_cycle(member, fee_type, %{cycle_start: ~D[2023-01-01], status: :unpaid})
|
||||||
|
|
||||||
# Load cycles with membership_fee_type relationship
|
# Load cycles with membership_fee_type relationship
|
||||||
|
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
||||||
|
|
||||||
member =
|
member =
|
||||||
member
|
member
|
||||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
|> Ash.load!([membership_fee_cycles: [:membership_fee_type]], actor: system_actor)
|
||||||
|> Ash.load!(:membership_fee_type)
|
|> Ash.load!(:membership_fee_type, actor: system_actor)
|
||||||
|
|
||||||
# Use fixed date in 2024 to ensure 2023 is last completed
|
# Use fixed date in 2024 to ensure 2023 is last completed
|
||||||
# We need to manually set the date for the helper function
|
# We need to manually set the date for the helper function
|
||||||
|
|
@ -183,8 +185,8 @@ defmodule MvWeb.MemberLive.Index.MembershipFeeStatusTest do
|
||||||
# Load cycles with membership_fee_type relationship
|
# Load cycles with membership_fee_type relationship
|
||||||
member =
|
member =
|
||||||
member
|
member
|
||||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
|> Ash.load!([membership_fee_cycles: [:membership_fee_type]], actor: system_actor)
|
||||||
|> Ash.load!(:membership_fee_type)
|
|> Ash.load!(:membership_fee_type, actor: system_actor)
|
||||||
|
|
||||||
status = MembershipFeeStatus.get_cycle_status_for_member(member, true)
|
status = MembershipFeeStatus.get_cycle_status_for_member(member, true)
|
||||||
|
|
||||||
|
|
@ -222,8 +224,8 @@ defmodule MvWeb.MemberLive.Index.MembershipFeeStatusTest do
|
||||||
# Load cycles and fee type first (will be empty)
|
# Load cycles and fee type first (will be empty)
|
||||||
member =
|
member =
|
||||||
member
|
member
|
||||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
|> Ash.load!([membership_fee_cycles: [:membership_fee_type]], actor: system_actor)
|
||||||
|> Ash.load!(:membership_fee_type)
|
|> Ash.load!(:membership_fee_type, actor: system_actor)
|
||||||
|
|
||||||
status = MembershipFeeStatus.get_cycle_status_for_member(member, false)
|
status = MembershipFeeStatus.get_cycle_status_for_member(member, false)
|
||||||
|
|
||||||
|
|
@ -273,12 +275,14 @@ defmodule MvWeb.MemberLive.Index.MembershipFeeStatusTest do
|
||||||
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||||
create_cycle(member2, fee_type, %{cycle_start: last_year_start, status: :unpaid})
|
create_cycle(member2, fee_type, %{cycle_start: last_year_start, status: :unpaid})
|
||||||
|
|
||||||
|
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
||||||
|
|
||||||
members =
|
members =
|
||||||
[member1, member2]
|
[member1, member2]
|
||||||
|> Enum.map(fn m ->
|
|> Enum.map(fn m ->
|
||||||
m
|
m
|
||||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
|> Ash.load!([membership_fee_cycles: [:membership_fee_type]], actor: system_actor)
|
||||||
|> Ash.load!(:membership_fee_type)
|
|> Ash.load!(:membership_fee_type, actor: system_actor)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
filtered = MembershipFeeStatus.filter_members_by_cycle_status(members, :paid, false)
|
filtered = MembershipFeeStatus.filter_members_by_cycle_status(members, :paid, false)
|
||||||
|
|
@ -300,12 +304,14 @@ defmodule MvWeb.MemberLive.Index.MembershipFeeStatusTest do
|
||||||
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||||
create_cycle(member2, fee_type, %{cycle_start: last_year_start, status: :unpaid})
|
create_cycle(member2, fee_type, %{cycle_start: last_year_start, status: :unpaid})
|
||||||
|
|
||||||
|
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
||||||
|
|
||||||
members =
|
members =
|
||||||
[member1, member2]
|
[member1, member2]
|
||||||
|> Enum.map(fn m ->
|
|> Enum.map(fn m ->
|
||||||
m
|
m
|
||||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
|> Ash.load!([membership_fee_cycles: [:membership_fee_type]], actor: system_actor)
|
||||||
|> Ash.load!(:membership_fee_type)
|
|> Ash.load!(:membership_fee_type, actor: system_actor)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
filtered = MembershipFeeStatus.filter_members_by_cycle_status(members, :unpaid, false)
|
filtered = MembershipFeeStatus.filter_members_by_cycle_status(members, :unpaid, false)
|
||||||
|
|
@ -327,12 +333,14 @@ defmodule MvWeb.MemberLive.Index.MembershipFeeStatusTest do
|
||||||
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||||
create_cycle(member2, fee_type, %{cycle_start: current_year_start, status: :unpaid})
|
create_cycle(member2, fee_type, %{cycle_start: current_year_start, status: :unpaid})
|
||||||
|
|
||||||
|
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
||||||
|
|
||||||
members =
|
members =
|
||||||
[member1, member2]
|
[member1, member2]
|
||||||
|> Enum.map(fn m ->
|
|> Enum.map(fn m ->
|
||||||
m
|
m
|
||||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
|> Ash.load!([membership_fee_cycles: [:membership_fee_type]], actor: system_actor)
|
||||||
|> Ash.load!(:membership_fee_type)
|
|> Ash.load!(:membership_fee_type, actor: system_actor)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
filtered = MembershipFeeStatus.filter_members_by_cycle_status(members, :paid, true)
|
filtered = MembershipFeeStatus.filter_members_by_cycle_status(members, :paid, true)
|
||||||
|
|
@ -354,12 +362,14 @@ defmodule MvWeb.MemberLive.Index.MembershipFeeStatusTest do
|
||||||
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||||
create_cycle(member2, fee_type, %{cycle_start: current_year_start, status: :unpaid})
|
create_cycle(member2, fee_type, %{cycle_start: current_year_start, status: :unpaid})
|
||||||
|
|
||||||
|
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
||||||
|
|
||||||
members =
|
members =
|
||||||
[member1, member2]
|
[member1, member2]
|
||||||
|> Enum.map(fn m ->
|
|> Enum.map(fn m ->
|
||||||
m
|
m
|
||||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
|> Ash.load!([membership_fee_cycles: [:membership_fee_type]], actor: system_actor)
|
||||||
|> Ash.load!(:membership_fee_type)
|
|> Ash.load!(:membership_fee_type, actor: system_actor)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
filtered = MembershipFeeStatus.filter_members_by_cycle_status(members, :unpaid, true)
|
filtered = MembershipFeeStatus.filter_members_by_cycle_status(members, :unpaid, true)
|
||||||
|
|
@ -373,12 +383,14 @@ defmodule MvWeb.MemberLive.Index.MembershipFeeStatusTest do
|
||||||
member1 = create_member(%{membership_fee_type_id: fee_type.id})
|
member1 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||||
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
member2 = create_member(%{membership_fee_type_id: fee_type.id})
|
||||||
|
|
||||||
|
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
||||||
|
|
||||||
members =
|
members =
|
||||||
[member1, member2]
|
[member1, member2]
|
||||||
|> Enum.map(fn m ->
|
|> Enum.map(fn m ->
|
||||||
m
|
m
|
||||||
|> Ash.load!(membership_fee_cycles: [:membership_fee_type])
|
|> Ash.load!([membership_fee_cycles: [:membership_fee_type]], actor: system_actor)
|
||||||
|> Ash.load!(:membership_fee_type)
|
|> Ash.load!(:membership_fee_type, actor: system_actor)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
# filter_unpaid_members should still work for backwards compatibility
|
# filter_unpaid_members should still work for backwards compatibility
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue