ImplementsCSV Import UI closes #335 #359
4 changed files with 54 additions and 307 deletions
|
|
@ -528,7 +528,9 @@ defmodule Mv.Membership.Import.MemberCSV do
|
|||
{:ok, member}
|
||||
|
||||
{:error, %Ash.Error.Invalid{} = error} ->
|
||||
{:error, format_ash_error(error, line_number)}
|
||||
# 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)}}
|
||||
|
|
@ -621,7 +623,7 @@ defmodule Mv.Membership.Import.MemberCSV do
|
|||
end
|
||||
|
||||
# Formats Ash errors into MemberCSV.Error structs
|
||||
defp format_ash_error(%Ash.Error.Invalid{errors: errors}, line_number) do
|
||||
defp format_ash_error(%Ash.Error.Invalid{errors: errors}, line_number, email) do
|
||||
# Try to find email-related errors first (for better error messages)
|
||||
email_error =
|
||||
Enum.find(errors, fn error ->
|
||||
|
|
@ -636,35 +638,37 @@ defmodule Mv.Membership.Import.MemberCSV do
|
|||
%Error{
|
||||
csv_line_number: line_number,
|
||||
field: field,
|
||||
message: format_error_message(message, field)
|
||||
message: format_error_message(message, field, email)
|
||||
}
|
||||
|
||||
%{message: message} ->
|
||||
%Error{
|
||||
csv_line_number: line_number,
|
||||
field: nil,
|
||||
message: format_error_message(message, nil)
|
||||
message: format_error_message(message, nil, email)
|
||||
}
|
||||
|
||||
_ ->
|
||||
%Error{
|
||||
csv_line_number: line_number,
|
||||
field: nil,
|
||||
message: "Validation failed"
|
||||
message: gettext("Validation failed")
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# Formats error messages, handling common cases like email uniqueness
|
||||
defp format_error_message(message, field) when is_binary(message) do
|
||||
defp format_error_message(message, field, email) when is_binary(message) do
|
||||
if email_uniqueness_error?(message, field) do
|
||||
"email has already been taken"
|
||||
# Include email in error message for better user feedback
|
||||
email_str = if email, do: to_string(email), else: gettext("email")
|
||||
gettext("email %{email} has already been taken", email: email_str)
|
||||
else
|
||||
message
|
||||
end
|
||||
end
|
||||
|
||||
defp format_error_message(message, _field), do: to_string(message)
|
||||
defp format_error_message(message, _field, _email), do: to_string(message)
|
||||
|
||||
# Checks if error message indicates email uniqueness constraint violation
|
||||
defp email_uniqueness_error?(message, :email) do
|
||||
|
|
|
|||
|
|
@ -2110,3 +2110,18 @@ msgstr "Verwenden Sie den Namen des benutzerdefinierten Feldes als CSV-Spaltenü
|
|||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Warnings"
|
||||
msgstr "Warnungen"
|
||||
|
||||
#: lib/mv/membership/import/member_csv.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Validation failed"
|
||||
msgstr "Validierung fehlgeschlagen: %{message}"
|
||||
|
||||
#: lib/mv/membership/import/member_csv.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "email"
|
||||
msgstr "E-Mail"
|
||||
|
||||
#: lib/mv/membership/import/member_csv.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "email %{email} has already been taken"
|
||||
msgstr "E-Mail %{email} wurde bereits verwendet"
|
||||
|
|
|
|||
|
|
@ -2111,3 +2111,18 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgid "Warnings"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv/membership/import/member_csv.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Validation failed"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv/membership/import/member_csv.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "email"
|
||||
msgstr ""
|
||||
|
||||
#: lib/mv/membership/import/member_csv.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "email %{email} has already been taken"
|
||||
msgstr ""
|
||||
|
|
|
|||
|
|
@ -2112,304 +2112,17 @@ msgstr ""
|
|||
msgid "Warnings"
|
||||
msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_value_live/form.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Use this form to manage Custom Field Value records in your database."
|
||||
#~ msgstr ""
|
||||
#: lib/mv/membership/import/member_csv.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "Validation failed"
|
||||
msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_value_live/form.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Choose a custom field"
|
||||
#~ msgstr ""
|
||||
#: lib/mv/membership/import/member_csv.ex
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "email"
|
||||
msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Joining year - reduced to 0"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/components/layouts/sidebar.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Admin"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Regular"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/components/member_filter_component.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Payment"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Current"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Paid via bank transfer"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Mark as Unpaid"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Half-yearly contribution for supporting members"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Reduced fee for unemployed, pensioners, or low income"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_value_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Custom field value not found"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Supporting Member"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Monthly fee for students and trainees"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/components/payment_filter_component.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Filter by payment status"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_value_live/form.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Custom field value %{action} successfully"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Total Contributions"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Manage contribution types for membership fees."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Change Contribution Type"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "New Contribution Type"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Time Period"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_value_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Custom field value deleted successfully"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_value_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "You do not have permission to access this custom field value"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Cannot delete - members assigned"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Preview Mockup"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Contribution Types"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "This page is not functional and only displays the planned features."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Member since"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_value_live/form.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Unsupported value type: %{type}"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_value_live/form.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Custom field"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Mark as Paid"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Contribution type"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/components/layouts/sidebar.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Contributions"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Reduced"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "No fee for honorary members"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_value_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "You do not have permission to delete this custom field value"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "%{count} period selected"
|
||||
#~ msgid_plural "%{count} periods selected"
|
||||
#~ msgstr[0] ""
|
||||
#~ msgstr[1] ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Mark as Suspended"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Contribution types define different membership fee structures. Each type has a fixed cycle (monthly, quarterly, half-yearly, yearly) that cannot be changed after creation."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_value_live/form.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Choose a member"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Suspend"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Reopen"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_value_live/form.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Value"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Why are not all contribution types shown?"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Contribution Start"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Standard membership fee for regular members"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_value_live/form.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Save Custom Field Value"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Honorary"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Contributions for %{name}"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/components/member_filter_component.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "Payment status filter"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Family"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/custom_field_value_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format, fuzzy
|
||||
#~ msgid "You do not have permission to view custom field values"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Student"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Quarterly fee for family memberships"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Members can only switch between contribution types with the same payment interval (e.g., yearly to yearly). This prevents complex period overlaps."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Open Contributions"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_period_live/show.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Member Contributions"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/contribution_type_live/index.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "About Contribution Types"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ #: lib/mv_web/live/components/member_filter_component.ex
|
||||
#~ #, elixir-autogen, elixir-format
|
||||
#~ msgid "Filter by %{name}"
|
||||
#~ msgstr ""
|
||||
#: lib/mv/membership/import/member_csv.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "email %{email} has already been taken"
|
||||
msgstr ""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue