# `GanttEx.Dependency`
[🔗](https://github.com/rocket4ce/gantt_ex/blob/v0.1.0/lib/gantt_ex/dependency.ex#L1)

The dependency graph behind auto-scheduling (`GanttEx.Scheduler`) and the
critical path (`GanttEx.CriticalPath`).

Only *schedulable* tasks take part: tasks and milestones, and projects
without children. Projects with children get their dates from their
descendants, so:

  * a link **from** a project depends on every schedulable descendant of it
  * a finish-to-start or start-to-start link **to** a project applies to each
    of its schedulable descendants

Lags are in the duration unit of the store, using the calendar of the task
being scheduled.

    iex> store = GanttEx.Store.new!(
    ...>   [%{id: 1, start_date: ~D[2025-01-06], duration: 2}, %{id: 2, start_date: ~D[2025-01-06], duration: 1}],
    ...>   [%{id: 1, source: 1, target: 2, lag: 1}]
    ...> )
    iex> GanttEx.Dependency.order(store)
    [1, 2]
    iex> task = GanttEx.Store.get_task(store, 2)
    iex> GanttEx.Dependency.earliest_start(store, task)
    ~N[2025-01-09 00:00:00]

# `earliest_start`

```elixir
@spec earliest_start(GanttEx.Store.t(), GanttEx.Task.t()) :: NaiveDateTime.t() | nil
```

Returns the earliest start the links of `task` allow, or `nil` when no link
constrains it.

# `finish_bound`

```elixir
@spec finish_bound(
  GanttEx.Store.t(),
  GanttEx.Task.t(),
  GanttEx.Link.t(),
  NaiveDateTime.t(),
  NaiveDateTime.t()
) :: NaiveDateTime.t()
```

Returns the latest end of `source` that does not delay `successor` through
`link`, given the successor's latest start and end.

# `incoming`

```elixir
@spec incoming(GanttEx.Store.t(), GanttEx.Task.t()) :: [GanttEx.Link.t()]
```

Returns the links that constrain `task`: links to the task itself, plus
finish-to-start and start-to-start links to its ancestor projects.

# `order`

```elixir
@spec order(GanttEx.Store.t()) :: [GanttEx.Task.id()]
```

Returns the schedulable task ids ordered so that every task comes after the
tasks it depends on (ties keep the tree order). Tasks in a cycle, which
links between a project and its own descendants can create, are appended
in tree order.

# `outgoing`

```elixir
@spec outgoing(GanttEx.Store.t(), GanttEx.Task.t()) :: [GanttEx.Link.t()]
```

Returns the links whose source is `task` or one of its ancestor projects.

# `schedulable?`

```elixir
@spec schedulable?(GanttEx.Store.t(), GanttEx.Task.t()) :: boolean()
```

Returns `true` when the dates of `task` are scheduled (not rolled up).

# `schedulable_ids`

```elixir
@spec schedulable_ids(GanttEx.Store.t()) :: [GanttEx.Task.id()]
```

Returns the ids of the schedulable tasks, in tree order.

# `source_ids`

```elixir
@spec source_ids(GanttEx.Store.t(), GanttEx.Link.t()) :: [GanttEx.Task.id()]
```

Returns the schedulable tasks a link source stands for.

# `start_bound`

```elixir
@spec start_bound(GanttEx.Store.t(), GanttEx.Task.t(), GanttEx.Link.t()) ::
  NaiveDateTime.t() | nil
```

Returns the earliest start of `task` allowed by one incoming `link`.

  * finish-to-start: starts after the source ends (plus lag)
  * start-to-start: starts after the source starts (plus lag)
  * finish-to-finish: ends after the source ends (plus lag)
  * start-to-finish: ends after the source starts (plus lag)

---

*Consult [api-reference.md](api-reference.md) for complete listing*
