Remove future date validation for join_date

Allow join_date to be set in the future. Only validation remaining
is that exit_date must be after join_date.
This commit is contained in:
Moritz 2025-12-16 17:24:24 +01:00
parent 8f8c3f258a
commit 9a1f0fbfa6
Signed by: moritz
GPG key ID: 1020A035E5DD0824
2 changed files with 59 additions and 10 deletions

View file

@ -242,6 +242,63 @@ defmodule Mv.Membership.Member do
{:ok, member}
end
end)
# Trigger cycle regeneration when join_date or exit_date changes
# Regenerates cycles based on new dates
# Note: Cycle generation runs synchronously in test environment, asynchronously in production
# CycleGenerator uses advisory locks and transactions internally to prevent race conditions
change after_action(fn changeset, member, _context ->
join_date_changed = Ash.Changeset.changing_attribute?(changeset, :join_date)
exit_date_changed = Ash.Changeset.changing_attribute?(changeset, :exit_date)
if (join_date_changed || exit_date_changed) && member.membership_fee_type_id do
if Application.get_env(:mv, :sql_sandbox, false) do
# Run synchronously in test environment for DB sandbox compatibility
# Use skip_lock?: true to avoid nested transactions (after_action runs within action transaction)
# Return notifications to Ash so they are sent after commit
case Mv.MembershipFees.CycleGenerator.generate_cycles_for_member(
member.id,
today: Date.utc_today(),
skip_lock?: true
) do
{:ok, _cycles, notifications} ->
{:ok, member, notifications}
{:error, reason} ->
require Logger
Logger.warning(
"Failed to regenerate cycles for member #{member.id}: #{inspect(reason)}"
)
{:ok, member}
end
else
# Run asynchronously in other environments
# Send notifications explicitly since they cannot be returned via after_action
Task.start(fn ->
case Mv.MembershipFees.CycleGenerator.generate_cycles_for_member(member.id) do
{:ok, _cycles, notifications} ->
# Send notifications manually for async case
if Enum.any?(notifications) do
Ash.Notifier.notify(notifications)
end
{:error, reason} ->
require Logger
Logger.warning(
"Failed to regenerate cycles for member #{member.id}: #{inspect(reason)}"
)
end
end)
{:ok, member}
end
else
{:ok, member}
end
end)
end
# Action to handle fuzzy search on specific fields
@ -395,11 +452,6 @@ defmodule Mv.Membership.Member do
end
end
# Join date not in the future
validate compare(:join_date, less_than_or_equal_to: &Date.utc_today/0),
where: [present(:join_date)],
message: "cannot be in the future"
# Exit date not before join date
validate compare(:exit_date, greater_than: :join_date),
where: [present([:join_date, :exit_date])],