Skip to content

2025-11-21: Invoice Generation Fix & Module Refactor

Probleem: Dubbele Facturen (Pending + Paid)

User 44 had 4 facturen voor 2 orders: - VG-2025-024 (pending) + VG-2025-023 (paid) voor order 27 - VG-2025-022 (pending) + VG-2025-021 (paid) voor order 26

Oorzaak

Commerce Invoice module genereerde automatisch facturen bij: 1. Order placed (validation → pending) via OrderPlacedSubscriber 2. Order paid (Mollie callback) via status update

Resultaat: 2 invoices per order (1 pending, 1 paid).

Oplossing

Custom Event Subscriber die alleen facturen genereert bij betaalde orders:

  1. Automatische generatie uitgeschakeld:

    ddrush config:set commerce_order.commerce_order_type.default \
      third_party_settings.commerce_invoice.order_placed_generation false -y
    

  2. Custom subscriber (OrderPaidInvoiceSubscriber):

  3. Luistert naar commerce_order.order.paid event
  4. Checkt of invoice al bestaat (voorkomt duplicaten)
  5. Genereert invoice alleen voor betaalde orders

Implementatie

Bestand: /web/modules/custom/vg_commerce/src/EventSubscriber/OrderPaidInvoiceSubscriber.php

Service registratie in vg_commerce.services.yml:

vg_commerce.order_paid_invoice_subscriber:
  class: Drupal\vg_commerce\EventSubscriber\OrderPaidInvoiceSubscriber
  arguments: ['@commerce_invoice.invoice_generator', '@entity_type.manager']
  tags:
    - { name: event_subscriber }

Cleanup

Pending invoices verwijderd (alleen dev, productie: credit notes!): - VG-2025-002, 016, 022, 024 (pending)

User 44 heeft nu 2 correcte paid invoices: - VG-2025-021 voor order 26 - VG-2025-023 voor order 27

Module Refactor: vg_commerce_tax → vg_commerce

Reden

Module vg_commerce_tax bevatte meer dan alleen tax logic: - Tax rate resolver (BTW 21% NL, 0% buiten NL) - Shipping tax subscriber - Invoice generation subscriber - Gin theme fixes (invoice page crash) - Checkout conditional fields

Naam was misleidend → hernoemen naar vg_commerce.

Hernoem Proces

  1. Module uninstall (config behouden)
  2. Directory + files hernoemen
  3. Namespaces updaten (Drupal\vg_commerce_taxDrupal\vg_commerce)
  4. Services updaten (vg_commerce_tax.*vg_commerce.*)
  5. Hook functions hernoemen (vg_commerce_tax_*vg_commerce_*)
  6. Module reinstall

Module Structuur

web/modules/custom/vg_commerce/
├── vg_commerce.info.yml
├── vg_commerce.module (hooks: menu_links, preprocess_page, form_alter)
├── vg_commerce.services.yml
└── src/
    ├── TaxRateResolver.php
    └── EventSubscriber/
        ├── ShippingTaxSubscriber.php
        └── OrderPaidInvoiceSubscriber.php

Services

  • vg_commerce.tax_rate_resolver - BTW berekening
  • vg_commerce.shipping_tax_subscriber - BTW op verzendkosten
  • vg_commerce.order_paid_invoice_subscriber - Invoice generatie bij betaling

Boekhoudregels

Belangrijk: Facturen NOOIT zomaar verwijderen in productie! - Gebruik credit notes/credit facturen - Verwijderen alleen in dev voor cleanup - Factuurnummers moeten sequentieel blijven

Testing

Test scenario: 1. Maak nieuwe order als authenticated user 2. Betaal via Mollie sandbox 3. Verifieer: 1 invoice met status "paid" (geen pending duplicate)

ECA Opmerking

Commerce Invoice module heeft geen native ECA actions voor invoice generation. Daarom custom Event Subscriber gebruikt (betrouwbaarder, geen UI overhead).