Packages

Build calendars from ecto queries, includes view helpers for easy rendering with Phoenix

Current section

Files

Jump to
ez_calendar lib ez_calendar.ex
Raw

lib/ez_calendar.ex

defmodule EZCalendar do
@moduledoc """
Functions for building calendars.
To use the Repo shortcut functions, add `EZCalendar` to your repo.
defmodule MyApp.Repo do
use Ecto.Repo, otp_app: :my_app
use EZCalendar
end
The following functions and their bang! variants then become available.
Repo.calendar(query, calendar_module, params, opts \\\\ [])
Repo.day_calendar(query, params, opts \\\\ [])
Repo.week_calendar(query, params, opts \\\\ [])
Repo.month_calendar(query, params, opts \\\\ [])
Repo.biweekly_calendar(query, params, opts \\\\ [])
You can use a keyword list for multiple queries. Each query will use
the default field(s) unless provided in the query list or in the options
and the results will be accessible by their key in each dates data field.
[
shifts: [Shift, [:starting, :ending]],
events: [Event, :starting_at],
meetings: Meeting,
deliveries: Delivery
]
|> Repo.month_calendar({2016, 11}, field: :scheduled_for)
Params can be a Date, DateTime, erl style tuple or map containing a day month and year.
The day can be ommited from the params, doing so will result in the first of the month being used.
Tuple and map values will be cast as integers for easy integration with phoenix.
The timezone and query field can be set with `:tz` and `:field` as options.
If using a biweekly calendar the `biweekly_start` can also be set.
"""
alias EZCalendar.ParamParser
defmacro __using__(_) do
quote do
def calendar(query, calendar_type, params, opts \\ []) do
EZCalendar.build_calendar(calendar_type, __MODULE__, query, params, opts)
end
def calendar!(query, calendar_type, params, opts \\ []) do
EZCalendar.build_calendar!(calendar_type, __MODULE__, query, params, opts)
end
def month_calendar(query, params, opts \\ []) do
EZCalendar.build_calendar(EZCalendar.MonthCalendar, __MODULE__, query, params, opts)
end
def month_calendar!(query, params, opts \\ []) do
EZCalendar.build_calendar!(EZCalendar.MonthCalendar, __MODULE__, query, params, opts)
end
def week_calendar(query, params, opts \\ []) do
EZCalendar.build_calendar(EZCalendar.WeekCalendar, __MODULE__, query, params, opts)
end
def week_calendar!(query, params, opts \\ []) do
EZCalendar.build_calendar!(EZCalendar.WeekCalendar, __MODULE__, query, params, opts)
end
def day_calendar(query, params, opts \\ []) do
EZCalendar.build_calendar(EZCalendar.DayCalendar, __MODULE__, query, params, opts)
end
def day_calendar!(query, params, opts \\ []) do
EZCalendar.build_calendar!(EZCalendar.DayCalendar, __MODULE__, query, params, opts)
end
def biweekly_calendar(query, params, opts \\ []) do
EZCalendar.build_calendar(EZCalendar.BiweeklyCalendar, __MODULE__, query, params, opts)
end
def biweekly_calendar!(query, params, opts \\ []) do
EZCalendar.build_calendar!(EZCalendar.BiweeklyCalendar, __MODULE__, query, params, opts)
end
end
end
@doc """
Builds a calendar struct. Returns a tuple containing `:ok` and the calendar or `:error` and the reason.
Takes a calendar module, repo, query, params and options as its arguments.
The params provided in the args are parsed into a date erl
and passed to the calendar modules `date_range` function.
The timezone and query field can be set with `:tz` and `:field` as options
"""
def build_calendar(calendar_module, repo, query, params, opts \\ []) do
case ParamParser.to_erl(params) do
{:ok, date} ->
{:ok, do_build_calendar(calendar_module, repo, query, date, opts)}
error -> error
end
end
@doc """
Builds a calendar struct. Returns a calendar or raises an error
Arguments and options are the same as `build_calendar/5`
"""
def build_calendar!(calendar_module, repo, query, params, opts \\ []) do
{:ok, date} = ParamParser.to_erl(params)
do_build_calendar(calendar_module, repo, query, date, opts)
end
defp do_build_calendar(calendar_module, repo, query, date, opts) do
{start_date, end_date} = calendar_module.date_range(date, opts)
EZCalendar.CalendarBuilder.build(query, repo, start_date, end_date, opts)
|> calendar_module.build(date)
end
end