mitgliederverwaltung/lib/mv/vereinfacht/changes/sync_contact.ex
Moritz 3a61699dd2
feat(vereinfacht): add client, sync flash and SyncContact change
- Application: create SyncFlash ETS table on start
- Vereinfacht: Client, SyncFlash, sync_member, format_error, sync_members_without_contact
- SyncContact change on Member create_member and update_member
- Member: attribute vereinfacht_contact_id, internal action set_vereinfacht_contact_id
2026-02-18 22:30:15 +01:00

54 lines
1.6 KiB
Elixir

defmodule Mv.Vereinfacht.Changes.SyncContact do
@moduledoc """
Syncs a member to Vereinfacht as a finance contact after create/update.
- If the member has no `vereinfacht_contact_id`, creates a contact via API and saves the ID.
- If the member already has an ID, updates the contact via API.
Runs in `after_transaction` so the member is persisted first. API failures are logged
but do not block the member operation. Requires Vereinfacht to be configured
(Mv.Config.vereinfacht_configured?/0).
"""
use Ash.Resource.Change
require Logger
@impl true
def change(changeset, _opts, _context) do
if Mv.Config.vereinfacht_configured?() do
Ash.Changeset.after_transaction(changeset, &sync_after_transaction/2)
else
changeset
end
end
# Ash calls after_transaction with (changeset, result) only - 2 args.
defp sync_after_transaction(_changeset, {:ok, member}) do
case Mv.Vereinfacht.sync_member(member) do
:ok ->
Mv.Vereinfacht.SyncFlash.store(to_string(member.id), :ok, "Synced to Vereinfacht.")
{:ok, member}
{:ok, member_updated} ->
Mv.Vereinfacht.SyncFlash.store(
to_string(member_updated.id),
:ok,
"Synced to Vereinfacht."
)
{:ok, member_updated}
{:error, reason} ->
Logger.warning("Vereinfacht sync failed for member #{member.id}: #{inspect(reason)}")
Mv.Vereinfacht.SyncFlash.store(
to_string(member.id),
:warning,
Mv.Vereinfacht.format_error(reason)
)
{:ok, member}
end
end
defp sync_after_transaction(_changeset, error), do: error
end