Refactor cycle generator and update translations
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Extract error handling into separate functions to reduce nesting depth.
This commit is contained in:
parent
1bb03b52c9
commit
a8ea121800
5 changed files with 82 additions and 42 deletions
|
|
@ -379,25 +379,10 @@ defmodule Mv.MembershipFees.CycleGenerator do
|
||||||
status: :unpaid
|
status: :unpaid
|
||||||
}
|
}
|
||||||
|
|
||||||
case Ash.create(MembershipFeeCycle, attrs, return_notifications?: true) do
|
handle_cycle_creation_result(
|
||||||
{:ok, cycle, notifications} when is_list(notifications) ->
|
Ash.create(MembershipFeeCycle, attrs, return_notifications?: true),
|
||||||
{:ok, cycle, notifications}
|
cycle_start
|
||||||
|
)
|
||||||
{:ok, cycle} ->
|
|
||||||
{:ok, cycle, []}
|
|
||||||
|
|
||||||
{:error, %Ash.Error.Invalid{errors: [%Ash.Error.Changes.InvalidAttribute{private_vars: %{constraint: constraint, constraint_type: :unique}}]}} = error ->
|
|
||||||
# Cycle already exists (unique constraint violation) - skip it silently
|
|
||||||
# This makes the function idempotent and prevents errors on server restart
|
|
||||||
if constraint == "membership_fee_cycles_unique_cycle_per_member_index" do
|
|
||||||
{:skip, cycle_start}
|
|
||||||
else
|
|
||||||
{:error, {cycle_start, error}}
|
|
||||||
end
|
|
||||||
|
|
||||||
{:error, reason} ->
|
|
||||||
{:error, {cycle_start, reason}}
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
{successes, skips, errors} =
|
{successes, skips, errors} =
|
||||||
|
|
@ -419,9 +404,7 @@ defmodule Mv.MembershipFees.CycleGenerator do
|
||||||
successful_cycles = Enum.map(successes, fn {:ok, cycle, _notifications} -> cycle end)
|
successful_cycles = Enum.map(successes, fn {:ok, cycle, _notifications} -> cycle end)
|
||||||
|
|
||||||
if Enum.any?(skips) do
|
if Enum.any?(skips) do
|
||||||
Logger.debug(
|
Logger.debug("Skipped #{length(skips)} cycles that already exist for member #{member_id}")
|
||||||
"Skipped #{length(skips)} cycles that already exist for member #{member_id}"
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
{:ok, successful_cycles, all_notifications}
|
{:ok, successful_cycles, all_notifications}
|
||||||
|
|
@ -433,4 +416,45 @@ defmodule Mv.MembershipFees.CycleGenerator do
|
||||||
{:error, {:partial_failure, errors}}
|
{:error, {:partial_failure, errors}}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp handle_cycle_creation_result({:ok, cycle, notifications}, _cycle_start)
|
||||||
|
when is_list(notifications) do
|
||||||
|
{:ok, cycle, notifications}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_cycle_creation_result({:ok, cycle}, _cycle_start) do
|
||||||
|
{:ok, cycle, []}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_cycle_creation_result(
|
||||||
|
{:error,
|
||||||
|
%Ash.Error.Invalid{
|
||||||
|
errors: [
|
||||||
|
%Ash.Error.Changes.InvalidAttribute{
|
||||||
|
private_vars: %{constraint: constraint, constraint_type: :unique}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}} = error,
|
||||||
|
cycle_start
|
||||||
|
) do
|
||||||
|
# Cycle already exists (unique constraint violation) - skip it silently
|
||||||
|
# This makes the function idempotent and prevents errors on server restart
|
||||||
|
handle_unique_constraint_violation(constraint, cycle_start, error)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_cycle_creation_result({:error, reason}, cycle_start) do
|
||||||
|
{:error, {cycle_start, reason}}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_unique_constraint_violation(
|
||||||
|
"membership_fee_cycles_unique_cycle_per_member_index",
|
||||||
|
cycle_start,
|
||||||
|
_error
|
||||||
|
) do
|
||||||
|
{:skip, cycle_start}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_unique_constraint_violation(_constraint, cycle_start, error) do
|
||||||
|
{:error, {cycle_start, error}}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ msgstr "Stadt"
|
||||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||||
#: lib/mv_web/live/member_live/index.html.heex
|
#: lib/mv_web/live/member_live/index.html.heex
|
||||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||||
#: lib/mv_web/live/membership_fee_type_live/index.ex
|
|
||||||
#: lib/mv_web/live/user_live/index.html.heex
|
#: lib/mv_web/live/user_live/index.html.heex
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
|
|
@ -779,6 +778,7 @@ msgid "Tip: Paste email addresses into the BCC field for privacy compliance"
|
||||||
msgstr "Tipp: E-Mail-Adressen ins BCC-Feld einfügen für Datenschutzkonformität"
|
msgstr "Tipp: E-Mail-Adressen ins BCC-Feld einfügen für Datenschutzkonformität"
|
||||||
|
|
||||||
#: lib/mv_web/components/core_components.ex
|
#: lib/mv_web/components/core_components.ex
|
||||||
|
#: lib/mv_web/live/membership_fee_type_live/form.ex
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "This field cannot be empty"
|
msgid "This field cannot be empty"
|
||||||
msgstr "Dieses Feld darf nicht leer bleiben"
|
msgstr "Dieses Feld darf nicht leer bleiben"
|
||||||
|
|
@ -1322,11 +1322,6 @@ msgstr "Textfeld"
|
||||||
msgid "Yes/No-Selection"
|
msgid "Yes/No-Selection"
|
||||||
msgstr "Ja/Nein-Auswahl"
|
msgstr "Ja/Nein-Auswahl"
|
||||||
|
|
||||||
#: lib/mv_web/live/components/payment_filter_component.ex
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "All payment statuses"
|
|
||||||
msgstr "Jeder Zahlungs-Zustand"
|
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex
|
#: lib/mv_web/live/member_live/index.html.heex
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Copy email addresses"
|
msgid "Copy email addresses"
|
||||||
|
|
@ -1754,7 +1749,7 @@ msgstr "Löschen"
|
||||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Delete All Cycles"
|
msgid "Delete All Cycles"
|
||||||
msgstr "Zyklus löschen"
|
msgstr "Alle Zyklen löschen"
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
|
@ -1816,6 +1811,16 @@ msgstr "Aktueller Zyklus Zahlungsstatus"
|
||||||
msgid "Last Cycle Payment Status"
|
msgid "Last Cycle Payment Status"
|
||||||
msgstr "Letzter Zyklus Zahlungsstatus"
|
msgstr "Letzter Zyklus Zahlungsstatus"
|
||||||
|
|
||||||
|
#: lib/mv_web/live/membership_fee_type_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Delete membership fee type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/membership_fee_type_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Edit membership fee type"
|
||||||
|
msgstr "Mitgliedsbeitragsart bearbeiten"
|
||||||
|
|
||||||
#~ #: lib/mv_web/live/components/payment_filter_component.ex
|
#~ #: lib/mv_web/live/components/payment_filter_component.ex
|
||||||
#~ #, elixir-autogen, elixir-format
|
#~ #, elixir-autogen, elixir-format
|
||||||
#~ msgid "All payment statuses"
|
#~ msgid "All payment statuses"
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ msgstr ""
|
||||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||||
#: lib/mv_web/live/member_live/index.html.heex
|
#: lib/mv_web/live/member_live/index.html.heex
|
||||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||||
#: lib/mv_web/live/membership_fee_type_live/index.ex
|
|
||||||
#: lib/mv_web/live/user_live/index.html.heex
|
#: lib/mv_web/live/user_live/index.html.heex
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
|
|
@ -780,6 +779,7 @@ msgid "Tip: Paste email addresses into the BCC field for privacy compliance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/core_components.ex
|
#: lib/mv_web/components/core_components.ex
|
||||||
|
#: lib/mv_web/live/membership_fee_type_live/form.ex
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "This field cannot be empty"
|
msgid "This field cannot be empty"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1323,11 +1323,6 @@ msgstr ""
|
||||||
msgid "Yes/No-Selection"
|
msgid "Yes/No-Selection"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/components/payment_filter_component.ex
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "All payment statuses"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex
|
#: lib/mv_web/live/member_live/index.html.heex
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Copy email addresses"
|
msgid "Copy email addresses"
|
||||||
|
|
@ -1816,3 +1811,13 @@ msgstr ""
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Last Cycle Payment Status"
|
msgid "Last Cycle Payment Status"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/membership_fee_type_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Delete membership fee type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/membership_fee_type_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Edit membership fee type"
|
||||||
|
msgstr ""
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ msgstr ""
|
||||||
#: lib/mv_web/live/custom_field_live/index_component.ex
|
#: lib/mv_web/live/custom_field_live/index_component.ex
|
||||||
#: lib/mv_web/live/member_live/index.html.heex
|
#: lib/mv_web/live/member_live/index.html.heex
|
||||||
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
#: lib/mv_web/live/member_live/show/membership_fees_component.ex
|
||||||
#: lib/mv_web/live/membership_fee_type_live/index.ex
|
|
||||||
#: lib/mv_web/live/user_live/index.html.heex
|
#: lib/mv_web/live/user_live/index.html.heex
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
|
|
@ -780,6 +779,7 @@ msgid "Tip: Paste email addresses into the BCC field for privacy compliance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/components/core_components.ex
|
#: lib/mv_web/components/core_components.ex
|
||||||
|
#: lib/mv_web/live/membership_fee_type_live/form.ex
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "This field cannot be empty"
|
msgid "This field cannot be empty"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1323,11 +1323,6 @@ msgstr ""
|
||||||
msgid "Yes/No-Selection"
|
msgid "Yes/No-Selection"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/mv_web/live/components/payment_filter_component.ex
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "All payment statuses"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/mv_web/live/member_live/index.html.heex
|
#: lib/mv_web/live/member_live/index.html.heex
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Copy email addresses"
|
msgid "Copy email addresses"
|
||||||
|
|
@ -1817,6 +1812,16 @@ msgstr "Current Cycle Payment Status"
|
||||||
msgid "Last Cycle Payment Status"
|
msgid "Last Cycle Payment Status"
|
||||||
msgstr "Last Cycle Payment Status"
|
msgstr "Last Cycle Payment Status"
|
||||||
|
|
||||||
|
#: lib/mv_web/live/membership_fee_type_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Delete membership fee type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/mv_web/live/membership_fee_type_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Edit membership fee type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ #: lib/mv_web/live/components/payment_filter_component.ex
|
#~ #: lib/mv_web/live/components/payment_filter_component.ex
|
||||||
#~ #, elixir-autogen, elixir-format
|
#~ #, elixir-autogen, elixir-format
|
||||||
#~ msgid "All payment statuses"
|
#~ msgid "All payment statuses"
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,8 @@ Enum.each(member_attrs_list, fn member_attrs ->
|
||||||
|
|
||||||
# Only set membership_fee_type_id if member doesn't have one yet (idempotent)
|
# Only set membership_fee_type_id if member doesn't have one yet (idempotent)
|
||||||
final_member =
|
final_member =
|
||||||
if is_nil(member.membership_fee_type_id) and Map.has_key?(member_attrs_without_status, :membership_fee_type_id) do
|
if is_nil(member.membership_fee_type_id) and
|
||||||
|
Map.has_key?(member_attrs_without_status, :membership_fee_type_id) do
|
||||||
member
|
member
|
||||||
|> Ash.Changeset.for_update(:update_member, %{
|
|> Ash.Changeset.for_update(:update_member, %{
|
||||||
membership_fee_type_id: member_attrs_without_status.membership_fee_type_id
|
membership_fee_type_id: member_attrs_without_status.membership_fee_type_id
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue