Dries Peeters
f2e81dfaef
feat(billing): invoice all unbilled time for a client from API and UI
...
Add POST /api/v1/clients/{client_id}/invoice-unbilled to build one draft
invoice from completed billable time not yet on any invoice line, grouped
by project with RateOverride-based rates. Supports API tokens
(write:invoices) or a logged-in user with create_invoices; enforces client
and module access.
InvoiceService gains shared preview/state helpers and
create_client_unbilled_invoice with safe_commit and invoice webhook.
Client detail page adds a confirmation flow and redirect to the new
invoice. Document read:invoices / write:invoices and the new route in
docs/api/API_TOKEN_SCOPES.md; expose the path on the v1 discovery payload.
Tests: two-project client creates two line items; second call returns
no_unbilled_entries.
2026-04-27 18:15:24 +02:00
..
2026-03-15 10:51:52 +01:00
2026-04-12 14:00:12 +02:00
2026-03-26 14:52:06 +01:00
2026-03-15 09:37:15 +01:00
2026-04-16 15:36:01 +02:00
2026-04-27 18:15:24 +02:00
2026-04-24 16:15:24 +02:00
2026-04-15 12:15:23 +02:00
2026-03-15 09:37:15 +01:00
2026-03-27 06:39:16 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-16 16:42:53 +01:00
2026-03-15 09:37:15 +01:00
2026-03-27 06:39:16 +01:00
2026-01-25 09:13:14 +01:00
2026-03-26 17:01:55 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-04-16 15:09:03 +02:00
2026-03-15 09:37:15 +01:00
2026-03-08 06:50:42 +01:00
2026-04-16 15:36:01 +02:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-26 14:52:06 +01:00
2026-03-08 06:50:42 +01:00
2026-04-15 12:57:01 +02:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-04-26 07:55:47 +02:00
2026-01-21 13:59:13 +01:00
2026-01-25 08:59:54 +01:00
2026-03-08 06:50:42 +01:00
2026-03-06 15:46:07 +01:00
2026-02-09 20:22:08 +01:00
2026-04-12 13:34:58 +02:00
2026-01-25 09:44:46 +01:00
2026-03-16 16:43:35 +01:00
2026-03-08 06:50:42 +01:00
2026-01-30 17:26:14 +01:00
2026-01-25 09:38:11 +01:00
2026-01-25 09:38:11 +01:00
2026-04-24 21:13:29 +02:00
2026-03-08 06:50:42 +01:00
2026-03-16 15:16:11 +01:00
2026-03-16 16:44:09 +01:00
2026-03-08 06:50:42 +01:00
2026-03-08 06:50:42 +01:00
2026-03-16 13:01:41 +01:00
2026-03-08 06:50:42 +01:00
2026-03-27 06:39:16 +01:00
2026-03-26 14:51:55 +01:00
2026-04-12 13:34:58 +02:00
2026-04-12 13:34:58 +02:00
2026-03-26 14:51:55 +01:00
2026-03-16 15:16:11 +01:00
2026-03-16 15:16:11 +01:00
2026-03-15 10:16:49 +01:00
2026-01-30 17:25:56 +01:00
2026-02-02 17:24:45 +01:00
2026-02-02 17:24:45 +01:00
2026-03-28 17:32:18 +01:00
2026-03-11 17:39:37 +01:00
2026-03-11 17:39:37 +01:00
2026-03-11 17:39:37 +01:00
2026-03-28 20:07:19 +01:00
2026-02-20 09:56:44 +01:00
2026-04-12 13:34:58 +02:00
2026-03-02 20:55:02 +01:00
2026-03-06 22:15:29 +01:00
2026-03-28 20:07:19 +01:00
2026-03-15 09:37:15 +01:00
2026-03-15 09:37:15 +01:00
2026-03-15 10:16:49 +01:00
2026-03-15 09:37:15 +01:00
2026-02-02 19:18:28 +01:00
2026-04-15 12:57:01 +02:00
2026-03-16 15:16:11 +01:00
2026-04-15 10:55:37 +02:00
2026-01-25 08:59:54 +01:00
2026-03-26 18:25:10 +01:00
2026-03-26 17:01:55 +01:00
2026-01-25 08:59:54 +01:00
2026-03-27 06:41:03 +01:00
2026-01-25 09:38:11 +01:00
2026-02-02 17:59:59 +01:00
2026-03-09 20:33:48 +01:00
2026-03-15 09:37:15 +01:00
2026-01-25 08:36:02 +01:00
2026-04-12 13:34:58 +02:00