mirror of
https://github.com/ClaperCo/Claper.git
synced 2025-12-15 19:37:53 +01:00
268 lines
6.1 KiB
Elixir
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
|