defmodule Confient.Works do @moduledoc """ The Works context. """ import Ecto.Query, warn: false alias Confient.Repo alias Confient.Works.Assignment @doc """ Returns the list of assignments. ## Examples iex> list_assignments() [%Assignment{}, ...] """ def list_assignments do Repo.all(Assignment) |> Repo.preload(:class) end def get_next_assignments(%Confient.School.Class{id: id}) do date = DateTime.now!(Application.fetch_env!(:confient, :timezone)) |> DateTime.to_date() query = from a in Assignment, where: a.id == ^id, where: a.due >= ^date, select: a Repo.all(query) end @doc """ Gets a single assignment. Raises `Ecto.NoResultsError` if the Assignment does not exist. ## Examples iex> get_assignment!(123) %Assignment{} iex> get_assignment!(456) ** (Ecto.NoResultsError) """ def get_assignment!(id), do: Repo.get!(Assignment, id) |> Repo.preload(:class) def get_full_assignment!(id) do Repo.one!( from a in Assignment, where: a.id == ^id, preload: [{:students_works, :student}, :class], select: a ) end def get_missing_works_from_student_in_assignement(id, class_id) do squery = from a in Assignment, where: a.id == ^id, left_join: w in Confient.Student.Work, select: %{id: w.student_id} query = from studs in subquery(squery), right_join: s in Confient.School.Student, on: studs.id == s.id, where: is_nil(studs.id) and s.class_id == ^class_id, select: s Repo.all(query) end def get_assignment(id) do case Repo.get(Assignment, id) |> Repo.preload(:class) do nil -> {:error, :no_assignment} assignment -> {:ok, assignment} end end @doc """ Creates a assignment. ## Examples iex> create_assignment(%{field: value}) {:ok, %Assignment{}} iex> create_assignment(%{field: bad_value}) {:error, %Ecto.Changeset{}} """ def create_assignment(attrs \\ %{}) do %Assignment{} |> Assignment.changeset(attrs) |> Repo.insert() end @doc """ Updates a assignment. ## Examples iex> update_assignment(assignment, %{field: new_value}) {:ok, %Assignment{}} iex> update_assignment(assignment, %{field: bad_value}) {:error, %Ecto.Changeset{}} """ def update_assignment(%Assignment{} = assignment, attrs) do assignment |> Assignment.changeset(attrs) |> Repo.update() end @doc """ Deletes a assignment. ## Examples iex> delete_assignment(assignment) {:ok, %Assignment{}} iex> delete_assignment(assignment) {:error, %Ecto.Changeset{}} """ def delete_assignment(%Assignment{} = assignment) do Repo.delete(assignment) end @doc """ Returns an `%Ecto.Changeset{}` for tracking assignment changes. ## Examples iex> change_assignment(assignment) %Ecto.Changeset{data: %Assignment{}} """ def change_assignment(%Assignment{} = assignment, attrs \\ %{}) do Assignment.changeset(assignment, attrs) end def create_or_update_work(attrs = %{path: _path, student_id: sid, assignment_id: aid} \\ %{}) do work = case Repo.one( from w in Confient.Student.Work, where: w.assignment_id == ^aid and w.student_id == ^sid, select: w ) do nil -> %Confient.Student.Work{} data -> data end work |> Confient.Student.Work.changeset(attrs) |> Repo.insert_or_update() end end