Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make it possible to get all the mentors related to an event: went, didn't go #191

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions lib/bokken/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,33 @@ defmodule Bokken.Accounts do
|> Map.fetch!(:mentors)
end

alias Bokken.Events.Lecture

# List all mentors related to an event, including their attendance
def list_mentors(%{"event_id" => event_id}) do
event_id
|> Events.get_event!([:mentors])
|> Map.fetch!(:mentors)
results =
Lecture
|> where([l], l.event_id == ^event_id)
|> join(:inner, [l], m in Mentor, on: m.id == l.mentor_id)
|> select([l, m], %{mentor: m, attendance: l.attendance})
|> Repo.all()

Enum.map(results, fn %{mentor: mentor, attendance: attendance} ->
Map.put(mentor, :attendance, attendance)
end)
end

def list_mentors(%{"event_id" => event_id}, attendances) when is_list(attendances) do
results =
Lecture
|> where([l], l.event_id == ^event_id and l.attendance in ^attendances)
|> join(:inner, [l], m in Mentor, on: m.id == l.mentor_id)
|> select([l, m], %{mentor: m, attendance: l.attendance})
|> Repo.all()

Enum.map(results, fn %{mentor: mentor, attendance: attendance} ->
Map.put(mentor, :attendance, attendance)
end)
end

def list_mentors do
Expand Down
66 changes: 66 additions & 0 deletions lib/bokken/events.ex
Original file line number Diff line number Diff line change
Expand Up @@ -840,4 +840,70 @@ defmodule Bokken.Events do
def change_availability(%Availability{} = availability, attrs \\ %{}) do
Availability.changeset(availability, attrs)
end

@doc """
Lists all the users that can be notified about a new event.

## Examples

iex> list_notifiable_signup_users()
[%User{}, ...]
"""
def list_notifiable_signup_users do
Accounts.list_users()
|> Enum.filter(fn user ->
user.active and user.verified and user.role in [:guardian, :mentor]
end)
Comment on lines +853 to +856
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be part of the query and not filtered in memory 💡

end

@doc """
Lists all the mentors that can be notified, because they have been selected for an event.

## Examples

iex> list_notifiable_selected_mentors(%Event{})
[%Mentor{}, ...]
"""
def list_notifiable_selected_mentors(%Event{} = event) do
Events.list_lectures(%{"event_id" => event.id}, [:mentor, :ninja, :event])
|> Enum.map(fn lecture ->
Accounts.get_user!(lecture.mentor.user_id) |> Map.put(:lecture, lecture)
end)
end

@doc """
Lists all the ninjas that can be notified, because they have been selected for an event.

## Examples

iex> list_notifiable_selected_ninjas(%Event{})
[%Ninja{}, ...]
"""
def list_notifiable_selected_ninjas(%Event{} = event) do
Events.list_lectures(%{"event_id" => event.id}, [:mentor, :ninja, :event])
|> Enum.map(fn lecture ->
Accounts.get_user!(lecture.ninja.guardian_id).user_id |> Map.put(:lecture, lecture)
end)
end

@doc """
Lists all the ninjas that won't be coming to an event.

## Examples

iex> list_not_coming_ninjas(%Event{})
[%Ninja{}, ...]
"""
def list_not_coming_ninjas(%Event{} = event) do
enrollments = list_enrollments(%{"event_id" => event.id})
lectures = list_lectures(%{"event_id" => event.id})

enrollments
|> Enum.filter(fn e ->
e.event_id == event.id and
not Enum.any?(lectures, fn l ->
l.ninja_id == e.ninja_id and l.event_id == e.event_id
end)
end)
end
end
2 changes: 1 addition & 1 deletion lib/bokken/events/lecture.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
defmodule Bokken.Events.Lecture do
@moduledoc """
one on one lecture
Lecture between one or more mentors and a ninja.
"""
use Bokken.Schema

Expand Down
22 changes: 11 additions & 11 deletions lib/bokken_web/controllers/availability_controller.ex
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
defmodule BokkenWeb.AvailabilityController do
use BokkenWeb, controller: "1.6"
use BokkenWeb, :controller

alias Bokken.Events
alias Bokken.Events.Availability

action_fallback BokkenWeb.FallbackController

def show(conn, %{"id" => availability_id}) do
availability = Events.get_availability!(availability_id)
def index(conn, availability_params) do
availabilities = Events.list_availabilities(availability_params)
unavailabilities = Events.list_unavailabilities(availability_params, [:mentor])

conn
|> put_status(:ok)
|> render("show.json", availability: availability)
|> render(:index, availabilities: availabilities, unavailabilities: unavailabilities)
end

def index(conn, availability_params) do
availabilities = Events.list_availabilities(availability_params, [:mentor])
unavailabilities = Events.list_unavailabilities(availability_params, [:mentor])
def show(conn, %{"id" => availability_id}) do
availability = Events.get_availability!(availability_id)

conn
|> put_status(:ok)
|> render("index.json", availabilities: availabilities, unavailabilities: unavailabilities)
|> render(:show, availability: availability)
end

def create(conn, %{
Expand All @@ -37,9 +37,9 @@ defmodule BokkenWeb.AvailabilityController do
|> put_status(:created)
|> put_resp_header(
"location",
Routes.event_availability_path(conn, :show, event, availability)
~p"/api/events/#{event}/availabilities/#{availability}"
)
|> render("show.json", availability: availability)
|> render(:show, availability: availability)
end
end

Expand All @@ -50,7 +50,7 @@ defmodule BokkenWeb.AvailabilityController do
Events.update_availability(old_availability, availability_params) do
conn
|> put_status(:ok)
|> render("show.json", availability: new_availability)
|> render(:show, availability: new_availability)
end
end
end
48 changes: 48 additions & 0 deletions lib/bokken_web/controllers/availability_json.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
defmodule BokkenWeb.AvailabilityJSON do
alias Bokken.Events.Availability

alias BokkenWeb.EventJSON
alias BokkenWeb.MentorJSON

def index(%{
availabilities: availabilities,
unavailabilities: unavailabilities,
current_user: current_user
}) do
%{
availabilities: for(availability <- availabilities, do: data(availability, current_user)),
unavailabilities:
for(availability <- unavailabilities, do: data(availability, current_user))
}
end

def show(%{availability: availability, current_user: current_user}) do
%{data: data(availability, current_user)}
end

def data(%Availability{} = availability, current_user) do
%{
availability_id: availability.id,
is_available: availability.is_available,
notes: availability.notes
}
|> Map.merge(event(availability))
|> Map.merge(mentor(availability, current_user))
end

defp event(availability) do
if Ecto.assoc_loaded?(availability.event) do
EventJSON.data(availability.event)
else
%{event_id: availability.event_id}
end
end

defp mentor(availability, current_user) do
if Ecto.assoc_loaded?(availability.mentor) do
MentorJSON.data(availability.mentor, current_user)
else
%{mentor_id: availability.mentor_id}
end
end
end
Loading