Skip to content

fix: separate invoices from work orders + bottom page padding - #45

Merged
Dev869 merged 1 commit into
mainfrom
fix/separate-invoices-from-workorders
May 18, 2026
Merged

Dev869 merged 1 commit into
mainfrom
fix/separate-invoices-from-workorders

Conversation

@Dev869

@Dev869 Dev869 commented May 18, 2026

Copy link
Copy Markdown
Owner

Domain rule (authoritative)

A WorkItem that has been sent out is an invoice, not a work order:

  • "Sent out" = invoiceSentDate is set, OR invoiceStatus ∈ {sent, paid, overdue}.
  • A WorkItem that has not been sent out is a work order.
  • The two sets are mutually exclusive — an item never appears in both places.

No Firestore migration, no new collection. Reversible behavior change only. invoiceSentDate / invoiceStatus write logic is unchanged. Quotes untouched.

Fix 1 — Single-sourced membership

Shared predicate: web/src/lib/workItem.ts

  • isInvoice(item) = Boolean(invoiceSentDate) || invoiceStatus ∈ {sent,paid,overdue}
  • isWorkOrder(item) = !isInvoice(item)
  • Unit tests: web/src/lib/workItem.test.ts (7 tests).

Views changed to use the shared predicate:

  • web/src/routes/contractor/WorkItems.tsx — Work Items list now excludes invoices (isWorkOrder at the top of the filter chain). Removed the now-nonsensical invoice-status sub-filter (state, URL param invoice, chip UI, options/labels, clear-all, active-count) since a work-orders list can't have sent/paid/overdue items.
  • web/src/routes/contractor/Dashboard.tsxpending widget (draft/inReview) and pipelineStages counts now filter with isWorkOrder. Finance/invoice widgets (revenue, invoice counts) left unchanged.
  • web/src/lib/finance.tsgetInvoicesByStatus and getInvoiceStatusCounts now derive membership from the shared isInvoice (previously returned all billable non-archived items, which incorrectly included never-sent drafts). This single-sources the Invoices route (/dashboard/invoices and /dashboard/finance/invoices — same Invoices component) so it shows ONLY invoices.
  • web/src/lib/finance.test.ts — updated getInvoiceStatusCounts test to the corrected contract (never-sent billable items are work orders, excluded; a draft-status item that was sent still counts as a draft invoice).

Not changed: WorkItemDetail route remains reachable for both (PR #44's section separation kept. GlobalSearch still finds everything (it's search, not a list). Invoice creation (NewInvoiceModal) reads directly and is unaffected.

Fix 2 — Bottom-of-page padding

shared scroll container: → . Desktop content was flush against the viewport bottom ( zeroed it out). Mobile (clears bottom nav + safe area) and all top/side spacing unchanged. Fixed once in the shared layout, not per-page.

Test plan

  • → exit 0
  • [x]
    RUN v4.1.6 /Users/devinwilson/Projects/open-ten99

❯ functions/lib/utils/categorize.test.js (0 test)
❯ functions/lib/utils/matching.test.js (0 test)
❯ functions/lib/utils/crypto.test.js (0 test)
❯ .claude/worktrees/agent-add3d974479af5b9c/web/src/lib/tests/invoiceBranding.test.ts (0 test)

Test Files 4 failed | 16 passed (20)
Tests 195 passed (195)
Start at 16:02:16
Duration 2.11s (transform 2.83s, setup 0ms, import 3.15s, tests 503ms, environment 2ms) → 66/66 pass (incl. 7 new predicate tests + updated finance test)

  • → no NEW errors in touched files vs (29 problems / 11 errors baseline == after; all pre-existing in untouched Dashboard deps)
  • Manual: Work Items list shows no sent invoices; Invoices list shows only sent items; Dashboard pending/pipeline exclude invoices; desktop pages have bottom breathing room

🤖 Generated with Claude Code
EOF
)

@github-actions

Copy link
Copy Markdown

🔥 Firebase Hosting preview: https://open-ten99--pr-45-q4m0ayj7.web.app
(expires in 7 days)

@Dev869
Dev869 merged commit de25424 into main May 18, 2026
3 checks passed
@Dev869
Dev869 deleted the fix/separate-invoices-from-workorders branch May 18, 2026 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant