mirror of
https://github.com/ClaperCo/Claper.git
synced 2026-02-24 20:19:48 +01:00
839 lines
22 KiB
Elixir
839 lines
22 KiB
Elixir
defmodule Claper.Events do
|
|
@moduledoc """
|
|
The Events context.
|
|
|
|
An activity leader is a facilitator, a user invited to manage an event.
|
|
"""
|
|
|
|
import Ecto.Query, warn: false
|
|
alias Claper.Repo
|
|
|
|
alias Claper.Accounts.User
|
|
alias Claper.Events.{Event, ActivityLeader}
|
|
alias Claper.Presentations
|
|
|
|
@default_page_size 5
|
|
|
|
@doc """
|
|
Returns the list of events of a given user.
|
|
|
|
## Examples
|
|
|
|
iex> list_events(123)
|
|
[%Event{}, ...]
|
|
|
|
"""
|
|
def list_events(user_id, preload \\ []) do
|
|
from(e in Event, where: e.user_id == ^user_id, order_by: [desc: e.id])
|
|
|> Repo.all()
|
|
|> Repo.preload(preload)
|
|
end
|
|
|
|
@doc """
|
|
Returns a paginated list of events for a given user.
|
|
|
|
## Examples
|
|
|
|
iex> paginate_events(123, %{page: 1, page_size: 10})
|
|
{[%Event{}, ...], total_count, total_pages}
|
|
|
|
"""
|
|
def paginate_events(user_id, params \\ %{}, preload \\ []) do
|
|
page = Map.get(params, "page", 1)
|
|
page_size = Map.get(params, "page_size", @default_page_size)
|
|
|
|
query =
|
|
from(e in Event,
|
|
where: e.user_id == ^user_id,
|
|
order_by: [desc: e.id]
|
|
)
|
|
|
|
Repo.paginate(query, page: page, page_size: page_size, preload: preload)
|
|
end
|
|
|
|
@doc """
|
|
Returns the list of not expired events for a given user.
|
|
|
|
## Examples
|
|
|
|
iex> list_not_expired_events(123)
|
|
[%Event{}, ...]
|
|
|
|
"""
|
|
def list_not_expired_events(user_id, preload \\ []) do
|
|
from(e in Event,
|
|
where: e.user_id == ^user_id and is_nil(e.expired_at),
|
|
order_by: [desc: e.id]
|
|
)
|
|
|> Repo.all()
|
|
|> Repo.preload(preload)
|
|
end
|
|
|
|
@doc """
|
|
Returns a paginated list of not expired events for a given user.
|
|
|
|
## Examples
|
|
|
|
iex> paginate_not_expired_events(123, %{page: 1, page_size: 10})
|
|
{[%Event{}, ...], total_count, total_pages}
|
|
|
|
"""
|
|
def paginate_not_expired_events(user_id, params \\ %{}, preload \\ []) do
|
|
page = Map.get(params, "page", 1)
|
|
page_size = Map.get(params, "page_size", @default_page_size)
|
|
|
|
query =
|
|
from(e in Event,
|
|
where: e.user_id == ^user_id and is_nil(e.expired_at),
|
|
order_by: [desc: e.id]
|
|
)
|
|
|
|
Repo.paginate(query, page: page, page_size: page_size, preload: preload)
|
|
end
|
|
|
|
@doc """
|
|
Returns the list of expired events for a given user.
|
|
|
|
## Examples
|
|
|
|
iex> list_expired_events(123)
|
|
[%Event{}, ...]
|
|
|
|
"""
|
|
def list_expired_events(user_id, preload \\ []) do
|
|
from(e in Event,
|
|
where: e.user_id == ^user_id and not is_nil(e.expired_at),
|
|
order_by: [desc: e.expired_at]
|
|
)
|
|
|> Repo.all()
|
|
|> Repo.preload(preload)
|
|
end
|
|
|
|
@doc """
|
|
Returns a paginated list of expired events for a given user.
|
|
|
|
## Examples
|
|
|
|
iex> paginate_expired_events(123, %{page: 1, page_size: 10})
|
|
{[%Event{}, ...], total_count, total_pages}
|
|
|
|
"""
|
|
def paginate_expired_events(user_id, params \\ %{}, preload \\ []) do
|
|
page = Map.get(params, "page", 1)
|
|
page_size = Map.get(params, "page_size", @default_page_size)
|
|
|
|
query =
|
|
from(e in Event,
|
|
where: e.user_id == ^user_id and not is_nil(e.expired_at),
|
|
order_by: [desc: e.expired_at]
|
|
)
|
|
|
|
Repo.paginate(query, page: page, page_size: page_size, preload: preload)
|
|
end
|
|
|
|
@doc """
|
|
Returns the list of events managed by a given user email.
|
|
|
|
## Examples
|
|
|
|
iex> list_managed_events_by("email@example.com")
|
|
[%Event{}, ...]
|
|
|
|
"""
|
|
def list_managed_events_by(email, preload \\ []) do
|
|
from(a in ActivityLeader,
|
|
join: u in Claper.Accounts.User,
|
|
on: u.email == a.email,
|
|
join: e in Event,
|
|
on: e.id == a.event_id,
|
|
where: a.email == ^email,
|
|
order_by: [desc: e.expired_at, desc: e.id],
|
|
select: e
|
|
)
|
|
|> Repo.all()
|
|
|> Repo.preload(preload)
|
|
end
|
|
|
|
@doc """
|
|
Returns a paginated list of events managed by a given user email.
|
|
|
|
## Examples
|
|
|
|
iex> paginate_managed_events_by("email@example.com", %{page: 1, page_size: 10})
|
|
{[%Event{}, ...], total_count, total_pages}
|
|
|
|
"""
|
|
def paginate_managed_events_by(email, params \\ %{}, preload \\ []) do
|
|
page = Map.get(params, "page", 1)
|
|
page_size = Map.get(params, "page_size", @default_page_size)
|
|
|
|
query =
|
|
from(a in ActivityLeader,
|
|
join: u in Claper.Accounts.User,
|
|
on: u.email == a.email,
|
|
join: e in Event,
|
|
on: e.id == a.event_id,
|
|
where: a.email == ^email,
|
|
order_by: [desc: e.expired_at, desc: e.id],
|
|
select: e
|
|
)
|
|
|
|
Repo.paginate(query, page: page, page_size: page_size, preload: preload)
|
|
end
|
|
|
|
def count_managed_events_by(email) do
|
|
from(a in ActivityLeader,
|
|
join: u in Claper.Accounts.User,
|
|
on: u.email == a.email,
|
|
join: e in Event,
|
|
on: e.id == a.event_id,
|
|
where: a.email == ^email,
|
|
select: e
|
|
)
|
|
|> Repo.aggregate(:count, :id)
|
|
end
|
|
|
|
def count_expired_events(user_id) do
|
|
from(e in Event,
|
|
where: e.user_id == ^user_id and not is_nil(e.expired_at)
|
|
)
|
|
|> Repo.aggregate(:count, :id)
|
|
end
|
|
|
|
def count_events_month(user_id) do
|
|
# minus 30 days, calculated as seconds
|
|
seconds = -30 * 24 * 3600
|
|
last_month = DateTime.utc_now() |> DateTime.add(seconds, :second)
|
|
|
|
from(e in Event,
|
|
where:
|
|
e.user_id == ^user_id and e.inserted_at <= ^DateTime.utc_now() and
|
|
e.inserted_at >= ^last_month
|
|
)
|
|
|> Repo.aggregate(:count, :id)
|
|
end
|
|
|
|
@doc """
|
|
Gets a single event by serial ID or UUID.
|
|
|
|
Raises `Ecto.NoResultsError` if the Event does not exist.
|
|
|
|
## Examples
|
|
|
|
iex> get_event!(123)
|
|
%Event{}
|
|
|
|
iex> get_event!("123e4567-e89b-12d3-a456-426614174000")
|
|
%Event{}
|
|
|
|
iex> get_event!(456)
|
|
** (Ecto.NoResultsError)
|
|
|
|
iex> get_event!("123e4567-e89b-12d3-a456-4266141740111")
|
|
** (Ecto.NoResultsError)
|
|
|
|
"""
|
|
def get_event!(id_or_uuid, preload \\ [])
|
|
|
|
def get_event!(
|
|
<<_::bytes-8, "-", _::bytes-4, "-", _::bytes-4, "-", _::bytes-4, "-", _::bytes-12>> =
|
|
uuid,
|
|
preload
|
|
),
|
|
do: Repo.get_by!(Event, uuid: uuid) |> Repo.preload(preload)
|
|
|
|
def get_event!(id, preload),
|
|
do: Repo.get!(Event, id) |> Repo.preload(preload)
|
|
|
|
@doc """
|
|
Gets a single managed event.
|
|
|
|
Raises `Ecto.NoResultsError` if the Event does not exist.
|
|
|
|
## Examples
|
|
|
|
iex> get_managed_event!(user, "123e4567-e89b-12d3-a456-426614174000")
|
|
%Event{}
|
|
|
|
iex> get_managed_event!(another_user, "123e4567-e89b-12d3-a456-426614174000")
|
|
** (Ecto.NoResultsError)
|
|
|
|
"""
|
|
def get_managed_event!(user, uuid, preload \\ []) do
|
|
from(
|
|
a in ActivityLeader,
|
|
join: e in Event,
|
|
on: e.id == a.event_id,
|
|
join: u in User,
|
|
on: e.user_id == u.id,
|
|
where: e.uuid == ^uuid and (u.id == ^user.id or a.email == ^user.email),
|
|
select: e
|
|
)
|
|
|> Repo.one!()
|
|
|> Repo.preload(preload)
|
|
end
|
|
|
|
@doc """
|
|
Gets a single user's event.
|
|
|
|
Raises `Ecto.NoResultsError` if the Event does not exist.
|
|
|
|
## Examples
|
|
|
|
iex> get_user_event!(user, "123e4567-e89b-12d3-a456-426614174000")
|
|
%Event{}
|
|
|
|
iex> get_user_event!(another_user, "123e4567-e89b-12d3-a456-426614174000")
|
|
** (Ecto.NoResultsError)
|
|
|
|
"""
|
|
def get_user_event!(user_id, id, preload \\ []),
|
|
do: Repo.get_by!(Event, uuid: id, user_id: user_id) |> Repo.preload(preload)
|
|
|
|
@doc """
|
|
Gets a single event by code.
|
|
|
|
Raises `Ecto.NoResultsError` if the Event does not exist.
|
|
|
|
## Examples
|
|
|
|
iex> get_event_with_code!("Hello")
|
|
%Event{}
|
|
|
|
iex> get_event_with_code!("Old event")
|
|
** (Ecto.NoResultsError)
|
|
|
|
"""
|
|
def get_event_with_code!(code, preload \\ []) do
|
|
now = NaiveDateTime.utc_now()
|
|
|
|
from(e in Event, where: e.code == ^code and (is_nil(e.expired_at) or e.expired_at > ^now))
|
|
|> Repo.one!()
|
|
|> Repo.preload(preload)
|
|
end
|
|
|
|
def get_event_with_code(code, preload \\ []) do
|
|
now = DateTime.utc_now()
|
|
|
|
from(e in Event, where: e.code == ^code and (is_nil(e.expired_at) or e.expired_at > ^now))
|
|
|> Repo.one()
|
|
|> Repo.preload(preload)
|
|
end
|
|
|
|
@doc """
|
|
Check if a user is a facilitator of a specific event.
|
|
|
|
## Examples
|
|
|
|
iex> led_by?("email@example.com", 123)
|
|
true
|
|
|
|
"""
|
|
def led_by?(email, event) do
|
|
from(a in ActivityLeader,
|
|
join: u in Claper.Accounts.User,
|
|
on: u.email == a.email,
|
|
join: e in Event,
|
|
on: e.id == a.event_id,
|
|
where: a.email == ^email and e.id == ^event.id
|
|
)
|
|
|> Repo.exists?()
|
|
end
|
|
|
|
@doc """
|
|
Creates a event.
|
|
|
|
## Examples
|
|
|
|
iex> create_event(%{field: value})
|
|
{:ok, %Event{}}
|
|
|
|
iex> create_event(%{field: bad_value})
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def create_event(attrs) do
|
|
%Event{}
|
|
|> Event.create_changeset(attrs)
|
|
|> validate_unique_event()
|
|
|> case do
|
|
{:ok, event} ->
|
|
Repo.insert(event, returning: [:uuid])
|
|
|
|
{:error, changeset} ->
|
|
{:error, %{changeset | action: :insert}}
|
|
end
|
|
end
|
|
|
|
defp validate_unique_event(%Ecto.Changeset{changes: %{code: code} = _changes} = event) do
|
|
case get_event_with_code(code) do
|
|
%Event{} -> {:error, Ecto.Changeset.add_error(event, :code, "Already exists")}
|
|
nil -> {:ok, event}
|
|
end
|
|
end
|
|
|
|
defp validate_unique_event(%Ecto.Changeset{data: event} = changeset) do
|
|
case get_different_event_with_code(event.code, event.id) do
|
|
%Event{} -> {:error, Ecto.Changeset.add_error(changeset, :code, "Already exists")}
|
|
nil -> {:ok, changeset}
|
|
end
|
|
end
|
|
|
|
defp get_different_event_with_code(nil, _event_id), do: nil
|
|
|
|
defp get_different_event_with_code(code, event_id) do
|
|
now = DateTime.utc_now()
|
|
|
|
from(e in Event, where: e.code == ^code and e.id != ^event_id and e.expired_at > ^now)
|
|
|> Repo.one()
|
|
end
|
|
|
|
@doc """
|
|
Updates an event.
|
|
|
|
## Examples
|
|
|
|
iex> update_event(event, %{field: new_value})
|
|
{:ok, %Event{}}
|
|
|
|
iex> update_event(event, %{field: bad_value})
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def update_event(%Event{} = event, attrs) do
|
|
event
|
|
|> Event.update_changeset(attrs)
|
|
|> validate_unique_event()
|
|
|> case do
|
|
{:ok, event} ->
|
|
Repo.update(event, returning: [:uuid])
|
|
|
|
{:error, changeset} ->
|
|
{:error, %{changeset | action: :update}}
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Terminates an event.
|
|
|
|
## Examples
|
|
|
|
iex> terminate_event(event)
|
|
{:ok, %Event{}}
|
|
|
|
"""
|
|
def terminate_event(%Event{} = event) do
|
|
event
|
|
|> Event.update_changeset(%{expired_at: NaiveDateTime.utc_now()})
|
|
|> Repo.update()
|
|
|> case do
|
|
{:ok, event} ->
|
|
broadcast({:ok, event, event.uuid}, :event_terminated)
|
|
|
|
{:error, changeset} ->
|
|
{:error, %{changeset | action: :update}}
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Import interactions from another event
|
|
|
|
## Examples
|
|
|
|
iex> import(user_id, from_event_uuid, to_event_uuid)
|
|
{:ok, %Event{}}
|
|
|
|
iex> import(user_id, from_event_uuid, to_event_uuid)
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def import(user_id, from_event_uuid, to_event_uuid) do
|
|
case Ecto.Multi.new()
|
|
|> Ecto.Multi.run(:from_event, fn _repo, _changes ->
|
|
{:ok,
|
|
get_user_event!(user_id, from_event_uuid,
|
|
presentation_file: [polls: [:poll_opts], forms: [], embeds: []]
|
|
)}
|
|
end)
|
|
|> Ecto.Multi.run(:to_event, fn _repo, _changes ->
|
|
{:ok,
|
|
get_user_event!(user_id, to_event_uuid, presentation_file: [:polls, :forms, :embeds])}
|
|
end)
|
|
|> Ecto.Multi.run(:polls, fn _repo, %{from_event: from_event, to_event: to_event} ->
|
|
{:ok,
|
|
from_event.presentation_file.polls
|
|
|> Enum.each(fn poll ->
|
|
if poll.position < to_event.presentation_file.length do
|
|
Claper.Polls.create_poll(%{
|
|
title: poll.title,
|
|
position: poll.position,
|
|
enabled: poll.enabled,
|
|
multiple: poll.multiple,
|
|
poll_opts:
|
|
Enum.map(poll.poll_opts, fn opt ->
|
|
%{content: opt.content, vote_count: 0}
|
|
end),
|
|
presentation_file_id: to_event.presentation_file.id
|
|
})
|
|
end
|
|
end)}
|
|
end)
|
|
|> Ecto.Multi.run(:forms, fn _repo, %{from_event: from_event, to_event: to_event} ->
|
|
{:ok,
|
|
from_event.presentation_file.forms
|
|
|> Enum.each(fn form ->
|
|
if form.position < to_event.presentation_file.length do
|
|
Claper.Forms.create_form(%{
|
|
title: form.title,
|
|
position: form.position,
|
|
enabled: form.enabled,
|
|
fields:
|
|
Enum.map(form.fields, fn field ->
|
|
%{
|
|
name: field.name,
|
|
type: field.type
|
|
}
|
|
end),
|
|
presentation_file_id: to_event.presentation_file.id
|
|
})
|
|
end
|
|
end)}
|
|
end)
|
|
|> Ecto.Multi.run(:embeds, fn _repo, %{from_event: from_event, to_event: to_event} ->
|
|
{:ok,
|
|
from_event.presentation_file.embeds
|
|
|> Enum.each(fn embed ->
|
|
if embed.position < to_event.presentation_file.length do
|
|
Claper.Embeds.create_embed(%{
|
|
title: embed.title,
|
|
content: embed.content,
|
|
position: embed.position,
|
|
enabled: embed.enabled,
|
|
attendee_visibility: embed.attendee_visibility,
|
|
presentation_file_id: to_event.presentation_file.id
|
|
})
|
|
end
|
|
end)}
|
|
end)
|
|
|> Repo.transaction() do
|
|
{:ok, %{to_event: to_event}} -> {:ok, to_event}
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Duplicates an event.
|
|
|
|
Raises `Ecto.NoResultsError` for invalid `user_id`-`event_uuid` combinations
|
|
and returns an error tuple if any part of the transaction fails.
|
|
|
|
## Examples
|
|
|
|
iex> duplicate(user_id, event_uuid)
|
|
{:ok, %Event{}}
|
|
|
|
iex> duplicate(user_id, event_uuid)
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
iex> duplicate(another_user_id, event_uuid)
|
|
** (Ecto.NoResultsError)
|
|
|
|
"""
|
|
def duplicate_event(user_id, event_uuid) do
|
|
original =
|
|
get_user_event!(user_id, event_uuid,
|
|
presentation_file: [
|
|
presentation_state: [],
|
|
polls: [:poll_opts],
|
|
forms: [],
|
|
embeds: [],
|
|
quizzes: [quiz_questions: [:quiz_question_opts]]
|
|
]
|
|
)
|
|
|
|
multi =
|
|
Ecto.Multi.new()
|
|
|> Ecto.Multi.run(:event, fn _repo, changes -> duplicate_event_attrs(original, changes) end)
|
|
|> Ecto.Multi.run(:presentation_file, fn _repo, changes ->
|
|
duplicate_presentation_file(original, changes)
|
|
end)
|
|
|> Ecto.Multi.run(:presentation_state, fn _repo, changes ->
|
|
duplicate_presentation_state(original, changes)
|
|
end)
|
|
|> Ecto.Multi.run(:polls, fn _repo, changes -> duplicate_polls(original, changes) end)
|
|
|> Ecto.Multi.run(:forms, fn _repo, changes -> duplicate_forms(original, changes) end)
|
|
|> Ecto.Multi.run(:embeds, fn _repo, changes -> duplicate_embeds(original, changes) end)
|
|
|> Ecto.Multi.run(:quizzes, fn _repo, changes -> duplicate_quizzes(original, changes) end)
|
|
|
|
case Repo.transaction(multi) do
|
|
{:ok, %{event: event}} -> {:ok, event}
|
|
{:error, _operation, value, _changes} -> {:error, value}
|
|
end
|
|
end
|
|
|
|
defp duplicate_event_attrs(original, _changes) do
|
|
code =
|
|
for _ <- 1..5,
|
|
into: "",
|
|
do: <<Enum.random(~c"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")>>
|
|
|
|
attrs =
|
|
Map.from_struct(original)
|
|
|> Map.drop([:id, :inserted_at, :updated_at, :presentation_file, :expired_at])
|
|
|> Map.put(:leaders, [])
|
|
|> Map.put(:code, "#{code}")
|
|
|> Map.put(:name, "#{original.name} (Copy)")
|
|
|
|
create_event(attrs)
|
|
end
|
|
|
|
defp duplicate_presentation_file(original, changes) do
|
|
case get_in(original.presentation_file) do
|
|
%Presentations.PresentationFile{} = presentation_file ->
|
|
attrs =
|
|
Map.from_struct(presentation_file)
|
|
|> Map.drop([:id, :inserted_at, :updated_at, :presentation_state])
|
|
|> Map.put(:event_id, changes.event.id)
|
|
|
|
Claper.Presentations.create_presentation_file(attrs)
|
|
|
|
_ ->
|
|
{:ok, nil}
|
|
end
|
|
end
|
|
|
|
defp duplicate_presentation_state(original, changes) do
|
|
case get_in(original.presentation_file.presentation_state) do
|
|
%Presentations.PresentationState{} = presentation_state ->
|
|
attrs =
|
|
Map.from_struct(presentation_state)
|
|
|> Map.drop([:id, :inserted_at, :updated_at])
|
|
|> Map.put(:presentation_file_id, changes.presentation_file.id)
|
|
|> Map.put(:position, 0)
|
|
|> Map.put(:banned, [])
|
|
|
|
Claper.Presentations.create_presentation_state(attrs)
|
|
|
|
_ ->
|
|
{:ok, nil}
|
|
end
|
|
end
|
|
|
|
defp duplicate_polls(original, changes) do
|
|
case get_in(original.presentation_file.polls) do
|
|
polls when is_list(polls) ->
|
|
polls =
|
|
for poll <- polls do
|
|
attrs =
|
|
Map.from_struct(poll)
|
|
|> Map.drop([:id, :inserted_at, :updated_at])
|
|
|> Map.put(:presentation_file_id, changes.presentation_file.id)
|
|
|> Map.put(
|
|
:poll_opts,
|
|
Enum.map(poll.poll_opts, fn opt ->
|
|
Map.from_struct(opt)
|
|
|> Map.drop([:id, :inserted_at, :updated_at, :vote_count])
|
|
end)
|
|
)
|
|
|
|
{:ok, poll} = Claper.Polls.create_poll(attrs)
|
|
poll
|
|
end
|
|
|
|
{:ok, polls}
|
|
|
|
_ ->
|
|
{:ok, nil}
|
|
end
|
|
end
|
|
|
|
defp duplicate_forms(original, changes) do
|
|
case get_in(original.presentation_file.forms) do
|
|
forms when is_list(forms) ->
|
|
forms =
|
|
for form <- forms do
|
|
attrs =
|
|
Map.from_struct(form)
|
|
|> Map.drop([:id, :inserted_at, :updated_at])
|
|
|> Map.put(:presentation_file_id, changes.presentation_file.id)
|
|
|> Map.put(
|
|
:fields,
|
|
Enum.map(form.fields, &Map.from_struct(&1))
|
|
)
|
|
|
|
{:ok, form} = Claper.Forms.create_form(attrs)
|
|
form
|
|
end
|
|
|
|
{:ok, forms}
|
|
|
|
_ ->
|
|
{:ok, nil}
|
|
end
|
|
end
|
|
|
|
defp duplicate_embeds(original, changes) do
|
|
case get_in(original.presentation_file.embeds) do
|
|
embeds when is_list(embeds) ->
|
|
embeds =
|
|
for embed <- embeds do
|
|
attrs =
|
|
Map.from_struct(embed)
|
|
|> Map.drop([:id, :inserted_at, :updated_at])
|
|
|> Map.put(:presentation_file_id, changes.presentation_file.id)
|
|
|
|
{:ok, embed} = Claper.Embeds.create_embed(attrs)
|
|
embed
|
|
end
|
|
|
|
{:ok, embeds}
|
|
|
|
_ ->
|
|
{:ok, nil}
|
|
end
|
|
end
|
|
|
|
defp duplicate_quizzes(original, changes) do
|
|
case get_in(original.presentation_file.quizzes) do
|
|
quizzes when is_list(quizzes) ->
|
|
quizzes =
|
|
for quiz <- quizzes do
|
|
attrs =
|
|
Map.from_struct(quiz)
|
|
|> Map.drop([:id, :inserted_at, :updated_at])
|
|
|> Map.put(:presentation_file_id, changes.presentation_file.id)
|
|
|> Map.put(:quiz_questions, Enum.map(quiz.quiz_questions, &map_quiz_question/1))
|
|
|
|
{:ok, quiz} = Claper.Quizzes.create_quiz(attrs)
|
|
quiz
|
|
end
|
|
|
|
{:ok, quizzes}
|
|
|
|
_ ->
|
|
{:ok, nil}
|
|
end
|
|
end
|
|
|
|
defp map_quiz_question(question) do
|
|
Map.from_struct(question)
|
|
|> Map.drop([:id, :inserted_at, :updated_at])
|
|
|> Map.put(
|
|
:quiz_question_opts,
|
|
Enum.map(question.quiz_question_opts, &map_quiz_question_opt/1)
|
|
)
|
|
end
|
|
|
|
defp map_quiz_question_opt(opt) do
|
|
Map.from_struct(opt)
|
|
|> Map.drop([:id, :inserted_at, :updated_at])
|
|
|> Map.put(:response_count, 0)
|
|
end
|
|
|
|
@doc """
|
|
Deletes a event.
|
|
|
|
## Examples
|
|
|
|
iex> delete_event(event)
|
|
{:ok, %Event{}}
|
|
|
|
iex> delete_event(event)
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def delete_event(%Event{} = event) do
|
|
Repo.delete(event)
|
|
end
|
|
|
|
@doc """
|
|
Returns an `%Ecto.Changeset{}` for tracking event changes.
|
|
|
|
## Examples
|
|
|
|
iex> change_event(event)
|
|
%Ecto.Changeset{data: %Event{}}
|
|
|
|
"""
|
|
def change_event(%Event{} = event, attrs \\ %{}) do
|
|
Event.changeset(event, attrs)
|
|
end
|
|
|
|
alias Claper.Events.ActivityLeader
|
|
|
|
@doc """
|
|
Creates a activity leader.
|
|
|
|
## Examples
|
|
|
|
iex> create_activity_leader(%{field: value})
|
|
{:ok, %ActivityLeader{}}
|
|
|
|
iex> create_activity_leader(%{field: bad_value})
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def create_activity_leader(attrs) do
|
|
%ActivityLeader{}
|
|
|> ActivityLeader.changeset(attrs)
|
|
|> Repo.insert()
|
|
end
|
|
|
|
@doc """
|
|
Gets a single facilitator.
|
|
|
|
Raises `Ecto.NoResultsError` if the Activity leader does not exist.
|
|
|
|
## Examples
|
|
|
|
iex> get_activity_leader!(123)
|
|
%ActivityLeader{}
|
|
|
|
iex> get_activity_leader!(456)
|
|
** (Ecto.NoResultsError)
|
|
|
|
"""
|
|
def get_activity_leader!(id), do: Repo.get!(ActivityLeader, id)
|
|
|
|
@doc """
|
|
Gets all facilitators for a given event.
|
|
|
|
## Examples
|
|
|
|
iex> get_activity_leaders_for_event!(event)
|
|
[%ActivityLeader{}, ...]
|
|
|
|
"""
|
|
def get_activity_leaders_for_event(event_id) do
|
|
from(a in ActivityLeader,
|
|
left_join: u in Claper.Accounts.User,
|
|
on: u.email == a.email,
|
|
where: a.event_id == ^event_id,
|
|
select: %{a | user_id: u.id}
|
|
)
|
|
|> Repo.all()
|
|
end
|
|
|
|
@doc """
|
|
Returns an `%Ecto.Changeset{}` for tracking facilitator changes.
|
|
|
|
## Examples
|
|
|
|
iex> change_activity_leader(activity_leader)
|
|
%Ecto.Changeset{data: %ActivityLeader{}}
|
|
|
|
"""
|
|
def change_activity_leader(%ActivityLeader{} = activity_leader, attrs \\ %{}) do
|
|
ActivityLeader.changeset(activity_leader, attrs)
|
|
end
|
|
|
|
defp broadcast({:ok, e, event_uuid}, event) do
|
|
Phoenix.PubSub.broadcast(
|
|
Claper.PubSub,
|
|
"event:#{event_uuid}",
|
|
{event, event_uuid}
|
|
)
|
|
|
|
{:ok, e}
|
|
end
|
|
end
|