---
name: evolution_timesheets_invoiced_column
description: "timesheets.invoiced stores the invoice id, not a 0/1 boolean — test with > 0"
metadata: 
  node_type: memory
  type: reference
  originSessionId: 3c220c8b-995b-43f3-b311-92d0dbb84a6b
---

In evolution's `timesheets` table, the `invoiced` column holds the **id of the invoice** the timesheet was billed onto, NOT a binary 0/1 flag. (Same likely applies to `timesheets_items.invoiced`, which is set to an `$invoiceid` in invoiceaddsave.php and reset to 0 on un-invoice.)

**Why:** A `WHERE timesheets.invoiced = 1` test looks like a boolean check but actually only matches timesheets billed on invoice id 1 — silently dropping nearly all invoiced labour. `> 1` is also wrong: it excludes invoice id 1.

**How to apply:** To test "has this timesheet been invoiced?", use `invoiced > 0`. To test "not yet invoiced", `invoiced = 0` (correct — unbilled rows are 0/unset). The actual invoice id is available directly in this column if you need to join to `invoices`. Most existing reports already use `invoiced = 0` / `> 0` correctly; the broken `= 1` pattern was only in tsEffectiveBillRateSave.php (now fixed). Relates to [[evolution_ajax_save_auth_gate]] (same report family).
