fix: add validation for required custom fields
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
894b9b9d5c
commit
bbc094daaa
3 changed files with 519 additions and 0 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ defmodule MvWeb.MemberLive.Form do
|
|||
field={value_form[:value]}
|
||||
label={cf.name}
|
||||
type={custom_field_input_type(cf.value_type)}
|
||||
required={cf.required}
|
||||
/>
|
||||
</.inputs_for>
|
||||
<input
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue