Files
Claper/lib/claper/events.ex
2022-07-23 01:44:03 +02:00

268 lines
6.1 KiB
Elixir

defmodule Claper.Events do
@moduledoc """
The Events context.
"""
import Ecto.Query, warn: false
alias Claper.Repo
alias Claper.Events.{Event, ActivityLeader}
@doc """
Returns the list of events.
## Examples
iex> list_events()
[%Event{}, ...]
"""
def list_events(user_id, preload \\ []) do
from(e in Event, where: e.user_id == ^user_id, order_by: [desc: e.expired_at])
|> Repo.all()
|> Repo.preload(preload)
end
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],
select: e
)
|> Repo.all()
|> Repo.preload(preload)
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,
order_by: [desc: e.id]
)
|> Repo.aggregate(:count, :id)
end
@doc """
Gets a single event.
Raises `Ecto.NoResultsError` if the Event does not exist.
## Examples
iex> get_event!(123)
%Event{}
iex> get_event!(456)
** (Ecto.NoResultsError)
"""
def get_event!(id, preload \\ []),
do: Repo.get_by!(Event, uuid: id) |> Repo.preload(preload)
def get_managed_event!(current_user, id, preload \\ []) do
event = Repo.get_by!(Event, uuid: id)
is_leader = Claper.Events.is_leaded_by(current_user.email, event) || event.user_id == current_user.id
if is_leader do
event |> Repo.preload(preload)
else
raise Ecto.NoResultsError
end
end
def get_user_event!(user_id, id, preload \\ []),
do: Repo.get_by!(Event, uuid: id, user_id: user_id) |> Repo.preload(preload)
def get_event_with_code!(code, preload \\ []) do
now = NaiveDateTime.utc_now()
from(e in Event, where: e.code == ^code and 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 e.expired_at > ^now)
|> Repo.one()
|> Repo.preload(preload)
end
def get_different_event_with_code(nil, _event_id), do: nil
def 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
def is_leaded_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,
order_by: [desc: e.expired_at]
)
|> 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
@doc """
Updates a 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 """
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 """
Returns the list of activity_leaders.
## Examples
iex> list_activity_leaders()
[%ActivityLeader{}, ...]
"""
def list_activity_leaders do
Repo.all(ActivityLeader)
end
@doc """
Gets a single activity_leader.
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)
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 activity_leader 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
end