Invoices
Captured contractor invoices — third-party invoices issued by contractors (typically to the customer) that RENEWA records as (1) evidence that a funded measure was delivered (ZUE / funding pass-through to BAFA/KfW) and (2) the basis for the commission RENEWA earns from the contractor. RENEWA does not owe money on these invoices.
Pivot (2026-04):
invoiceswas deliberately kept separate frombilling_invoices(RENEWA-issued invoices: customer invoices for EB/KOP deals, commission invoices). Unification was rejected — different ledgers, lifecycles, and GoBD scope; project-overview unification is a query-projection concern. See spec2026-04-28-invoices-incoming-outgoing-separation-design.mdand the billing module introduced in PR#1397. The German terms Eingangs-/Ausgangsrechnung are intentionally avoided: captured invoices are not RENEWA payables.
Source Files
| Layer | Path |
|---|---|
| Schema | backend/src/db/schema.ts |
| Routes | backend/src/routes/invoices.ts |
| Service | backend/src/services/invoice-service.ts |
| Components | frontend/src/components/invoices/ (~16 files) |
| Queries | frontend/src/lib/queries/invoiceQueries.ts |
The RENEWA-issued side lives in the billing module: billing_invoices + ~25 satellite tables (billing_*), backend/src/routes/billing*.ts, backend/src/services/billing/.
Database Tables
| Table | Purpose |
|---|---|
invoices | Main entity — project, contractor contact, amounts, payment status, dates |
invoice_line_items | Individual billed items with description, quantity, price, component type |
invoice_line_item_funding_measures | Links line items to Funding Applications measures (BAFA/KfW pass-through) |
invoice_line_item_funding_loans | Links line items to funding loans |
component_invoice_links | Links Building Components to invoice line items |
funding_invoice_allocations | Distributes funding across invoices (with approval workflow) |
Key Fields
| Field | Type | Notes |
|---|---|---|
projectId | uuid FK | Parent project (cascade delete) |
contactId | uuid FK | Contractor contact who issued the invoice (required) |
quoteId | uuid FK | Source quote (optional, set null on delete) |
invoiceNumber | varchar | Invoice identifier |
totalAmount / netAmount / taxAmount | decimal(12,2) | Financial totals |
taxRate | decimal | Default 0.19 (German VAT) |
paymentStatus | enum | unpaid, pending, partially_paid, paid, overdue, cancelled |
paidAmount / outstandingAmount | decimal | Payment tracking |
discountPercentage, skontoPercentage | decimal | Discount and early-payment terms |
customerPaymentConfirmation | boolean | Whether customer confirmed payment |
Money Handling (MANDATORY)
decimal(p,s) columns leave Drizzle as strings and stay decimal strings on the wire (never number in DTOs). Parse with fromString(...) from @shared/money, compute via Big.js (add/sub/mul/div, round(m, 2) HALF_UP), stringify back. Never Number()/parseFloat() or native arithmetic on money columns — enforced by ESLint renewa-local/no-number-on-money + quick-lint.sh. Spec: 2026-04-24-money-arithmetic-bigjs-design.md.
Relationships
Invoice *──1 Project
Invoice *──1 Contact (contractor / issuer)
Invoice *──1 Quote (source, optional)
Invoice 1──* Invoice Line Items
Invoice Line Items *──* Building Components (via component_invoice_links)
Invoice *──* Funding Applications (via funding_invoice_allocations)
Frontend Components
| Component | Purpose |
|---|---|
InvoiceForm | Create/edit invoice with financial details |
InvoiceLineItemsTable | Manage individual line items |
InvoicesList | List view with filtering and sorting |
BuildingInvoicesList | Invoices scoped to a building |
InlineInvoicesTable / InlineInvoiceRow / InlineInvoiceExpandedRow | Compact inline display |
LinkFundingApplicationsDialog | Link invoices to Funding Applications |
CreateInvoiceWithProjectDialog | Quick-create with project selection |
InvoiceFileManager / InvoiceFileDropzone / InvoiceFileUpload | Attach Files to invoices |
InvoiceAuditLogDialog | View Audit Logs for an invoice |
Features
- Evidence + commission basis — captured amounts feed project settlement and RENEWA’s commission calculation
- Payment tracking with status lifecycle (
unpaid→partially_paid→paid) - Funding allocation linking line items to Funding Applications measures and loans
- Component linking connecting invoice line items to Building Components
- File management via CAS Files (entity file links)
- Audit trail via Audit Logs dialog for tracking changes
- Skonto/discount terms with deadlines (German early-payment convention)
- Financial overview aggregated on Buildings detail page; quote billing aggregates (
contractValue,billedTotal,paidTotal,openTotal) are denormalized onto Quotes
Related Pages
Quotes | Projects | Buildings | Funding Applications | Building Components | Products | Contacts | Files | Financial Calculations | Audit Logs | Database Architecture