Current section

Files

Jump to
ami lib ami course_period.ex
Raw

lib/ami/course_period.ex

defmodule Ami.CoursePeriod do
use Ecto.Schema
import Ecto.{Query, Changeset}
alias Ami.{
Course,
Enrollment,
Score,
PackagePeriod,
Repo,
Community,
User,
CommunityUser
}
schema "course_periods" do
@timestamps_opts [type: :naive_datetime_usec]
field(:starts_on, :date)
field(:ends_on, :date)
field(:enrollment_end, :date)
field(:created_at, :utc_datetime_usec)
field(:updated_at, :utc_datetime_usec)
field(:is_learning_lab, :boolean)
field(:is_external, :boolean)
field(:buddy_type, :integer)
field(:manual_buddy_nomination, :boolean)
field(:position, :integer)
field(:one_for_all_email, :string, virtual: true)
field(:community_title, :string, virtual: true)
belongs_to(:course, Course)
belongs_to(:package_period, PackagePeriod)
belongs_to(:community, Community)
belongs_to(:oneforall_buddy, User, foreign_key: :oneforall_id)
has_many(:enrollments, Enrollment)
has_many(:scores, Score)
end
def changeset(%__MODULE__{} = struct, params \\ %{}) do
struct
|> cast(params, [
:starts_on,
:ends_on,
:enrollment_end,
:is_external,
:buddy_type,
:manual_buddy_nomination,
:position,
:community_id,
:oneforall_id,
:course_id
])
|> cast(%{created_at: DateTime.utc_now(), updated_at: DateTime.utc_now()}, [
:created_at,
:updated_at
])
end
def open_community_courses_for(user) do
Repo.all(
from(
cp in __MODULE__,
join: c in assoc(cp, :course),
join: com in assoc(cp, :community),
join: cu in assoc(com, :community_users),
where: c.on_air == true,
where: cu.user_id == ^user.id,
or_where: cu.user_id == ^user.id and cu.is_moderator == true,
where: cp.starts_on <= ^Date.utc_today() and cp.ends_on >= ^Date.utc_today(),
order_by: [asc: cp.ends_on, asc: c.title],
preload: [course: {c, [:thumb_image_attachments, :instructors]}]
)
)
|> Enum.uniq_by(fn cp -> cp.course_id end)
end
def for_on_air_featured_courses do
Repo.all(
from(
cp in __MODULE__,
join: c in assoc(cp, :course),
where: c.on_air == true,
where: c.is_featured == true,
order_by: [cp.ends_on, c.title],
preload: [course: {c, [:thumb_image_attachments, :instructors]}]
)
)
end
def for_open_on_air_public_courses do
Repo.all(
from(
cp in __MODULE__,
join: c in assoc(cp, :course),
where: c.on_air == true,
where: is_nil(c.community_id),
where: cp.starts_on <= ^Date.utc_today() and cp.ends_on >= ^Date.utc_today(),
where: is_nil(cp.community_id),
preload: [course: {c, [:thumb_image_attachments, :instructors]}],
order_by: [cp.ends_on, c.title]
)
)
end
def for_open_onair_universalpublic_community_courses do
Repo.all(
from(
cp in __MODULE__,
join: c in assoc(cp, :course),
join: com in assoc(cp, :community),
where: c.on_air == true,
where: com.access_type in [0, 1],
where: cp.starts_on <= ^Date.utc_today() and cp.ends_on >= ^Date.utc_today(),
order_by: [asc: cp.ends_on, asc: c.title],
preload: [course: {c, [:thumb_image_attachments, :instructors]}]
)
)
|> Enum.uniq_by(fn cp -> cp.course_id end)
end
def for_learning_lab() do
Repo.all(
from(
cp in __MODULE__,
join: c in assoc(cp, :course),
where: c.on_air == true,
where: cp.is_learning_lab == true,
where: cp.starts_on <= ^Date.utc_today() and cp.ends_on >= ^Date.utc_today(),
order_by: [asc: cp.ends_on, asc: c.title],
preload: [course: {c, [:thumb_image_attachments, :instructors]}]
)
)
end
def is_active?(course_period) do
Date.compare(course_period.starts_on, Date.utc_today()) in [:lt, :eq] &&
Date.compare(course_period.ends_on, Date.utc_today()) in [:gt, :eq]
end
def current_for(course) do
Repo.all(
from(
cp in __MODULE__,
where: cp.course_id == ^course.id,
where: cp.starts_on <= ^Date.utc_today() and cp.ends_on >= ^Date.utc_today(),
order_by: [asc: cp.starts_on]
)
)
|> List.first()
end
def currents_for(%Course{} = course) do
Repo.all(
from(
cp in __MODULE__,
join: c in assoc(cp, :course),
where: cp.course_id == ^course.id,
where: cp.starts_on <= ^Date.utc_today() and cp.ends_on >= ^Date.utc_today(),
order_by: [asc: cp.starts_on],
preload: [course: {c, [:thumb_image_attachments, :instructors]}]
)
)
end
def currents_for(%Community{} = community) do
Repo.all(
from(
cp in __MODULE__,
join: c in assoc(cp, :course),
where: cp.community_id == ^community.id,
where: c.on_air == true,
where: cp.starts_on <= ^Date.utc_today() and cp.ends_on >= ^Date.utc_today(),
order_by: [asc: cp.position, asc: c.title],
preload: [:course]
)
)
end
def currents_for(%Community{} = community, %Course{} = course) do
Repo.all(
from(
cp in __MODULE__,
join: c in assoc(cp, :course),
where: c.on_air == true,
where: cp.course_id == ^course.id,
where: cp.community_id == ^community.id,
where: cp.starts_on <= ^Date.utc_today() and cp.ends_on >= ^Date.utc_today(),
order_by: [asc: cp.ends_on],
preload: [:course]
)
)
end
@doc """
Return all open course periods for a given course depending on the passed user's status
"""
def currents_for(%Course{} = course, %User{} = user) do
case user.status do
0 ->
fetch_current_public_course_periods_for(course)
|> Enum.concat(fetch_user_communities_current_cps_for(course, user))
1 ->
fetch_current_public_course_periods_for(course)
|> Enum.concat(fetch_user_communities_current_cps_for(course, user))
2 ->
fetch_user_communities_current_cps_for(course, user)
_ ->
fetch_current_public_course_periods_for(course)
end
end
@doc """
Return a List of all open/current public course periods for a given course
"""
def fetch_current_public_course_periods_for(%Course{} = course) do
Repo.all(
from(
cp in __MODULE__,
join: c in assoc(cp, :course),
where: cp.course_id == ^course.id,
where: cp.starts_on <= ^Date.utc_today() and cp.ends_on >= ^Date.utc_today(),
where: is_nil(cp.community_id),
where: cp.is_learning_lab == false,
where: is_nil(cp.package_period_id),
order_by: [asc: cp.starts_on],
preload: [course: {c, [:thumb_image_attachments, :instructors]}]
)
)
end
@doc """
Return a List of all open/current community course periods for passed course belonging to the communities the passed user belongs to, as member or moderator
"""
def fetch_user_communities_current_cps_for(%Course{} = course, %User{} = user) do
query =
from(
cu in CommunityUser,
where: cu.user_id == ^user.id,
distinct: cu.community_id,
select: cu.community_id
)
# or Communities.Repo.all(query) but failing test, not sure how it impact performance though
community_ids = Repo.all(query)
Repo.all(
from(
cp in __MODULE__,
join: c in assoc(cp, :course),
where: cp.course_id == ^course.id,
where: cp.starts_on <= ^Date.utc_today() and cp.ends_on >= ^Date.utc_today(),
where: cp.community_id in ^community_ids,
order_by: [asc: cp.starts_on],
preload: [course: {c, [:thumb_image_attachments, :instructors]}]
)
)
end
def automatic_buddy?(course_period), do: course_period.buddy_type == 1
def oneforall_buddy?(course_period), do: course_period.buddy_type == 2
def enrollments_count(course_period) do
Repo.one(
from(
e in Enrollment,
where: e.active == true,
where: e.course_period_id == ^course_period.id,
select: count(e.id)
)
)
end
def students_for(course_period) do
Repo.all(
from(
e in Enrollment,
where: e.active == true,
where: e.course_period_id == ^course_period.id,
join: u in assoc(e, :user),
left_join: p in assoc(u, :profile),
preload: [user: {u, profile: p}]
)
)
end
def students_for_matching(course_period, user_id, term) do
from(
u in User,
where: u.id != ^user_id,
join: e in assoc(u, :enrollments),
left_join: p in assoc(u, :profile),
where: e.active == true,
where: e.course_period_id == ^course_period.id,
where:
ilike(u.name, ^"#{term}%") or ilike(p.first_name, ^"#{term}%") or
ilike(p.last_name, ^"#{term}%"),
preload: [profile: p],
select: [:id, :name, profile: [:id, :first_name, :last_name]]
)
|> Repo.all()
end
def public_cp_opening_today() do
Repo.all(
from(
cp in __MODULE__,
join: c in assoc(cp, :course),
where: c.on_air == true,
where: is_nil(c.community_id),
where: cp.starts_on == ^Date.utc_today(),
where: is_nil(cp.community_id),
preload: [course: {c, [:thumb_image_attachments, :instructors]}],
order_by: [cp.ends_on, c.title],
distinct: cp.course_id
)
)
end
def community_cp_opening_today(user_id) do
Repo.all(
from(
cp in __MODULE__,
join: c in assoc(cp, :course),
join: com in assoc(cp, :community),
join: cu in assoc(com, :community_users),
where: cu.user_id == ^user_id,
where: cp.starts_on == ^Date.utc_today(),
preload: [course: c],
order_by: [cp.ends_on, c.title],
distinct: cp.course_id
)
)
end
def community_cp_opened_days_ago(user_id, count) do
Repo.all(
from(
cp in __MODULE__,
join: c in assoc(cp, :course),
join: com in assoc(cp, :community),
join: cu in assoc(com, :community_users),
where: cu.user_id == ^user_id,
where: cp.starts_on == ^Timex.shift(Date.utc_today(), days: -count),
preload: [course: c],
order_by: [cp.ends_on, c.title],
distinct: cp.course_id
)
)
end
end