import: update csv with country
This commit is contained in:
parent
f681ca98b2
commit
2408978180
2 changed files with 76 additions and 9 deletions
|
|
@ -17,15 +17,24 @@ defmodule Mv.Membership.Import.HeaderMapper do
|
|||
|
||||
## Member Field Mapping
|
||||
|
||||
Maps CSV headers to canonical member fields:
|
||||
- `email` (required)
|
||||
- `first_name` (optional)
|
||||
- `last_name` (optional)
|
||||
- `street` (optional)
|
||||
- `postal_code` (optional)
|
||||
- `city` (optional)
|
||||
Maps CSV headers to canonical member fields (same as `Mv.Constants.member_fields()` for
|
||||
importable attributes). All DB-backed member attributes can be imported.
|
||||
|
||||
Supports both English and German variants (e.g., "Email" / "E-Mail", "First Name" / "Vorname").
|
||||
- `email` (required)
|
||||
- `first_name`, `last_name` (optional)
|
||||
- `join_date`, `exit_date` (optional, ISO-8601 date)
|
||||
- `notes` (optional)
|
||||
- `country`, `city`, `street`, `house_number`, `postal_code` (optional)
|
||||
- `membership_fee_start_date` (optional, ISO-8601 date)
|
||||
|
||||
Supports English and German header variants (e.g. "Email" / "E-Mail", "Join Date" / "Beitrittsdatum").
|
||||
|
||||
## Fields not supported for import
|
||||
|
||||
- **membership_fee_status** – Computed (calculation from membership fee cycles). Not stored;
|
||||
cannot be set via CSV. Export can include it.
|
||||
- **groups** – Many-to-many relationship (through member_groups). Import would require
|
||||
resolving group names/slugs to IDs and creating associations; not in current import scope.
|
||||
|
||||
## Custom Field Detection
|
||||
|
||||
|
|
@ -75,11 +84,37 @@ defmodule Mv.Membership.Import.HeaderMapper do
|
|||
"nachname",
|
||||
"familienname"
|
||||
],
|
||||
join_date: [
|
||||
"join date",
|
||||
"join_date",
|
||||
"beitrittsdatum",
|
||||
"beitritts-datum"
|
||||
],
|
||||
exit_date: [
|
||||
"exit date",
|
||||
"exit_date",
|
||||
"austrittsdatum",
|
||||
"austritts-datum"
|
||||
],
|
||||
notes: [
|
||||
"notes",
|
||||
"notizen",
|
||||
"bemerkungen"
|
||||
],
|
||||
street: [
|
||||
"street",
|
||||
"address",
|
||||
"strasse"
|
||||
],
|
||||
house_number: [
|
||||
"house number",
|
||||
"house_number",
|
||||
"house no",
|
||||
"hausnummer",
|
||||
"nr",
|
||||
"nr.",
|
||||
"nummer"
|
||||
],
|
||||
postal_code: [
|
||||
"postal code",
|
||||
"postal_code",
|
||||
|
|
@ -93,6 +128,18 @@ defmodule Mv.Membership.Import.HeaderMapper do
|
|||
"town",
|
||||
"stadt",
|
||||
"ort"
|
||||
],
|
||||
country: [
|
||||
"country",
|
||||
"land",
|
||||
"staat"
|
||||
],
|
||||
membership_fee_start_date: [
|
||||
"membership fee start date",
|
||||
"membership_fee_start_date",
|
||||
"fee start",
|
||||
"beitragsbeginn",
|
||||
"beitrags-beginn"
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -549,9 +549,12 @@ defmodule Mv.Membership.Import.MemberCSV do
|
|||
line_number,
|
||||
actor
|
||||
) do
|
||||
# Convert empty strings to nil for date fields so Ash accepts them
|
||||
member_attrs = sanitize_date_fields(trimmed_member_attrs)
|
||||
|
||||
# Create member with custom field values
|
||||
member_attrs_with_cf =
|
||||
trimmed_member_attrs
|
||||
member_attrs
|
||||
|> Map.put(:custom_field_values, custom_field_values)
|
||||
|
||||
# Only include custom_field_values if not empty
|
||||
|
|
@ -793,6 +796,23 @@ defmodule Mv.Membership.Import.MemberCSV do
|
|||
end)
|
||||
end
|
||||
|
||||
# Converts empty strings to nil for date fields so Ash can accept them
|
||||
@date_fields [:join_date, :exit_date, :membership_fee_start_date]
|
||||
|
||||
defp sanitize_date_fields(attrs) when is_map(attrs) do
|
||||
Enum.reduce(@date_fields, attrs, fn field, acc ->
|
||||
put_date_field(acc, field, Map.get(acc, field))
|
||||
end)
|
||||
end
|
||||
|
||||
defp put_date_field(acc, field, ""), do: Map.put(acc, field, nil)
|
||||
|
||||
defp put_date_field(acc, field, val) when is_binary(val) do
|
||||
if String.trim(val) == "", do: Map.put(acc, field, nil), else: acc
|
||||
end
|
||||
|
||||
defp put_date_field(acc, _field, _), do: acc
|
||||
|
||||
# Formats Ash errors into MemberCSV.Error structs
|
||||
defp format_ash_error(%Ash.Error.Invalid{errors: errors}, line_number, email) do
|
||||
# Try to find email-related errors first (for better error messages)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue