Integrate Member policies in LiveViews
- Add on_mount hook to ensure user role is loaded in all Member LiveViews - Pass actor parameter to all Ash operations (read, get, create, update, destroy, load)
This commit is contained in:
parent
dc3268cbf4
commit
bc87893134
7 changed files with 167 additions and 74 deletions
|
|
@ -388,6 +388,7 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
@impl true
|
||||
def update(assigns, socket) do
|
||||
member = assigns.member
|
||||
actor = assigns.current_user
|
||||
|
||||
# Load cycles if not already loaded
|
||||
cycles =
|
||||
|
|
@ -401,7 +402,7 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
cycles = Enum.sort_by(cycles, & &1.cycle_start, {:desc, Date})
|
||||
|
||||
# Get available fee types (filtered to same interval if member has a type)
|
||||
available_fee_types = get_available_fee_types(member)
|
||||
available_fee_types = get_available_fee_types(member, actor)
|
||||
|
||||
{:ok,
|
||||
socket
|
||||
|
|
@ -422,7 +423,9 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
@impl true
|
||||
def handle_event("change_membership_fee_type", %{"value" => ""}, socket) do
|
||||
# Remove membership fee type
|
||||
case update_member_fee_type(socket.assigns.member, nil) do
|
||||
actor = socket.assigns.current_user
|
||||
|
||||
case update_member_fee_type(socket.assigns.member, nil, actor) do
|
||||
{:ok, updated_member} ->
|
||||
send(self(), {:member_updated, updated_member})
|
||||
|
||||
|
|
@ -430,7 +433,10 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
socket
|
||||
|> assign(:member, updated_member)
|
||||
|> assign(:cycles, [])
|
||||
|> assign(:available_fee_types, get_available_fee_types(updated_member))
|
||||
|> assign(
|
||||
:available_fee_types,
|
||||
get_available_fee_types(updated_member, socket.assigns.current_user)
|
||||
)
|
||||
|> assign(:interval_warning, nil)
|
||||
|> put_flash(:info, gettext("Membership fee type removed"))}
|
||||
|
||||
|
|
@ -441,7 +447,8 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
|
||||
def handle_event("change_membership_fee_type", %{"value" => fee_type_id}, socket) do
|
||||
member = socket.assigns.member
|
||||
new_fee_type = Ash.get!(MembershipFeeType, fee_type_id, domain: MembershipFees)
|
||||
actor = socket.assigns.current_user
|
||||
new_fee_type = Ash.get!(MembershipFeeType, fee_type_id, domain: MembershipFees, actor: actor)
|
||||
|
||||
# Check if interval matches
|
||||
interval_warning =
|
||||
|
|
@ -459,15 +466,22 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
if interval_warning do
|
||||
{:noreply, assign(socket, :interval_warning, interval_warning)}
|
||||
else
|
||||
case update_member_fee_type(member, fee_type_id) do
|
||||
actor = socket.assigns.current_user
|
||||
|
||||
case update_member_fee_type(member, fee_type_id, actor) do
|
||||
{:ok, updated_member} ->
|
||||
# Reload member with cycles
|
||||
actor = socket.assigns.current_user
|
||||
|
||||
updated_member =
|
||||
updated_member
|
||||
|> Ash.load!([
|
||||
:membership_fee_type,
|
||||
membership_fee_cycles: [:membership_fee_type]
|
||||
])
|
||||
|> Ash.load!(
|
||||
[
|
||||
:membership_fee_type,
|
||||
membership_fee_cycles: [:membership_fee_type]
|
||||
],
|
||||
actor: actor
|
||||
)
|
||||
|
||||
cycles =
|
||||
Enum.sort_by(
|
||||
|
|
@ -482,7 +496,10 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
socket
|
||||
|> assign(:member, updated_member)
|
||||
|> assign(:cycles, cycles)
|
||||
|> assign(:available_fee_types, get_available_fee_types(updated_member))
|
||||
|> assign(
|
||||
:available_fee_types,
|
||||
get_available_fee_types(updated_member, socket.assigns.current_user)
|
||||
)
|
||||
|> assign(:interval_warning, nil)
|
||||
|> put_flash(:info, gettext("Membership fee type updated. Cycles regenerated."))}
|
||||
|
||||
|
|
@ -503,7 +520,9 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
:suspended -> :mark_as_suspended
|
||||
end
|
||||
|
||||
case Ash.update(cycle, action: action, domain: MembershipFees) do
|
||||
actor = socket.assigns.current_user
|
||||
|
||||
case Ash.update(cycle, action: action, domain: MembershipFees, actor: actor) do
|
||||
{:ok, updated_cycle} ->
|
||||
updated_cycles = replace_cycle(socket.assigns.cycles, updated_cycle)
|
||||
|
||||
|
|
@ -537,12 +556,17 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
case CycleGenerator.generate_cycles_for_member(member.id) do
|
||||
{:ok, _new_cycles, _notifications} ->
|
||||
# Reload member with cycles
|
||||
actor = socket.assigns.current_user
|
||||
|
||||
updated_member =
|
||||
member
|
||||
|> Ash.load!([
|
||||
:membership_fee_type,
|
||||
membership_fee_cycles: [:membership_fee_type]
|
||||
])
|
||||
|> Ash.load!(
|
||||
[
|
||||
:membership_fee_type,
|
||||
membership_fee_cycles: [:membership_fee_type]
|
||||
],
|
||||
actor: actor
|
||||
)
|
||||
|
||||
cycles =
|
||||
Enum.sort_by(
|
||||
|
|
@ -572,7 +596,8 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
cycle = find_cycle(socket.assigns.cycles, cycle_id)
|
||||
|
||||
# Load cycle with membership_fee_type for display
|
||||
cycle = Ash.load!(cycle, :membership_fee_type)
|
||||
actor = socket.assigns.current_user
|
||||
cycle = Ash.load!(cycle, :membership_fee_type, actor: actor)
|
||||
|
||||
{:noreply, assign(socket, :editing_cycle, cycle)}
|
||||
end
|
||||
|
|
@ -589,9 +614,11 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
|
||||
case Decimal.parse(normalized_amount_str) do
|
||||
{amount, _} when is_struct(amount, Decimal) ->
|
||||
actor = socket.assigns.current_user
|
||||
|
||||
case cycle
|
||||
|> Ash.Changeset.for_update(:update, %{amount: amount})
|
||||
|> Ash.update(domain: MembershipFees) do
|
||||
|> Ash.update(domain: MembershipFees, actor: actor) do
|
||||
{:ok, updated_cycle} ->
|
||||
updated_cycles = replace_cycle(socket.assigns.cycles, updated_cycle)
|
||||
|
||||
|
|
@ -616,7 +643,8 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
cycle = find_cycle(socket.assigns.cycles, cycle_id)
|
||||
|
||||
# Load cycle with membership_fee_type for display
|
||||
cycle = Ash.load!(cycle, :membership_fee_type)
|
||||
actor = socket.assigns.current_user
|
||||
cycle = Ash.load!(cycle, :membership_fee_type, actor: actor)
|
||||
|
||||
{:noreply, assign(socket, :deleting_cycle, cycle)}
|
||||
end
|
||||
|
|
@ -627,8 +655,9 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
|
||||
def handle_event("confirm_delete_cycle", %{"cycle_id" => cycle_id}, socket) do
|
||||
cycle = find_cycle(socket.assigns.cycles, cycle_id)
|
||||
actor = socket.assigns.current_user
|
||||
|
||||
case Ash.destroy(cycle, domain: MembershipFees) do
|
||||
case Ash.destroy(cycle, domain: MembershipFees, actor: actor) do
|
||||
:ok ->
|
||||
updated_cycles = Enum.reject(socket.assigns.cycles, &(&1.id == cycle_id))
|
||||
|
||||
|
|
@ -699,12 +728,17 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
|
||||
if deleted_count > 0 do
|
||||
# Reload member to get updated cycles
|
||||
actor = socket.assigns.current_user
|
||||
|
||||
updated_member =
|
||||
member
|
||||
|> Ash.load!([
|
||||
:membership_fee_type,
|
||||
membership_fee_cycles: [:membership_fee_type]
|
||||
])
|
||||
|> Ash.load!(
|
||||
[
|
||||
:membership_fee_type,
|
||||
membership_fee_cycles: [:membership_fee_type]
|
||||
],
|
||||
actor: actor
|
||||
)
|
||||
|
||||
updated_cycles =
|
||||
Enum.sort_by(
|
||||
|
|
@ -786,15 +820,20 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
membership_fee_type_id: member.membership_fee_type_id
|
||||
}
|
||||
|
||||
case Ash.create(MembershipFeeCycle, attrs, domain: MembershipFees) do
|
||||
actor = socket.assigns.current_user
|
||||
|
||||
case Ash.create(MembershipFeeCycle, attrs, domain: MembershipFees, actor: actor) do
|
||||
{:ok, _new_cycle} ->
|
||||
# Reload member with cycles
|
||||
updated_member =
|
||||
member
|
||||
|> Ash.load!([
|
||||
:membership_fee_type,
|
||||
membership_fee_cycles: [:membership_fee_type]
|
||||
])
|
||||
|> Ash.load!(
|
||||
[
|
||||
:membership_fee_type,
|
||||
membership_fee_cycles: [:membership_fee_type]
|
||||
],
|
||||
actor: actor
|
||||
)
|
||||
|
||||
cycles =
|
||||
Enum.sort_by(
|
||||
|
|
@ -842,11 +881,11 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
|
||||
# Helper functions
|
||||
|
||||
defp get_available_fee_types(member) do
|
||||
defp get_available_fee_types(member, actor) do
|
||||
all_types =
|
||||
MembershipFeeType
|
||||
|> Ash.Query.sort(name: :asc)
|
||||
|> Ash.read!()
|
||||
|> Ash.read!(domain: MembershipFees, actor: actor)
|
||||
|
||||
# If member has a fee type, filter to same interval
|
||||
if member.membership_fee_type do
|
||||
|
|
@ -858,12 +897,12 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do
|
|||
end
|
||||
end
|
||||
|
||||
defp update_member_fee_type(member, fee_type_id) do
|
||||
defp update_member_fee_type(member, fee_type_id, actor) do
|
||||
attrs = %{membership_fee_type_id: fee_type_id}
|
||||
|
||||
member
|
||||
|> Ash.Changeset.for_update(:update_member, attrs, domain: Membership)
|
||||
|> Ash.update(domain: Membership)
|
||||
|> Ash.update(domain: Membership, actor: actor)
|
||||
end
|
||||
|
||||
defp find_cycle(cycles, cycle_id) do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue