diff --git a/lib/safira/contest/contest.ex b/lib/safira/contest/contest.ex index 672033e8..a2645fa9 100644 --- a/lib/safira/contest/contest.ex +++ b/lib/safira/contest/contest.ex @@ -169,7 +169,13 @@ defmodule Safira.Contest do def create_redeem(attrs \\ %{}, user_type \\ :staff) do Multi.new() - |> Multi.insert(:redeem, Redeem.changeset(%Redeem{}, attrs, user_type)) + |> Multi.insert(:redeem, fn _ -> + if Interaction.is_badge_spotlighted(attrs.badge_id) do + attrs = Map.put(attrs, :spotlighted, true) + end + + Redeem.changeset(%Redeem{}, attrs, user_type) + end) |> Multi.update(:attendee, fn %{redeem: redeem} -> redeem = Repo.preload(redeem, [:badge, :attendee]) diff --git a/lib/safira/contest/redeem.ex b/lib/safira/contest/redeem.ex index d5009e9a..cfc905ce 100644 --- a/lib/safira/contest/redeem.ex +++ b/lib/safira/contest/redeem.ex @@ -14,6 +14,8 @@ defmodule Safira.Contest.Redeem do alias Safira.Contest.Badge schema "redeems" do + field(:spotlighted, :boolean, default: false) + belongs_to(:attendee, Attendee, foreign_key: :attendee_id, type: :binary_id) belongs_to(:staff, Staff) belongs_to(:badge, Badge) @@ -24,7 +26,7 @@ defmodule Safira.Contest.Redeem do @doc false def changeset(redeem, attrs, user_type \\ :staff) do redeem - |> cast(attrs, [:attendee_id, :staff_id, :badge_id]) + |> cast(attrs, [:spotlighted, :attendee_id, :staff_id, :badge_id]) |> foreign_key_constraint(:attendee_id) |> foreign_key_constraint(:staff_id) |> validate_required([:attendee_id, :badge_id]) diff --git a/lib/safira/jobs/spotlight_badge.ex b/lib/safira/jobs/spotlight_badge.ex new file mode 100644 index 00000000..3ea89424 --- /dev/null +++ b/lib/safira/jobs/spotlight_badge.ex @@ -0,0 +1,40 @@ +defmodule Safira.Jobs.SpotlightBadge do + @moduledoc """ + Job to gift the Spotlight badge to all eligible attendees. + Eligible attendees are those that have redeemed a spotlighted badge. + + Receives the badge_id to gift. + """ + import Ecto.Query, warn: false + + alias Safira.Accounts.Attendee + alias Safira.Contest + alias Safira.Contest.Badge + alias Safira.Repo + + @spec run(integer()) :: :ok + def run(badge_id) do + badge = Repo.get(Badge, badge_id) + + list_eligible_attendees(badge_id) + |> Enum.each(&create_redeem(&1, badge)) + end + + defp list_eligible_attendees(badge_id) do + Attendee + |> join(:inner, [a], r in assoc(a, :redeems)) + |> where([a, r], r.spotlighted == true and r.badge_id != ^badge_id) + |> Repo.all() + end + + defp create_redeem(attendee, badge) do + Contest.create_redeem( + %{ + attendee_id: attendee.id, + staff_id: 1, + badge_id: badge.id + }, + :admin + ) + end +end diff --git a/priv/repo/migrations/20240205215721_add_spotlighted_to_redeems.exs b/priv/repo/migrations/20240205215721_add_spotlighted_to_redeems.exs new file mode 100644 index 00000000..71166049 --- /dev/null +++ b/priv/repo/migrations/20240205215721_add_spotlighted_to_redeems.exs @@ -0,0 +1,9 @@ +defmodule Safira.Repo.Migrations.AddSpotlightedToRedeems do + use Ecto.Migration + + def change do + alter table(:redeems) do + add :spotlighted, :boolean, default: false + end + end +end