User Guide
04.3 · Direct Costs

Indenting and Nesting Items

Nesting groups related items together and creates a parent row whose total sums its children's totals.

The Rules

  • Max indent level: 6 (7 levels total).
  • Tab indents; Shift+Tab outdents.
  • Indenting assigns the nearest previous row at the same or lower level as the parent.

Worked Example

Start with a flat list:

1  Site Preparation
2  Excavation
3  Backfill

Select rows 2 and 3, press Tab:

1  Site Preparation
2    Excavation
3    Backfill

Row 1 becomes the parent. Its TotalWithChildren now sums lines 2 and 3.

Header vs Mixed Parent

Row 1 in the example has Qty = 0 and no resource — it's a pure header. A parent can also have its own quantity and rate, in which case TX1 adds that to the children's total. This is allowed but unusual. Recommended pattern: keep parents as pure headers.

Reordering

  • Alt+↑ / ↓ moves selected rows up or down among siblings.
  • Dragging a row onto another row re-parents it.
  • Drag-and-drop respects the max indent level and blocks invalid moves.

Collapsing

Click the chevron to collapse a parent. The expand state persists across sessions via the project's DirectCostHierarchyStateJson field.

What Rolls Up

AggregateSource
TotalWithChildrenΣ of all descendants' TotalWithChildren + own DirectTotal.
RateWithChildrenTotalWithChildren / Quantity — only meaningful if the parent has its own Qty.
Sell Total (parent)Computed per-row by the sell-rate pipeline, not re-summed.

Warning — Performance

Changing a deep-nested row triggers a bubble-up notification to every ancestor. Large hierarchies (thousands of items) should be debounced — the engine does this with NotifyAncestorsOfTotalChange() to avoid re-rendering on every keystroke.