This allows to use identifiers in table helpers without checking the
subjects. That's useful for work packages with types having
automatically generated subjects.
When using `expect_work_packages`, if the column name is `hierarchy`,
the indentations of the work packages names will indicate parent-child
relationships.
So it's possible to check if a work package is parent of another one
along with other properties by writing something like this:
```ruby
expect_work_packages([parent, child], <<~TABLE)
| hierarchy | duration |
| parent | 3 |
| child1 | 2 |
| child2 | 2 |
TABLE
```
If `child2` is not a child of `parent`, this test would fail.
ActiveSupport deep_merge does not concatenate arrays from different
hashes. Relations were stored as an array.
Switch to a hash to store all relations without any loss.
This effectively removes the year from a bunch of copyright headers.
We stopped indicating a specific year at some point, but
didn't propagate this change to every file yet.
When a work package becomes a successor of another work package, its
scheduling mode is switched to automatic if it has no children so that
it can be scheduled as soon as possible automatically.
Similarly, when a work package is no longer a successor of any other
work package, its scheduling mode is switched to manual if it has no
children and no dates so that it can keep its current dates.
The `schedule_manually` column is also non-nullable now.
This includes the following changes:
- Automatically scheduled parent dates are and `ignore_non_working_days`
attributes are now always derived from children's values, even if the
children are scheduled manually.
It's more natural. Without that, adding a child to a work package
would not change the parent's dates.
As a consequence, the parent can start on a non-working day if one of
its children is manually scheduled, ignores non-working days, and
starts on a non-working day. That's why the parent's
`ignore_non_working_days` attribute is now also derived from all its
children regardless of the scheduling mode.
If the parent is manually scheduled, its dates and it's ability to
ignore non-working days will still be defined independently from its
children.
- Fix tests broken by scheduling mode being manual by default.
The tests had to be adapted to explicitly set scheduling mode to
automatic for followers and parents, and sometimes even follower's
children. Without it, work packages would not be rescheduled
automatically.
- Replace schedule helpers with table helpers.
Schedule helpers helped well, but table helpers are more flexible and
support more column types.
- Add "days counting" and "scheduling mode" columns to table helpers.
"days counting" to set `ignore_non_working_days` attribute.
- "all days" value maps to `ignore_non_working_days: true`.
- "working days" value maps to `ignore_non_working_days: false`.
"scheduling mode" to set `schedule_manually` attribute.
- "manual" value maps to `schedule_manually: true`.
- "automatic" value maps to `schedule_manually: false`.
They are taken from the schedule_helpers. It will help writing tests
with many work packages needing both the schedule, some properties
(follows relationships) and some other attributes like automatic/manual
scheduling mode.
When using `match_table` helper, some column were missing on the output.
It's because the headers where read from the first row, and the ones
without any value were stripped out. As this information is used to know
how to pull column data from work packages, the data was missing.
It allows to declare work packages and their properties from a visual
table. It is especially useful to visualize hierarchies and data as if
it were presented in the work package table page in OpenProject app.