fix(member-export): split composite Name and Address into component columns on export

This commit is contained in:
Simon 2026-07-16 09:38:54 +02:00
parent a64835fe6d
commit 0a23d03d9d
3 changed files with 96 additions and 1 deletions

View file

@ -29,10 +29,17 @@ defmodule MvWeb.MemberLive.Index.ExportPayload do
member_fields_computed = assigns[:member_fields_visible_computed] || []
member_fields_visible = assigns[:member_fields_visible] || []
# The composite Name/Address cells have no DB column of their own, so they are
# not in `member_fields_visible_db` — and their constituents are hidden from
# it precisely because the composite replaces them in the table. When a
# composite is the visible variant, export its constituent DB columns instead
# so the CSV/PDF still carries name and address, split into components.
composite_constituents = composite_export_constituents(member_fields_visible, assigns)
# Order DB member fields exactly like the table/constants.
ordered_member_fields_db =
Mv.Constants.member_fields()
|> Enum.filter(&(&1 in member_fields_db))
|> Enum.filter(&(&1 in member_fields_db or &1 in composite_constituents))
# Order computed fields in canonical order.
ordered_computed_fields =
@ -92,6 +99,26 @@ defmodule MvWeb.MemberLive.Index.ExportPayload do
defp cycle_status_filter(:unpaid), do: "unpaid"
defp cycle_status_filter(_), do: nil
# DB constituent columns to add for whichever composite cells are currently
# visible. Email is a name constituent only while folded into the compact
# Member cell (`member_include_email`); otherwise it is exported as its own
# visible column and needs no expansion here.
defp composite_export_constituents(member_fields_visible, assigns) do
name =
if :name in member_fields_visible do
FieldVisibility.name_constituents(assigns[:member_include_email] || false)
else
[]
end
address =
if :address in member_fields_visible,
do: FieldVisibility.address_constituents(),
else: []
name ++ address
end
defp build_member_fields_list(ordered_db, member_fields_visible) do
member_fields_visible = member_fields_visible || []

View file

@ -135,6 +135,20 @@ defmodule MvWeb.MemberLive.Index.FieldVisibility do
leading ++ rest
end
@doc """
The DB constituent columns the composite `:name` cell stands in for, in
canonical order. `:email` is a constituent only while it is folded into the
compact Member cell (`include_email?` true); otherwise it is its own column.
"""
@spec name_constituents(boolean()) :: [atom()]
def name_constituents(include_email?) do
if include_email?, do: @name_constituents, else: @name_constituents -- [:email]
end
@doc "The DB constituent columns the composite `:address` cell stands in for, in canonical order."
@spec address_constituents() :: [:street | :house_number | :postal_code | :city, ...]
def address_constituents, do: @address_constituents
# The email is a separate offered column except when it is folded into the
# compact Member cell (compact + include_email).
defp email_offered?(compact_member, include_email), do: not (compact_member and include_email)