Skip to content

Planning

These functions are dedicated to the planning of events or todos across one or more calendars, based on a planner config to determine how to plan. This config is written to a planners.yaml file:

- name: appointments
  title: Appointments
  write:
    type: event
  find:
    type: freebusy
    default_duration: 30
  calendars:
    - booking
  constraints:
    - holidays

It can also be edited in the Studio under the "Calendars" tab.

The planners.yaml must adhere to the following schema:

items:
  additionalProperties: false
  properties:
    calendars:
      items:
        pattern: ^[a-z][a-zA-Z0-9_]*$
        title: Identifier
        type: string
      maxItems: 20
      type: array
    constraints:
      items:
        pattern: ^[a-z][a-zA-Z0-9_]*$
        title: Identifier
        type: string
      type: array
    find:
      additionalProperties: false
      properties:
        default_duration:
          minimum: 5
          type: number
        max_days:
          minimum: 1
          type: number
        offset_from_now_in_m:
          minimum: 0
          type: number
        type:
          enum:
            - slot
            - freebusy
          type: string
      required:
        - type
      type: object
    name:
      type: string
    title:
      type: string
    write:
      additionalProperties: false
      properties:
        type:
          enum:
            - event
            - todo
          type: string
      required:
        - type
      type: object
  required:
    - name
    - title
    - write
    - find
    - calendars
  type: object
type: array

To make it easier to work with in tests, you can provide in-memory calendars wherever needed. Database and in-memory calendars can be freely mixed.

_temp_cal = Calendaring.new_in_memory_calendar()
# Add event, slot, etc..

_planner = @my_planner
_planner.calendars = [_temp_cal]
_planner.constraints = [_temp_cal]
# To overwrite where the slots should come from:
_planner.slot_calendar = _temp_cal

Planning.delete(config, object)

Delete the given object.

Returns a boolean indicating if the deletion succeeded. If the write calendar from the config doesn't match the given object, true will be returned, but no object will be deleted.

Examples:

object = Planning.get(config, id)
Planning.delete(config, object)

Planning.find(config, opts \\ [])

Find an available slot in which to plan an event/todo.

Depending on the configuration, this will call Calendaring.suggest_events or Calendaring.available_slots with the given options. The options that were passed in through the second argument will overwrite defaults derived from the config.

Options:

  • :amount: The maximum amount of slots to return.
  • :skip: The number of slots to skip. Defaults to 0.
  • :until: Until when to generate the slots. Defaults to now + max_days, where max_days is the planner setting.
  • :from: From when to start fetching the slots. Defaults to now + offset_from_now_in_m where offset_from_now_in_m is the planner setting.
  • :now: The current datetime to use as "now". Useful for testing.
  • :constraints: Additional calendars to consider. The resulting slots won't overlap with events on any of the given calendars.
  • :duration: The duration of the slot. Example: [minutes: 30]. Defaults to the default_duration on the planner config.

Planning.get(config, id)

Get an event/todo by it's ID.

Examples:

_item = Planning.plan(my_config, %{title: "Lunch", ...})
Planning.get(my_config, _item.id)

Planning.list(config, opts \\ [])

List the events/todos based on the config and opts.

Options:

  • :from: a datetime from where to start searching. Defaults to now.
  • :until: an end datetime until where to search. Defaults to [weeks: 2].
  • :amount: The maximum amount of events to return. Defaults to nil.
  • :skip: The number of events to skip. Defaults to 0.
  • :user_id: The user to look for.

Planning.plan(config, opts)

Plan an event or todo based on the given config.

Returns nil when planning failed.

Options:

  • :title: A required title.
  • :description: An optional markdown text field.
  • :from: A required datetime string from when the event/todo starts.
  • :until: A required datetime string from when the event/todo ends.
  • :location: An optional string indicating where the event/todo takes place.
  • :metadata: An optional map with arbitrary data about the event/todo.

Planning.plan(config, slot, opts)

Same as plan/2, except the from and until are derived from the slot. If slot is nil then this function behaves the same as plan/2 and from and until must be supplied as an option.