refactoring
This commit is contained in:
parent
86a3c4e50e
commit
12715f3d85
1 changed files with 104 additions and 68 deletions
|
|
@ -524,32 +524,12 @@ defmodule Mv.Membership.Import.MemberCSV do
|
|||
{:error, %Error{csv_line_number: line_number, field: nil, message: first_error}}
|
||||
|
||||
{:ok, custom_field_values} ->
|
||||
# Create member with custom field values
|
||||
member_attrs_with_cf =
|
||||
trimmed_member_attrs
|
||||
|> Map.put(:custom_field_values, custom_field_values)
|
||||
|
||||
# Only include custom_field_values if not empty
|
||||
final_attrs =
|
||||
if Enum.empty?(custom_field_values) do
|
||||
Map.delete(member_attrs_with_cf, :custom_field_values)
|
||||
else
|
||||
member_attrs_with_cf
|
||||
end
|
||||
|
||||
case Mv.Membership.create_member(final_attrs, actor: actor) do
|
||||
{:ok, member} ->
|
||||
{:ok, member}
|
||||
|
||||
{:error, %Ash.Error.Invalid{} = error} ->
|
||||
# Extract email from final_attrs for better error messages
|
||||
email = Map.get(final_attrs, :email) || Map.get(trimmed_member_attrs, :email)
|
||||
{:error, format_ash_error(error, line_number, email)}
|
||||
|
||||
{:error, error} ->
|
||||
{:error,
|
||||
%Error{csv_line_number: line_number, field: nil, message: inspect(error)}}
|
||||
end
|
||||
create_member_with_custom_fields(
|
||||
trimmed_member_attrs,
|
||||
custom_field_values,
|
||||
line_number,
|
||||
actor
|
||||
)
|
||||
end
|
||||
end
|
||||
rescue
|
||||
|
|
@ -557,6 +537,40 @@ defmodule Mv.Membership.Import.MemberCSV do
|
|||
{:error, %Error{csv_line_number: line_number, field: nil, message: Exception.message(e)}}
|
||||
end
|
||||
|
||||
# Creates a member with custom field values, handling errors appropriately
|
||||
defp create_member_with_custom_fields(
|
||||
trimmed_member_attrs,
|
||||
custom_field_values,
|
||||
line_number,
|
||||
actor
|
||||
) do
|
||||
# Create member with custom field values
|
||||
member_attrs_with_cf =
|
||||
trimmed_member_attrs
|
||||
|> Map.put(:custom_field_values, custom_field_values)
|
||||
|
||||
# Only include custom_field_values if not empty
|
||||
final_attrs =
|
||||
if Enum.empty?(custom_field_values) do
|
||||
Map.delete(member_attrs_with_cf, :custom_field_values)
|
||||
else
|
||||
member_attrs_with_cf
|
||||
end
|
||||
|
||||
case Mv.Membership.create_member(final_attrs, actor: actor) do
|
||||
{:ok, member} ->
|
||||
{:ok, member}
|
||||
|
||||
{:error, %Ash.Error.Invalid{} = error} ->
|
||||
# Extract email from final_attrs for better error messages
|
||||
email = Map.get(final_attrs, :email) || Map.get(trimmed_member_attrs, :email)
|
||||
{:error, format_ash_error(error, line_number, email)}
|
||||
|
||||
{:error, error} ->
|
||||
{:error, %Error{csv_line_number: line_number, field: nil, message: inspect(error)}}
|
||||
end
|
||||
end
|
||||
|
||||
# Prepares custom field values from row map for Ash
|
||||
# Returns {:ok, [custom_field_value_maps]} or {:error, [validation_errors]}
|
||||
defp prepare_custom_field_values(custom_attrs, custom_field_lookup) when is_map(custom_attrs) do
|
||||
|
|
@ -564,25 +578,13 @@ defmodule Mv.Membership.Import.MemberCSV do
|
|||
custom_attrs
|
||||
|> Enum.filter(fn {_id, value} -> value != nil && value != "" end)
|
||||
|> Enum.reduce({[], []}, fn {custom_field_id_str, value}, {acc_values, acc_errors} ->
|
||||
case Map.get(custom_field_lookup, custom_field_id_str) do
|
||||
nil ->
|
||||
# Custom field not found, skip
|
||||
{acc_values, acc_errors}
|
||||
|
||||
%{id: custom_field_id, value_type: value_type, name: custom_field_name} ->
|
||||
case format_custom_field_value(value, value_type, custom_field_name) do
|
||||
{:ok, formatted_value} ->
|
||||
value_map = %{
|
||||
"custom_field_id" => to_string(custom_field_id),
|
||||
"value" => formatted_value
|
||||
}
|
||||
|
||||
{[value_map | acc_values], acc_errors}
|
||||
|
||||
{:error, reason} ->
|
||||
{acc_values, [reason | acc_errors]}
|
||||
end
|
||||
end
|
||||
process_single_custom_field(
|
||||
custom_field_id_str,
|
||||
value,
|
||||
custom_field_lookup,
|
||||
acc_values,
|
||||
acc_errors
|
||||
)
|
||||
end)
|
||||
|
||||
if Enum.empty?(errors) do
|
||||
|
|
@ -594,6 +596,35 @@ defmodule Mv.Membership.Import.MemberCSV do
|
|||
|
||||
defp prepare_custom_field_values(_, _), do: {:ok, []}
|
||||
|
||||
# Processes a single custom field value and returns updated accumulator
|
||||
defp process_single_custom_field(
|
||||
custom_field_id_str,
|
||||
value,
|
||||
custom_field_lookup,
|
||||
acc_values,
|
||||
acc_errors
|
||||
) do
|
||||
case Map.get(custom_field_lookup, custom_field_id_str) do
|
||||
nil ->
|
||||
# Custom field not found, skip
|
||||
{acc_values, acc_errors}
|
||||
|
||||
%{id: custom_field_id, value_type: value_type, name: custom_field_name} ->
|
||||
case format_custom_field_value(value, value_type, custom_field_name) do
|
||||
{:ok, formatted_value} ->
|
||||
value_map = %{
|
||||
"custom_field_id" => to_string(custom_field_id),
|
||||
"value" => formatted_value
|
||||
}
|
||||
|
||||
{[value_map | acc_values], acc_errors}
|
||||
|
||||
{:error, reason} ->
|
||||
{acc_values, [reason | acc_errors]}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Formats a custom field value according to its type
|
||||
# Uses _union_type and _union_value format as expected by Ash
|
||||
# Returns {:ok, formatted_value} or {:error, error_message}
|
||||
|
|
@ -620,31 +651,19 @@ defmodule Mv.Membership.Import.MemberCSV do
|
|||
|
||||
defp format_custom_field_value(value, :boolean, custom_field_name) when is_binary(value) do
|
||||
trimmed = String.trim(value)
|
||||
lower = String.downcase(trimmed)
|
||||
|
||||
bool_value =
|
||||
case lower do
|
||||
"true" -> true
|
||||
"1" -> true
|
||||
"yes" -> true
|
||||
"ja" -> true
|
||||
"false" -> false
|
||||
"0" -> false
|
||||
"no" -> false
|
||||
"nein" -> false
|
||||
_ -> nil
|
||||
end
|
||||
case parse_boolean_value(trimmed) do
|
||||
{:ok, bool_value} ->
|
||||
{:ok, %{"_union_type" => "boolean", "_union_value" => bool_value}}
|
||||
|
||||
if bool_value != nil do
|
||||
{:ok, %{"_union_type" => "boolean", "_union_value" => bool_value}}
|
||||
else
|
||||
{:error,
|
||||
format_custom_field_error_with_details(
|
||||
custom_field_name,
|
||||
:boolean,
|
||||
trimmed,
|
||||
gettext("(true/false/1/0/yes/no/ja/nein)")
|
||||
)}
|
||||
:error ->
|
||||
{:error,
|
||||
format_custom_field_error_with_details(
|
||||
custom_field_name,
|
||||
:boolean,
|
||||
trimmed,
|
||||
gettext("(true/false/1/0/yes/no/ja/nein)")
|
||||
)}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -690,6 +709,23 @@ defmodule Mv.Membership.Import.MemberCSV do
|
|||
{:ok, %{"_union_type" => "string", "_union_value" => String.trim(value)}}
|
||||
end
|
||||
|
||||
# Parses a boolean value from a string, supporting multiple formats
|
||||
defp parse_boolean_value(value) when is_binary(value) do
|
||||
lower = String.downcase(value)
|
||||
parse_boolean_value_lower(lower)
|
||||
end
|
||||
|
||||
# Helper function with pattern matching for boolean values
|
||||
defp parse_boolean_value_lower("true"), do: {:ok, true}
|
||||
defp parse_boolean_value_lower("1"), do: {:ok, true}
|
||||
defp parse_boolean_value_lower("yes"), do: {:ok, true}
|
||||
defp parse_boolean_value_lower("ja"), do: {:ok, true}
|
||||
defp parse_boolean_value_lower("false"), do: {:ok, false}
|
||||
defp parse_boolean_value_lower("0"), do: {:ok, false}
|
||||
defp parse_boolean_value_lower("no"), do: {:ok, false}
|
||||
defp parse_boolean_value_lower("nein"), do: {:ok, false}
|
||||
defp parse_boolean_value_lower(_), do: :error
|
||||
|
||||
# Generates a consistent error message for custom field validation failures
|
||||
# Uses human-readable field type labels (e.g., "Number" instead of "integer")
|
||||
defp format_custom_field_error(custom_field_name, value_type, value) do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue