From c445b78157b6bcc072aa48831f74de9b2d2472b9 Mon Sep 17 00:00:00 2001 From: Moritz Date: Fri, 12 Dec 2025 19:01:18 +0100 Subject: [PATCH] feat: prevent deletion of membership fee type when used as default in settings --- lib/membership_fees/membership_fee_type.ex | 22 +++++++++++++++++++ .../membership_fee_type_integration_test.exs | 18 +++++++++++++++ .../membership_fee_type_test.exs | 16 ++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/lib/membership_fees/membership_fee_type.ex b/lib/membership_fees/membership_fee_type.ex index 2f22e65..f96920d 100644 --- a/lib/membership_fees/membership_fee_type.ex +++ b/lib/membership_fees/membership_fee_type.ex @@ -120,6 +120,28 @@ defmodule Mv.MembershipFees.MembershipFeeType do end end, on: [:destroy] + + # Prevent deletion if used as default in settings + validate fn changeset, _context -> + if changeset.action_type == :destroy do + require Ash.Query + + setting_count = + Mv.Membership.Setting + |> Ash.Query.filter(default_membership_fee_type_id == ^changeset.data.id) + |> Ash.count!() + + if setting_count > 0 do + {:error, + message: "Cannot delete membership fee type: it's used as default in settings"} + else + :ok + end + else + :ok + end + end, + on: [:destroy] end attributes do diff --git a/test/membership_fees/membership_fee_type_integration_test.exs b/test/membership_fees/membership_fee_type_integration_test.exs index 8006962..b70f47c 100644 --- a/test/membership_fees/membership_fee_type_integration_test.exs +++ b/test/membership_fees/membership_fee_type_integration_test.exs @@ -123,6 +123,24 @@ defmodule Mv.MembershipFees.MembershipFeeTypeIntegrationTest do error_message = extract_error_message(error) assert error_message =~ "cycle(s) reference" end + + test "cannot delete when used as default in settings" do + fee_type = create_fee_type(%{interval: :yearly}) + + # Set as default in settings + {:ok, settings} = Mv.Membership.get_settings() + + settings + |> Ash.Changeset.for_update(:update_membership_fee_settings, %{ + default_membership_fee_type_id: fee_type.id + }) + |> Ash.update!() + + # Try to delete + assert {:error, error} = Ash.destroy(fee_type) + error_message = extract_error_message(error) + assert error_message =~ "used as default in settings" + end end describe "settings integration" do diff --git a/test/membership_fees/membership_fee_type_test.exs b/test/membership_fees/membership_fee_type_test.exs index a87d667..626e096 100644 --- a/test/membership_fees/membership_fee_type_test.exs +++ b/test/membership_fees/membership_fee_type_test.exs @@ -228,6 +228,22 @@ defmodule Mv.MembershipFees.MembershipFeeTypeTest do error_message = extract_error_message(error) assert error_message =~ "cycle" or error_message =~ "referenced" end + + test "cannot delete when used as default in settings", %{fee_type: fee_type} do + # Set as default in settings + {:ok, settings} = Mv.Membership.get_settings() + + settings + |> Ash.Changeset.for_update(:update_membership_fee_settings, %{ + default_membership_fee_type_id: fee_type.id + }) + |> Ash.update!() + + # Try to delete + assert {:error, error} = Ash.destroy(fee_type) + error_message = extract_error_message(error) + assert error_message =~ "used as default in settings" + end end # Helper to check if an error occurred on a specific field