Skip to content

Car Economics & Invoicing

This document explains revenue/expense tracking, vehicle balances, invoicing, and payments.

Scope

  • Revenue recognition on orders, extra services, and insurances
  • Vehicle-level economics (profits/expenses, purchases, balances)
  • Invoices, invoice series/numbering, and PDF generation
  • Payments lifecycle and Stripe integration touchpoints
  • Calculators and totals

Data model (Prisma)

  • invoices and invoices_series (invoice header, numbering series, type)
  • payments and payment_methods (capture status, type, method, stage)
  • vehicle_balances (per-vehicle PROFIT/EXPENSE with categories)
  • orders snapshot totals (totalProfit, expenses, etc.)

See prisma/schema.prisma:

  • Key enums: InvoiceType, PaymentStage, PaymentStatus, PaymentType, PaymentMethod, PaymentVariant, VehicleBalanceType, VehicleBalanceCategory.
  • Important fields (selection):
    • orders.totalProfit, orders.expenses, orders.paymentInstructions, orders.paymentVariant
    • payments.stage, payments.type, payments.method, payments.status, paymentIntentId
    • vehicle_balances.type, vehicle_balances.category, amount and meta

Services

  • services/tenant/InvoiceService.ts: CRUD and business rules for invoices
  • services/tenant/InvoiceSerieService.ts: series management and last/next numbering
  • services/tenant/PaymentService.ts: creation, capture/refund hooks, invariants
  • services/tenant/VehicleBalanceService.ts: track per-vehicle expenses/profits
  • services/tenant/VehiclePurchaseService.ts: purchases/depreciation inputs
  • services/tenant/CalculationService.ts: assist with totals where applicable

Services are exposed via services/index.ts and injected into GraphQL resolvers through context.services.

GraphQL API

  • Schema files: server/graphql/schema/*.graphql cover invoices, payments, and related types.
  • Resolvers (selection):
    • Invoices:
      • Query: server/graphql/resolvers/query/Invoice/{invoices,invoice,lastInvoiceNumber}.resolver.js
      • Mutation: server/graphql/resolvers/mutation/Invoice/{createInvoice,updateInvoice,deleteInvoice}.resolver.js
    • Payments:
      • Mutations under server/graphql/resolvers/mutation/stripe/* integrate with Stripe flows
      • Other payment-related resolvers under server/graphql/resolvers/mutation/addPayment.resolver.js, etc.

Calculators and totals

  • lib/calculators.js: pricing, totals, and economics helpers used by order flows and invoice/payment computations.
    • Inputs: base tariffs, seasonal matrices, extra services, insurance, kilometers, delivery, taxes
    • Outputs: totals, profits, expenses, and odometer-based calculations

Invoicing flow

  1. Order finalized (check-in/out) → totals computed (lib/calculators.js).
  2. Create invoice via GraphQL mutation → InvoiceService persists header, lines, tenant/company context.
  3. Invoice series/numbering:
    • InvoiceSerieService returns series code and next number per tenant/company.
    • Query lastInvoiceNumber used for UI previews and validations.
  4. PDF generation:
    • Components under components/PDFDocuments/Invoice/* render data from fetchers (e.g., fetchInvoiceData.js).
    • Document downloaded/emailed to the client; see docs/rebuild/11-pdf-and-documents.md.

Payments lifecycle

  • Payment variants on orders (PaymentVariant): noPayments, instantPayment, etc.
  • Stages/statuses are tracked in payments:
    • PaymentStage: initiation → confirmation → settlement
    • PaymentStatus: pending/succeeded/failed/refunded
  • Stripe integration: see docs/rebuild/09-integrations.md (webhooks and resolvers). Payments mutate order/invoice states and persist paymentIntentId where applicable.

Vehicle economics

  • vehicle_balances captures both PROFIT and EXPENSE entries per vehicle, categorized (fuel, maintenance, insurance, purchase, other).
  • VehicleBalanceService and VehiclePurchaseService provide creation/query/update routines.
  • Reporting resolvers (tests reference): _tests_/vehicleExpenses.resolver.test.js, _tests_/vehicleProfits.resolver.test.js, _tests_/vehicleStatsPrisma.resolver.test.js demonstrate expected aggregations and error handling.

UI overview

  • Invoice pages and tables under components/InvoicesPage/* (including electronic billing helpers under components/InvoicesPage/electronicBilling/*).
  • Billing and payments in order views: components/OrderView/BillingTabOrderView/* and related.
  • Client and payments UX integrate with Stripe components and payment link flows.

Ops and constraints

  • Multi-store support (Fauna→Postgres migration) controlled via flags; services/read paths must respect flags.
  • Numbering and series must be unique per tenant/company; see resolvers that guard uniqueness.
  • PDFs: ensure correct locale, currency, and tax rules from settings.
  • Webhooks: keep idempotent; reconcile payment state with Stripe events.

Testing

  • Unit tests around expenses/profits/stats under _tests_/*.
  • Invoice/Payment resolver tests under _tests_ and server/graphql/resolvers/*/*.test.{js,ts}.
  • See docs/rebuild/14-testing-and-quality.md for running the suite.