feat(invoices): surface monthly/manual accumulator drafts in the Bills list
Manual/monthly-cadence customers accumulate logged hours into one running
draft invoice (is_monthly_draft, migration 128). That draft gets a real
invoice number and stamps the hours ("Billed: R-2026-0026"), but listInvoices
hid is_monthly_draft rows from the main list — so the invoice looked lost even
though it existed on the customer's monthly-queue card. It also carried status
'scheduled' despite never auto-sending on manual cadence, reading misleadingly
as "Scheduled".
- Bills list now opts into drafts via a new `includeDrafts` query param
(GET /admin/invoices → listInvoices includeMonthlyDrafts). Pickers/sub-lists
that reuse billsService.list leave it off, so they're unaffected.
- Draft rows render a distinct "Draft" badge instead of "Scheduled"
(transformInvoice already exposes isMonthlyDraft).
- The hours "Billed: R-…" chip now links straight to its invoice.
- i18n: bills.status.draft (de "Entwurf", en "Draft").
This commit is contained in:
@@ -448,12 +448,24 @@ export const HoursSection: React.FC<HoursSectionProps> = ({
|
||||
</td>
|
||||
<td className="py-1.5 pr-3">
|
||||
{e.status === 'billed' ? (
|
||||
<span className="text-xs text-green-700 dark:text-green-300">
|
||||
{e.invoiceNumber
|
||||
? t('customers.hours.status.billedOn',
|
||||
'Billed: {{number}}', { number: e.invoiceNumber })
|
||||
: t('customers.hours.status.billed', 'Billed')}
|
||||
</span>
|
||||
e.invoiceId ? (
|
||||
// Link straight to the invoice so a "Billed: R-…" entry
|
||||
// is one click from its (possibly draft) invoice.
|
||||
<Link
|
||||
to={`/admin/clients/bills/${e.invoiceId}`}
|
||||
className="text-xs text-green-700 dark:text-green-300 underline hover:no-underline"
|
||||
>
|
||||
{e.invoiceNumber
|
||||
? t('customers.hours.status.billedOn', 'Billed: {{number}}', { number: e.invoiceNumber })
|
||||
: t('customers.hours.status.billed', 'Billed')}
|
||||
</Link>
|
||||
) : (
|
||||
<span className="text-xs text-green-700 dark:text-green-300">
|
||||
{e.invoiceNumber
|
||||
? t('customers.hours.status.billedOn', 'Billed: {{number}}', { number: e.invoiceNumber })
|
||||
: t('customers.hours.status.billed', 'Billed')}
|
||||
</span>
|
||||
)
|
||||
) : (
|
||||
<span className="text-xs text-amber-700 dark:text-amber-300">
|
||||
{t('customers.hours.status.unbilled', 'Unbilled')}
|
||||
|
||||
Reference in New Issue
Block a user