2025-12-29 B2B BTW Fix, Verzending Staffel & DNS Setup¶
Datum: 2025-12-29 Status: Completed Focus: B2B belasting berekening, verzendkosten staffel, domein configuratie
Samenvatting¶
Cruciale doorbraak bereikt met B2B BTW berekening: patch toegepast waardoor promoties correct worden berekend VOOR BTW in plaats van erna. Daarnaast verzendkosten staffel gebouwd met configureerbare UI voor NL/BE/wereld, en hoofddomein voedingsgeneeskunde.nl geconfigureerd voor live gang.
B2B BTW Berekening Fix¶
Probleem¶
Commerce berekende BTW incorrect voor B2B shop: - Prijs excl. BTW -> BTW toevoegen -> Promotie toepassen - Dit resulteerde in verkeerde kortingsbedragen
Correcte B2B flow: - Prijs excl. BTW -> Promotie toepassen -> BTW toevoegen
Oplossing: Patch #2982355¶
Issue: https://www.drupal.org/project/commerce/issues/2982355
Patch: commerce-tax_processor-2982355-61.patch (2025-10-09)
Patch splitst TaxOrderProcessor in twee processors:
- EarlyTaxOrderProcessor (priority 300) - voor B2C included tax
- LateTaxOrderProcessor (priority 50) - voor B2B excluded tax
Installatie:
cd /var/www/sites/dev.voedingsgeneeskunde/web/modules/contrib/commerce
wget https://www.drupal.org/files/issues/2025-10-09/commerce-tax_processor-2982355-61.patch
patch -p1 < commerce-tax_processor-2982355-61.patch
Composer integratie:
Patch toegevoegd aan composer.json onder extra.patches:
"drupal/commerce": {
"B2B tax calculation - apply promotions before tax #2982355": "https://www.drupal.org/files/issues/2025-10-09/commerce-tax_processor-2982355-61.patch"
}
Tax Type Configuratie¶
Kritieke instelling voor B2B:
Voor: display_inclusive: true - BTW included in prijzen (B2C)
Na: display_inclusive: false - BTW apart berekend (B2B)
Resultaat¶
Correcte B2B berekening nu actief:
Voorbeeld: Los nummer (€9,13) + VGBC ticket (€49,95) + Verzending (€4,10) met 33% studentkorting
Los nummer: €9,13 excl. BTW
VGBC ticket: €49,95 excl. BTW
Studentkorting: -€16,48 (33% van €49,95)
Verzending: €4,10 excl. BTW
---
Subtotaal: €46,70 excl. BTW
BTW 9%: €0,82 (op €9,13)
BTW 21%: €7,90 (op €33,47 + €4,10)
---
Totaal: €55,42
Verificatie: - Los nummer: geen korting (correct - alleen tickets krijgen korting) - VGBC ticket: korting VOOR BTW (correct) - BTW split: 9% en 21% apart (correct) - Verzending: verschijnt in checkout (correct)
Verzendkosten Staffel¶
Requirement¶
Staffel voor losse nummers per land en aantal:
Nederland: - 1 exemplaar: €4,25 - 2-5 exemplaren: €5,95 - 6-10 exemplaren: €7,50 - Meer dan 10: €9,00
België: - 1 exemplaar: €7,95 - 2-5 exemplaren: €10,50 - 6-10 exemplaren: €13,00 - Meer dan 10: Op aanvraag
Rest van de wereld: - 1 exemplaar: €11,90 - 2-5 exemplaren: €17,00 - 6-10 exemplaren: €23,00 - Meer dan 10: Op aanvraag
Implementatie¶
Custom Shipping Plugin:
/web/modules/custom/vg_commerce/src/Plugin/Commerce/ShippingMethod/TieredShipping.php
Features:
- Telt alleen los_nummer product variation type
- Land-specifieke tarieven (NL/BE/wereld)
- Configureerbare UI via shipping method form
- "Op aanvraag" optie voor >10 exemplaren (retourneert NULL = geen verzending mogelijk)
Configuratie UI elementen:
Per land 4 velden: - 1 exemplaar (required) - 2-5 exemplaren (required) - 6-10 exemplaren (required) - Meer dan 10 (conditional - alleen zichtbaar als checkbox "Op aanvraag" uit staat)
Checkbox "Op aanvraag": - Aangevinkt: geen verzending mogelijk voor >10, klant moet contact opnemen - Uitgevinkt: toont prijsveld voor >10 exemplaren
Aanpassen prijzen:
Shop managers kunnen tarieven wijzigen via:
/admin/commerce/config/shipping-methods/1/edit
Geen code wijzigingen nodig - alles via UI configureerbaar.
DNS & Domain Setup¶
Domein Migratie¶
Hoofddomein voedingsgeneeskunde.nl vrijgemaakt van oude site en gekoppeld aan nieuwe Drupal 11 platform.
Apache Configuratie¶
Nieuwe vhost: voedingsgeneeskunde.nl.conf
<VirtualHost *:80>
ServerName voedingsgeneeskunde.nl
ServerAlias www.voedingsgeneeskunde.nl
DocumentRoot /var/www/sites/live.voedingsgeneeskunde.nl/web
# Redirect to HTTPS
RewriteEngine on
RewriteCond %{SERVER_NAME} =voedingsgeneeskunde.nl [OR]
RewriteCond %{SERVER_NAME} =www.voedingsgeneeskunde.nl
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
SSL certificaat:
Drupal Trusted Hosts¶
settings.php aangepast:
$settings['trusted_host_patterns'] = [
'^d8dev\.voedingsgeneeskunde\.nl$',
'^nieuw\.voedingsgeneeskunde\.nl$',
'^voedingsgeneeskunde\.nl$',
'^www\.voedingsgeneeskunde\.nl$',
];
Subdomain Redirect¶
nieuw.voedingsgeneeskunde.nl redirect permanent naar hoofddomein voor consistentie.
Nieuwe configs:
- nieuw.voedingsgeneeskunde-redirect.conf (HTTP)
- nieuw.voedingsgeneeskunde-redirect-ssl.conf (HTTPS)
Conflict opgelost:
Oude d8_dev-le-ssl.conf had ook ServerName voor nieuw subdomain. Deze disabled:
DNS Propagatie¶
DNS wijziging doorgevoerd:
voedingsgeneeskunde.nl A-record -> 37.97.221.249 (VPS IP)
Propagatietijd: 24-48 uur (afhankelijk van TTL en DNS caching)
Gebruikersbeheer¶
User Profile Issue¶
User 46 (Joost Angemelt) had geen toegang tot profiel paginas na aanmaken via admin UI.
Diagnose: - Geen customer profile (ID 166) - Geen openbaar profile (ID 167) - Profile hooks werden niet getriggerd bij admin user creation
Oplossing: Profielen handmatig aangemaakt via Drush:
drush php:eval "
\$profile_storage = \Drupal::entityTypeManager()->getStorage('profile');
\$customer = \$profile_storage->create([
'type' => 'customer',
'uid' => 46,
'is_default' => TRUE,
'status' => TRUE,
]);
\$customer->save();
"
Field Beroep Locatie¶
Context¶
field_beroep (beroep field) staat nu in openbaar profile maar moet naar customer profile.
Redenen: 1. Gebruikt voor StudentProfessionCondition (33% korting) 2. Marketing/business data, niet publieke info 3. StudentProfessionCondition checkt al beide profile types
Actiepunt: Collega zal field migratie handmatig uitvoeren (field verplaatsen van openbaar -> customer profile).
Inzichten & Technische Details¶
Commerce Tax Calculation Order¶
Standaard Commerce flow (B2C): 1. Product base price 2. Tax toevoegen (included) 3. Promotions toepassen
B2B flow (met patch): 1. Product base price 2. Promotions toepassen 3. Tax toevoegen (excluded)
Key config:
- display_inclusive: false zorgt dat tax niet in unit_price wordt gebakken
- Patch zorgt voor juiste processor volgorde via priority settings
- EarlyTaxOrderProcessor: priority 300 (hoog = vroeg)
- LateTaxOrderProcessor: priority 50 (laag = laat)
Shipping Method Architecture¶
Standard Drupal Commerce shipping methods:
- flat_rate - vast tarief
- flat_rate_per_item - per item tarief
- Geen out-of-the-box support voor tiered pricing
Custom plugin extends:
- ShippingMethodBase
- Implementeert calculateRates(ShipmentInterface $shipment)
- Haalt country code uit shipping profile address
- Telt quantity van specifieke variation type
Plugin discovery:
- Annotatie: @CommerceShippingMethod
- PSR-4 autoloading via namespace
- Cache clear nodig na nieuwe plugin
DNS & Hosting¶
IP adres: 37.97.221.249 (TransIP VPS)
Subdomains actief:
- dev.voedingsgeneeskunde.nl - development
- design.voedingsgeneeskunde.nl - design mockups
- docs.voedingsgeneeskunde.nl - documentatie (deze site)
- joost.voedingsgeneeskunde.nl - test environment
- redactie.voedingsgeneeskunde.nl - redactie backend
- voedingsgeneeskunde.nl - live production (nieuw)
- nieuw.voedingsgeneeskunde.nl - redirect naar main (backwards compatibility)
Oude subdomains verwijderd:
- d8dev.voedingsgeneeskunde.nl
- d8live.voedingsgeneeskunde.nl
Bestanden Gewijzigd¶
Core Files¶
/web/modules/contrib/commerce/- patch toegepastcomposer.json- patch referentie toegevoegd
Custom Code¶
/web/modules/custom/vg_commerce/src/Plugin/Commerce/ShippingMethod/TieredShipping.php- NEW
Configuration¶
/web/sites/default/settings.php- trusted_host_patterns- Commerce tax type BTW:
display_inclusive: false
Apache¶
/etc/apache2/sites-available/voedingsgeneeskunde.nl.conf- NEW/etc/apache2/sites-available/voedingsgeneeskunde.nl-le-ssl.conf- NEW (Certbot)/etc/apache2/sites-available/nieuw.voedingsgeneeskunde-redirect.conf- NEW/etc/apache2/sites-available/nieuw.voedingsgeneeskunde-redirect-ssl.conf- NEW
Testing Checklist¶
- B2B BTW berekening correct (korting voor BTW)
- BTW split 9%/21% werkt
- Los nummer: geen korting
- VGBC ticket: wel korting
- Verzending verschijnt in checkout
- Verzending staffel configureerbaar via UI
- Hoofddomein voedingsgeneeskunde.nl bereikbaar
- SSL certificaat actief
- Subdomain nieuw redirect naar main
- Trusted hosts ingesteld
- DNS propagatie voltooid (in progress - 24-48u)
Volgende Stappen¶
Prioriteit 1: Testing¶
- VGBC Fase 2 testing (4 scenarios)
- BTW verificatie op orders >=56
- Views configuratie review winkel
- Verzending staffel testen met verschillende landen/aantallen
Prioriteit 2: Cleanup¶
- Hardcoded waarden check (StandhouderQuotaValidator)
- Field_partner verificatie op customer profiles
Prioriteit 3: Live Migration¶
Webshop gaat morgen/overmorgen live: 1. Config export 2. Database backup 3. Oude test orders opschonen 4. Productieconfiguratie Mollie 5. DNS check (voedingsgeneeskunde.nl propagatie)
Toekomst: Fase 3¶
- Multi-ticket checkout (meerdere attendees)
- QR codes + commerce_license integratie
- Student korting per attendee (niet per order)
- TicketAssignmentPane voor attendee gegevens
Links & Resources¶
Drupal.org Issues: - Commerce #2982355 - B2B Tax Calculation
Related Sessions: - 2025-12-28 BTW Prijsweergave Fix - 2025-12-16 Fase 2 Testing Checklist
Documentation: - Commerce Overview - Patches Overview
Tags¶
commerce tax btw b2b shipping dns apache ssl patch tiered-pricing