From 2db467d5d16d76f574a8edb7ec6c2ba4a89378ff Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 2 Jun 2026 12:04:37 +0200 Subject: [PATCH] fix(pdf-export): match DateTime.from_iso8601 three-tuple when formatting cells DateTime.from_iso8601/1 returns {:ok, datetime, offset}, so the two-tuple clauses never matched and datetime cells fell through to the naive-parse fallback. Matching the real shape routes them through the intended DateTime path; UTC values render identically. --- lib/mv/membership/members_pdf.ex | 9 ++------- test/mv/membership/members_pdf_test.exs | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/mv/membership/members_pdf.ex b/lib/mv/membership/members_pdf.ex index b2989ca..a1c8418 100644 --- a/lib/mv/membership/members_pdf.ex +++ b/lib/mv/membership/members_pdf.ex @@ -143,7 +143,7 @@ defmodule Mv.Membership.MembersPDF do defp convert_to_template_format(export_data, locale, club_name) do # Set locale for translations - Gettext.put_locale(MvWeb.Gettext, locale) + _ = Gettext.put_locale(MvWeb.Gettext, locale) headers = Enum.map(export_data.columns, & &1.label) column_count = length(export_data.columns) @@ -211,9 +211,6 @@ defmodule Mv.Membership.MembersPDF do {:ok, datetime, _offset} -> format_datetime(datetime, locale) - {:ok, datetime} -> - format_datetime(datetime, locale) - {:error, _} -> # Try NaiveDateTime if DateTime parsing fails case NaiveDateTime.from_iso8601(iso8601_string) do @@ -257,8 +254,6 @@ defmodule Mv.Membership.MembersPDF do end end - defp format_date(_, _), do: "" - defp format_dates_in_rows(rows, columns, locale) do date_indices = find_date_column_indices(columns) @@ -321,7 +316,7 @@ defmodule Mv.Membership.MembersPDF do defp format_cell_date_datetime(cell_value, locale) do case DateTime.from_iso8601(cell_value) do - {:ok, datetime} -> format_datetime(datetime, locale) + {:ok, datetime, _offset} -> format_datetime(datetime, locale) _ -> format_cell_date_naive(cell_value, locale) end end diff --git a/test/mv/membership/members_pdf_test.exs b/test/mv/membership/members_pdf_test.exs index 78a8ca6..2b83e3b 100644 --- a/test/mv/membership/members_pdf_test.exs +++ b/test/mv/membership/members_pdf_test.exs @@ -101,6 +101,29 @@ defmodule Mv.Membership.MembersPDFTest do assert byte_size(pdf_binary) > 1000 end + test "renders date column holding an ISO8601 datetime value" do + # Regression: a date column whose value is a full datetime string must be + # parsed via DateTime.from_iso8601/1 (which returns a 3-tuple) and rendered, + # not silently dropped. + export_data = %{ + columns: [ + %{key: "first_name", kind: :member_field, label: "Vorname"}, + %{key: "join_date", kind: :member_field, label: "Eintritt"} + ], + rows: [ + ["Max", "2024-01-15T14:30:00Z"] + ], + meta: %{ + generated_at: "2024-01-15T14:30:00Z", + member_count: 1 + } + } + + assert {:ok, pdf_binary} = MembersPDF.render(export_data) + assert String.starts_with?(pdf_binary, "%PDF") + assert byte_size(pdf_binary) > 1000 + end + test "generates valid PDF with custom fields and computed fields" do export_data = %{ columns: [