fix: add validation for required custom fields
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
carla 2025-12-17 13:31:15 +01:00
parent 894b9b9d5c
commit bbc094daaa
3 changed files with 519 additions and 0 deletions

View file

@ -329,6 +329,63 @@ defmodule Mv.Membership.Member do
{:error, field: :email, message: "is not a valid email"}
end
end
# Validate required custom fields
validate fn changeset, _ ->
custom_field_values_arg = Ash.Changeset.get_argument(changeset, :custom_field_values)
# If argument is not provided (nil), check existing values from member data (update scenario)
# If argument is provided (empty list or list with values), use those values
provided_values =
if is_nil(custom_field_values_arg) do
# Update scenario: check existing custom field values from member
case Ash.load(changeset.data, :custom_field_values) do
{:ok, %{custom_field_values: existing_values}} ->
Enum.reduce(existing_values, %{}, fn cfv, acc ->
value = if is_map(cfv.value), do: Map.get(cfv.value, :value), else: nil
Map.put(acc, cfv.custom_field_id, value)
end)
_ ->
%{}
end
else
# Create or update scenario: use provided argument values
Enum.reduce(custom_field_values_arg, %{}, fn cfv, acc ->
custom_field_id = Map.get(cfv, "custom_field_id")
value_map = Map.get(cfv, "value", %{})
actual_value = Map.get(value_map, "value")
Map.put(acc, custom_field_id, actual_value)
end)
end
# Load all required custom fields
case Mv.Membership.list_custom_fields() do
{:ok, all_custom_fields} ->
required_custom_fields = Enum.filter(all_custom_fields, & &1.required)
# Check each required custom field
missing_fields =
Enum.filter(required_custom_fields, fn cf ->
value = Map.get(provided_values, cf.id)
not value_present?(value, cf.value_type)
end)
if Enum.empty?(missing_fields) do
:ok
else
missing_names = Enum.map_join(missing_fields, ", ", & &1.name)
{:error,
field: :custom_field_values,
message: "Required custom fields missing: #{missing_names}"}
end
{:error, _} ->
# If we can't load custom fields, skip validation (shouldn't happen in normal operation)
:ok
end
end
end
attributes do
@ -665,4 +722,18 @@ defmodule Mv.Membership.Member do
query
end
end
# Helper function to check if a value is present for a given custom field type
# Boolean: false is valid, only nil is invalid
# String: nil or empty strings are invalid
# Integer: nil is invalid, 0 is valid
# Date: nil is invalid
# Email: nil is invalid
defp value_present?(nil, _type), do: false
defp value_present?(value, :boolean), do: not is_nil(value)
defp value_present?(value, :string), do: is_binary(value) and String.trim(value) != ""
defp value_present?(value, :integer), do: not is_nil(value)
defp value_present?(value, :date), do: not is_nil(value)
defp value_present?(value, :email), do: not is_nil(value)
defp value_present?(_value, _type), do: false
end