Verzending¶
De transportkosten van een bestelling worden bepaald via Transsmart, dat in deze
shop via de Odoo-middleware wordt aangesproken. De prijs komt primair uit Odoo; lukt
dat niet, dan valt de berekening terug op de DB-tabel order_transport_price. Deze
pagina beschrijft hoe de transportprijs tot stand komt, hoe een verzending wordt
geboekt, en welk gedrag de huidige code feitelijk vertoont rond niet-leverbare landen.
Transportkeuze in de checkout¶
Elke klant heeft een standaard-Transport op zijn entiteit
(customer->getTransport()). In de checkout toont de actie transportDelivery
(_core/controller/classes/atx/customers/cart/CartController.php rond regel 780) twee
keuzes: het standaardtransport van de klant of afhalen ('00'). De gekozen transport
wordt bij createOrder gevalideerd tegen ['00', customer->getTransport()->getId()].
Of een transport via Transsmart loopt, hangt af van
Transport::isTranssmart() (_core/model/classes/atx/orders/Transport.php:549), dat
controleert of de OdooId gelijk is aan '-129'. Is dat het geval, dan loopt de
prijsbepaling via de Transsmart-stack; anders rechtstreeks via de DB-tabel.
Transportprijs bepalen¶
Het startpunt is Cart::calculateTransportCost()
(_core/model/classes/atx/customers/cart/Cart.php:644), dat delegeert naar
ShippingRateCalculatorManager
(src/Atraxion/Shipping/ShippingRateCalculatorManager.php). Die manager bevat een
circuit breaker en routeert tussen Transsmart en de DB-fallback:
flowchart TD
A["Cart::calculateTransportCost()"] --> M{ShippingRateCalculatorManager}
M -->|transport niet Transsmart| DB[DefaultShippingRateCalculator]
M -->|circuit open| DB
M -->|anders| C[CachedShippingRateCalculator session-cache]
C --> H["HasFreeShippingCalculator snelle check 2s"]
H -->|prijs bekend| R1[ShippingRate = max colli/pallet]
H -->|timeout of prijs onbekend| D["TranssmartShippingRateCalculator diepe check 15s"]
D --> R2[ShippingRate uit NShift shipment lines]
H -.->|prijs 0 en Never free shipping| EX[TransportNotAvailableException]
D -.->|prijs 0 en warning_message| CB[circuit opent en DB-fallback]
DB --> DBT[(order_transport_price)]
Snelle check (HasFreeShippingCalculator)¶
HasFreeShippingCalculator (src/Transsmart/Service/HasFreeShippingCalculator.php)
bouwt een TransportSellingConfig-DTO uit de winkelwagen, het land, het channel en de
transport-/betaalinfo, en roept Odoo aan via
DynAppsAPI::getTransportSellingConfig() met een timeout van 2 seconden (endpoint
/api/v1/get_transport_selling_config).
Slaagt de check en is transport_price_unknown == false
(HasFreeShippingCalculator.php:97), dan is de prijs
max(unit_price_colli, unit_price_pallet) (:98). Time-out de check, of geeft Odoo
transport_price_unknown == true terug, dan valt de berekening door naar de diepe check
(:112).
Diepe check (TranssmartShippingRateCalculator)¶
De fallback (src/Transsmart/Service/TranssmartShippingRateCalculator.php) bouwt een
volledige OrderDTO en roept DynAppsAPI::getNShiftShipmentLines() aan met een
timeout van 15 seconden (endpoint /api/v1/get_nshift_shipment_lines). Het antwoord
wordt via NShiftShipmentLinesResponse::toShippingRate() omgezet naar een
ShippingRate.
DB-fallback (order_transport_price)¶
Wanneer het transport niet via Transsmart loopt, of wanneer de circuit breaker open
staat, gebruikt DefaultShippingRateCalculator
(src/Atraxion/Shipping/ShippingRateCalculator.php) de DB-tabel via
CountryColliPriceDAO::getByCountryIsoCodeAndTransport()
(_core/model/dbclasses/atx/orders/CountryColliPriceDAO.php:197).
De tabel order_transport_price (entiteit
_core/model/classes/atx/orders/CountryColliPrice.php) bevat onder meer
countryIsoCode, franco (grens vanaf wanneer transport gratis is), buyPrice,
sellPrice, vlaggen forCompany/sepa/vip, een transport-FK,
weightBasedPrices (JSON) en een is_default-rij per land. De lookup gebeurt op
(countryIsoCode, transport-id, sepa, forCompany) met terugval op de
is_default-rij van het land.
Geen harde landen-gate¶
De huidige code blokkeert een land niet op verzendniveau, behalve in één precieze situatie. Het feitelijke gedrag:
- Op het snelle-checkpad wordt
warning_messageuitTransportSellingConfigResultwél gedeserialiseerd (src/Transsmart/DataTransfer/TransportSellingConfigResult.php:15), maar nooit gelezen door enige aanroeper. Een niet-nul prijs uit Odoo wordt altijd geaccepteerd, ongeacht een eventuele waarschuwing. - Een prijs van €0 wordt geaccepteerd en als gratis verzending behandeld. De enige
uitzondering is de tegenstrijdige combinatie prijs
<= 0énxx_free_shipping_comment === 'Never free shipping'; alleen dan wordt eenTransportNotAvailableExceptiongegooid (HasFreeShippingCalculator.php:103). - Op het diepe-checkpad gooit
NShiftShipmentLinesResponse::toShippingRate()alleen een exception als drie condities tegelijk gelden:sales_price === 0, énwarning_messageis aanwezig (isset), énmb_strlen(warning_message) > 1(NShiftShipmentLinesResponse.php:27). Een lege of éénkarakter-bericht triggert de exception dus niet. Die exception blokkeert de bestelling niet — het opent de circuit breaker en schakelt over op de DB-prijs.
Concreet: voor een land als Noorwegen kan Odoo €0 met een waarschuwing teruggeven,
maar tenzij de comment exact 'Never free shipping' is, vat de code dit op als gratis
verzending en gaat de bestelling door. Het Transsmart-pad vertrouwt dus de Odoo-prijs;
het land zelf wordt niet als gate gebruikt.
Verzending boeken na de bestelling¶
Het boeken van de verzending verloopt synchroon binnen het webrequest, zonder queue:
CartController::doFinishOrder()(CartController.phprond regel 1688) roeptOrderService::sendOrderToErp()aan (_core/model/classes/atx/orders/OrderService.php:1125).sendOrderToErp()roeptUploadOrders::uploadSingle()aan (OrderService.php:1149).UploadOrders(src/Odoo/Service/UploadOrders.php) bouwt eenOrderDTOmet onder meerxx_transsmart_costcenter_idendelivery_method, en voegt eventueel gecachete NShift-verzendregels uitOrder::getNShiftShipmentLines()toe.- De DTO wordt naar de Odoo-middleware gePОST; Odoo triggert de NShift/Transsmart-boeking aan zijn kant.
Het kostencentrum (xx_transsmart_costcenter_id) volgt een prioriteitsvolgorde: het
transport van de channel-eigenaar → de verzendmethode van het platform → het transport
van de klant → de harde fallback 22.
Zie ook¶
- Winkelwagen & checkout — waar de transportkeuze gebeurt.
- Bestellingen & orderverwerking — het doorsturen naar de ERP.
- Integraties — Transsmart en Odoo technisch.