Add anonymous and remote participations
This commit is contained in:
@@ -17,6 +17,7 @@ defmodule Mobilizon.Events.EventOptions do
|
||||
maximum_attendee_capacity: integer,
|
||||
remaining_attendee_capacity: integer,
|
||||
show_remaining_attendee_capacity: boolean,
|
||||
anonymous_participation: boolean,
|
||||
attendees: [String.t()],
|
||||
program: String.t(),
|
||||
comment_moderation: CommentModeration.t(),
|
||||
@@ -31,6 +32,7 @@ defmodule Mobilizon.Events.EventOptions do
|
||||
:maximum_attendee_capacity,
|
||||
:remaining_attendee_capacity,
|
||||
:show_remaining_attendee_capacity,
|
||||
:anonymous_participation,
|
||||
:attendees,
|
||||
:program,
|
||||
:comment_moderation,
|
||||
@@ -45,6 +47,7 @@ defmodule Mobilizon.Events.EventOptions do
|
||||
field(:maximum_attendee_capacity, :integer)
|
||||
field(:remaining_attendee_capacity, :integer)
|
||||
field(:show_remaining_attendee_capacity, :boolean)
|
||||
field(:anonymous_participation, :boolean)
|
||||
field(:attendees, {:array, :string})
|
||||
field(:program, :string)
|
||||
field(:comment_moderation, CommentModeration)
|
||||
|
||||
@@ -8,6 +8,7 @@ defmodule Mobilizon.Events.EventParticipantStats do
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
not_approved: integer(),
|
||||
not_confirmed: integer(),
|
||||
rejected: integer(),
|
||||
participant: integer(),
|
||||
moderator: integer(),
|
||||
@@ -17,6 +18,7 @@ defmodule Mobilizon.Events.EventParticipantStats do
|
||||
|
||||
@attrs [
|
||||
:not_approved,
|
||||
:not_confirmed,
|
||||
:rejected,
|
||||
:participant,
|
||||
:moderator,
|
||||
@@ -29,6 +31,7 @@ defmodule Mobilizon.Events.EventParticipantStats do
|
||||
@derive Jason.Encoder
|
||||
embedded_schema do
|
||||
field(:not_approved, :integer, default: 0)
|
||||
field(:not_confirmed, :integer, default: 0)
|
||||
field(:rejected, :integer, default: 0)
|
||||
field(:participant, :integer, default: 0)
|
||||
field(:moderator, :integer, default: 0)
|
||||
@@ -47,6 +50,7 @@ defmodule Mobilizon.Events.EventParticipantStats do
|
||||
defp validate_stats(%Ecto.Changeset{} = changeset) do
|
||||
changeset
|
||||
|> validate_number(:not_approved, greater_than_or_equal_to: 0)
|
||||
|> validate_number(:not_confirmed, greater_than_or_equal_to: 0)
|
||||
|> validate_number(:rejected, greater_than_or_equal_to: 0)
|
||||
|> validate_number(:participant, greater_than_or_equal_to: 0)
|
||||
|> validate_number(:moderator, greater_than_or_equal_to: 0)
|
||||
|
||||
@@ -76,6 +76,7 @@ defmodule Mobilizon.Events do
|
||||
|
||||
defenum(ParticipantRole, :participant_role, [
|
||||
:not_approved,
|
||||
:not_confirmed,
|
||||
:rejected,
|
||||
:participant,
|
||||
:moderator,
|
||||
@@ -661,9 +662,39 @@ defmodule Mobilizon.Events do
|
||||
@doc """
|
||||
Gets a single participation for an event and actor.
|
||||
"""
|
||||
@spec get_participant(integer | String.t(), integer | String.t()) ::
|
||||
@spec get_participant(integer | String.t(), integer | String.t(), map()) ::
|
||||
{:ok, Participant.t()} | {:error, :participant_not_found}
|
||||
def get_participant(event_id, actor_id) do
|
||||
def get_participant(event_id, actor_id, params \\ %{})
|
||||
|
||||
# This one if to check someone doesn't go to the same event twice
|
||||
def get_participant(event_id, actor_id, %{email: email}) do
|
||||
case Participant
|
||||
|> where([p], event_id: ^event_id, actor_id: ^actor_id)
|
||||
|> where([p], fragment("? ->>'email' = ?", p.metadata, ^email))
|
||||
|> Repo.one() do
|
||||
%Participant{} = participant ->
|
||||
{:ok, participant}
|
||||
|
||||
nil ->
|
||||
{:error, :participant_not_found}
|
||||
end
|
||||
end
|
||||
|
||||
# This one if for finding participants by their cancellation token when wanting to cancel a participation
|
||||
def get_participant(event_id, actor_id, %{cancellation_token: cancellation_token}) do
|
||||
case Participant
|
||||
|> where([p], event_id: ^event_id, actor_id: ^actor_id)
|
||||
|> where([p], fragment("? ->>'cancellation_token' = ?", p.metadata, ^cancellation_token))
|
||||
|> Repo.one() do
|
||||
%Participant{} = participant ->
|
||||
{:ok, participant}
|
||||
|
||||
nil ->
|
||||
{:error, :participant_not_found}
|
||||
end
|
||||
end
|
||||
|
||||
def get_participant(event_id, actor_id, %{}) do
|
||||
case Repo.get_by(Participant, event_id: event_id, actor_id: actor_id) do
|
||||
%Participant{} = participant ->
|
||||
{:ok, participant}
|
||||
@@ -673,6 +704,14 @@ defmodule Mobilizon.Events do
|
||||
end
|
||||
end
|
||||
|
||||
@spec get_participant_by_confirmation_token(String.t()) :: Participant.t()
|
||||
def get_participant_by_confirmation_token(confirmation_token) do
|
||||
Participant
|
||||
|> where([p], fragment("? ->>'confirmation_token' = ?", p.metadata, ^confirmation_token))
|
||||
|> preload([p], [:actor, :event])
|
||||
|> Repo.one()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a single participation for an event and actor.
|
||||
|
||||
@@ -706,7 +745,7 @@ defmodule Mobilizon.Events do
|
||||
|
||||
@doc """
|
||||
Returns the list of participants for an event.
|
||||
Default behaviour is to not return :not_approved participants
|
||||
Default behaviour is to not return :not_approved or :not_confirmed participants
|
||||
"""
|
||||
@spec list_participants_for_event(String.t(), list(atom()), integer | nil, integer | nil) ::
|
||||
[Participant.t()]
|
||||
|
||||
@@ -10,6 +10,7 @@ defmodule Mobilizon.Events.Participant do
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Events
|
||||
alias Mobilizon.Events.{Event, ParticipantRole}
|
||||
alias Mobilizon.Web.Email.Checker
|
||||
|
||||
alias Mobilizon.Web.Endpoint
|
||||
|
||||
@@ -28,6 +29,12 @@ defmodule Mobilizon.Events.Participant do
|
||||
field(:role, ParticipantRole, default: :participant)
|
||||
field(:url, :string)
|
||||
|
||||
embeds_one :metadata, Metadata, on_replace: :delete do
|
||||
field(:email, :string)
|
||||
field(:confirmation_token, :string)
|
||||
field(:cancellation_token, :string)
|
||||
end
|
||||
|
||||
belongs_to(:event, Event, primary_key: true)
|
||||
belongs_to(:actor, Actor, primary_key: true)
|
||||
|
||||
@@ -55,11 +62,18 @@ defmodule Mobilizon.Events.Participant do
|
||||
def changeset(%__MODULE__{} = participant, attrs) do
|
||||
participant
|
||||
|> cast(attrs, @attrs)
|
||||
|> cast_embed(:metadata, with: &metadata_changeset/2)
|
||||
|> ensure_url()
|
||||
|> validate_required(@required_attrs)
|
||||
|> unique_constraint(:actor_id, name: :participants_event_id_actor_id_index)
|
||||
end
|
||||
|
||||
defp metadata_changeset(schema, params) do
|
||||
schema
|
||||
|> cast(params, [:email, :confirmation_token, :cancellation_token])
|
||||
|> Checker.validate_changeset()
|
||||
end
|
||||
|
||||
# If there's a blank URL that's because we're doing the first insert
|
||||
@spec ensure_url(Ecto.Changeset.t()) :: Ecto.Changeset.t()
|
||||
defp ensure_url(%Ecto.Changeset{data: %__MODULE__{url: nil}} = changeset) do
|
||||
|
||||
Reference in New Issue
Block a user