641129dc74
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
79 lines
2.2 KiB
Elixir
79 lines
2.2 KiB
Elixir
import EctoEnum
|
|
|
|
defenum(Mobilizon.Events.ParticipantRoleEnum, :participant_role_type, [
|
|
:not_approved,
|
|
:participant,
|
|
:moderator,
|
|
:administrator,
|
|
:creator
|
|
])
|
|
|
|
defmodule Mobilizon.Events.Participant do
|
|
@moduledoc """
|
|
Represents a participant, an actor participating to an event
|
|
"""
|
|
use Ecto.Schema
|
|
import Ecto.Changeset
|
|
alias Mobilizon.Events.{Participant, Event}
|
|
alias Mobilizon.Actors.Actor
|
|
|
|
@primary_key {:id, :binary_id, autogenerate: true}
|
|
schema "participants" do
|
|
field(:role, Mobilizon.Events.ParticipantRoleEnum, default: :participant)
|
|
field(:url, :string)
|
|
belongs_to(:event, Event, primary_key: true)
|
|
belongs_to(:actor, Actor, primary_key: true)
|
|
|
|
timestamps()
|
|
end
|
|
|
|
@doc false
|
|
def changeset(%Participant{} = participant, attrs) do
|
|
participant
|
|
|> Ecto.Changeset.cast(attrs, [:url, :role, :event_id, :actor_id])
|
|
|> generate_url()
|
|
|> validate_required([:url, :role, :event_id, :actor_id])
|
|
end
|
|
|
|
# If there's a blank URL that's because we're doing the first insert
|
|
defp generate_url(%Ecto.Changeset{data: %Participant{url: nil}} = changeset) do
|
|
case fetch_change(changeset, :url) do
|
|
{:ok, _url} -> changeset
|
|
:error -> do_generate_url(changeset)
|
|
end
|
|
end
|
|
|
|
# Most time just go with the given URL
|
|
defp generate_url(%Ecto.Changeset{} = changeset), do: changeset
|
|
|
|
defp do_generate_url(%Ecto.Changeset{} = changeset) do
|
|
uuid = Ecto.UUID.generate()
|
|
|
|
changeset
|
|
|> put_change(
|
|
:url,
|
|
"#{MobilizonWeb.Endpoint.url()}/join/event/#{uuid}"
|
|
)
|
|
|> put_change(
|
|
:id,
|
|
uuid
|
|
)
|
|
end
|
|
|
|
@doc """
|
|
We check that the actor asking to leave the event is not it's only organizer
|
|
We start by fetching the list of organizers and if there's only one of them
|
|
and that it's the actor requesting leaving the event we return true
|
|
"""
|
|
@spec check_that_participant_is_not_only_organizer(integer(), integer()) :: boolean()
|
|
def check_that_participant_is_not_only_organizer(event_id, actor_id) do
|
|
case Mobilizon.Events.list_organizers_participants_for_event(event_id) do
|
|
[%Participant{actor: %Actor{id: participant_actor_id}}] ->
|
|
participant_actor_id == actor_id
|
|
|
|
_ ->
|
|
false
|
|
end
|
|
end
|
|
end
|