Recued
Menu
← Back to recipes

Show unbilled hours

by recued-core v2 5 views

Use “Show unbilled hours” in Recued. What you have worked and not yet billed, per task. Hours and entry count come from the store over every matching row; the per-task money breakdown covers the entries fetched, and the card says when those differ.

Complete workflow

Billable Hours 5 pinned recipes

Use Billable Hours in Recued for time tracking, invoicing, freelance, and consulting. It includes 11 built-in actions and 4 ready-to-run workflows. Actions that change data use Recued's approval controls.

You are viewing one recipe in this workflow. Installing it opens the complete pack so its other recipes and background automations arrive together.

Show unbilled hours
This recipe

Use “Show unbilled hours” in Recued. What you have worked and not yet billed, per task. Hours and entry count come from the store over every matching row; the per-task money breakdown covers the entries fetched, and the card says when those differ.

pack:billable-hourstime-trackingboardrecords
by recued-core pinned v2

Use “Open an engagement” in Recued. Record a client and the hourly rate you bill them. Keyed on the label, so re-running with the same one converges instead of opening a second engagement at a different rate.

pack:billable-hourstime-trackingbillablerecords
by recued-core pinned v2

Use “Log hours” in Recued. Record one block of work against an engagement. It uses the connections and settings you choose when you run it.

pack:billable-hourstime-trackingbillablerecords
by recued-core pinned v2

Use “Bill a period” in Recued. Group a period's unbilled billable hours by task, stamp each entry with your invoice reference, and produce invoice lines whose amounts add up to the total. Entries already carrying an invoice reference are left alone, so running it twice cannot charge the same hour twice.

pack:billable-hourstime-trackingbillableinvoicing
by recued-core pinned v2
View pack details, dependencies, and permissions →

Reading it

Unbilled is billable time not yet stamped by Bill a period. That is the number that is worth money to you today.

Non-billable time is counted separately and is never in the amount. It is shown because knowing how much unbillable work an engagement absorbs is the point of tracking it at all.

The amount is computed at the engagement's CURRENT rate, not the rate in force when each hour was logged — the rate lives on the engagement, not on the entry. If you raised your rate mid-engagement, this revalues old unbilled hours upward. Open an engagement says how to avoid that: a second engagement.

Money is rounded once, here, to two decimals. Minutes are stored exactly; nothing accumulates rounding across entries because the conversion happens on the total, not per row.

This groups by task and rounds per group exactly as bill-period does, so the figure here is the figure you will bill. Rounding once on the grand total instead would make this preview disagree with the invoice by a penny or two — which is worse than either rule on its own, because you would not know which one was wrong.

⛔⛔ THE HOURS AND THE ENTRY COUNT ARE COMPLETE; THE MONEY BREAKDOWN COVERS THE ENTRIES FETCHED. They come from two different places on purpose. The totals are computed by the store over every matching row (entry.unbilled_rollup), so they do not silently shrink when you have more unbilled work than one page holds — which is exactly what a page-derived total used to do, and it was understating money owed. The per-task breakdown still needs the rows themselves, so it shows what the limit fetched.

When the two disagree the card says so and warns. Raise the limit and re-run to make the amount complete. A quiet smaller number is the failure worth avoiding here: you would invoice it.

How it works 40 steps

Inspect the data fetches, transforms, gates, and output this recipe runs.

Process (40 steps)
engagement_id trim
Trim whitespace from setting engagement id
id_present compare
Check if engagement id has data
id_guard guard
Stop if id present equals
engagement ?
found compare
Check if engagement record id has data
found_guard guard
Stop if found equals
engagement_ref template
Generate text from a template
period trim
Trim whitespace from setting period
by_period compare
Check if period has data
all_entries ?
skip: step.by_period equal true
period_entries ?
skip: step.by_period equal false
rollup_all ?
skip: step.by_period equal true
rollup_period ?
skip: step.by_period equal false
rollup coalesce
Use the first available value from: rollup period aggregate, rollup all aggregate, [object Object]
rows coalesce
Use the first available value from: period entries records, all entries records,
row_count count
Count items in rows
billable_rows filter
Filter by condition
nonbillable_rows filter
Filter by condition
unbilled_rows filter
Filter by condition
billed_rows filter
Filter by condition
unbilled_lines map
Extract from each item
unbilled_keyed map
Extract task from each item
unbilled_groups group_by
Group by task_key
group_lines map
Extract from each item
group_lines_sorted sort
Sort by amount
amount_unrounded sum
Sum values in
amount_due round
Round amount unrounded to 2 decimal places
unbilled_minutes default
Apply default
billed_minutes sum
Sum values in
nonbillable_minutes sum
Sum values in
unbilled_hours_raw math
Calculate: {{step.unbilled_minutes}} / 60
unbilled_hours round
Round unbilled hours raw to 2 decimal places
nonbillable_hours_raw math
Calculate: {{step.nonbillable_minutes}} / 60
nonbillable_hours round
Round nonbillable hours raw to 2 decimal places
unbilled_count default
Apply default
shown_count count
Count items in unbilled rows
complete compare
Check if shown count equals unbilled count
partial_warning ternary
Apply ternary
table to_table
Format results as a data table
card to_summary
Format results as a summary card
Settings 3 configurable

Configurable at install. Defaults shown — change them anytime in Recued.

limit setting = 200
period setting =
engagement id setting = [object Object]

About

Tags

pack:billable-hourstime-trackingboardrecordsv2

Details

40 steps 3 configurable settings recipe_id: list-unbilled-hours