- 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
54 lines
1.6 KiB
Elixir
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
|