← Blog

Magento

Magento 2 naar Shopware 6: 17 stille catalogus-valkuilen

Een Antwerpse B2B-catalogus, 6.200 SKU's, in één weekend van Magento 2 naar Shopware 6. De importer logde nul fouten. Dinsdagmiddag klopten de B2B-prijzen niet.

Jacob Molkenboer· Oprichter · A Brand New Company· 12 aug 2024· 9 min
Open leren grootboek met geschreven prijskolommen, groen zijden lint, koperen sleutel op kaart, rood verzendlabel op ivoorpapier.

De migratie zou het rustige stuk worden. We hadden vier developers, een bevroren Magento 2.4.6 staging-kopie van de catalogus van een Antwerpse groothandel (6.200 SKU's, veertien klantgroepen, drie talen) en een Shopware 6.6 target met de officiële Migration Assistant klaargezet. De importer draaide zaterdagnacht. Zondagochtend stond op het dashboard: 6.217 producten geïmporteerd. Nul rode regels, nul waarschuwingen. We meldden de klant dat het klaar was en gingen offline.

Dinsdagmiddag belde de B2B-accountmanager. Elke Reseller-prijs toonde de openbare adviesprijs. De Pro-klantgroep, die netto bedragen hoorde te zien, kreeg bedragen inclusief btw. De bestseller, een industriële kit van 25 liter in drie verpakkingsmaten, stond met drie wezen-varianten in de catalogus en had geen hoofdproduct.

De Migration Assistant had niet gelogen. Hij deed wat elke importer tussen twee niet-triviale e-commerceplatforms doet: mappen wat hij kent, een default zetten voor wat hij niet kent, en de rest stilhouden. Dit is de cheatsheet die we toen graag hadden gehad.

Waarom stille fouten de gevaarlijke categorie zijn

De Migration Assistant van Shopware is eerlijk over harde fouten. Ongeldige UTF-8, missende verplichte velden, kapotte foreign keys: die gooien een error, loggen het en zetten de worker stop. De valkuilen hieronder zijn anders. Stuk voor stuk leveren ze een geslaagde import op. De data komt netjes in de database. Alleen verkeerd, op een manier die pas drie tot veertien dagen later boven water komt, meestal via een mail van een klant of een afstemming bij finance.

We hebben gerangschikt op stilte, niet op frequentie. Nummer één is de valkuil met de grootste kans op een groen vinkje plus een incident op maandagochtend. Nummer zeventien vang je in je eerste smoke-test.

Waarschuwing

De succes-teller van de Migration Assistant meet weggeschreven rijen, niet behouden betekenis. Behandel hem als een vrachtbon, niet als een QA-rapport.

De zeventien valkuilen, gerangschikt op stilte

  1. Staffelprijzen per klantgroep. Magento slaat staffelprijzen op per (product, customer_group_id, qty) in catalog_product_entity_tier_price. Shopware 6 kent geen native group-staffel op de product-entity. De assistant schrijft ze in de B2B Suite Advanced Prices module als je de licentie hebt, en laat ze stilletjes vallen als dat niet zo is. De productpagina toont alsnog een prijs. Het is de adviesprijs.
  2. Netto versus bruto klantgroepen. Magento bepaalt netto-versus-bruto weergave via store-config plus de tax class van de klantgroep. Shopware 6 heeft één boolean op de groep zelf (displayGross). De assistant zet die standaard op true voor elke geïmporteerde groep. Een reseller-groep die in Magento netto was, toont in Shopware nu prijzen inclusief btw. De waarden in de database kloppen, op het scherm zit je er 21% naast.
  3. Multi-source voorraad platgeslagen tot één getal. Op Magento 2.3+ met MSI heeft elke SKU rijen in inventory_source_item per magazijn. Shopware 6 slaat voorraad op als één integer op het product, waarbij warehousing naar plugins wordt geschoven. De assistant telt de bronnen op. Een SKU met 12 in Antwerpen en 0 in Rotterdam komt binnen als 12 beschikbaar. Vandaag waar, vals zodra de doos in Antwerpen verzonden is.
  4. Speciale prijzen met datumbereik. Magento respecteert special_price_from en special_price_to op de storefront. De assistant zet de aanbieding in de listPrice- en price-velden van Shopware, en gooit het datumbereik weg. Je Black Friday-korting wordt de permanente juni-prijs.
  5. Tax classes gematcht op naam, niet op tarief. Als je Magento tax classes 'Taxable Goods' heten en de Shopware-target 'Standard rate', matcht de assistant op string. Alles wat niet matcht, krijgt standaard de UUID van het standaardtarief. Carttotalen ogen goed omdat de meeste producten op hetzelfde tarief landen. De per-product breakdown klopt niet voor artikelen met verlaagd tarief.
  6. Configurable-hoofdproducten gekoppeld aan de verkeerde simples. De assistant mapt Magento configurable products op hoofdproducten in Shopware, en child-simples op varianten. Als het configurator-attribuut (maat, kleur) in stap één niet als configurator-relevante property meeverhuisd is, gokt de variantkoppeling op SKU-patroon. Wezen-simples verschijnen in de catalogus zonder hoofdproduct.
  7. Bundelproducten verdampen of vallen uiteen. Het bundle-producttype van Magento heeft geen native equivalent in Shopware 6. De assistant slaat bundels over (alleen een regel in het foutenlog als je verbose hebt aangezet) of importeert de componenten als losse simples. Je bundel-SKU houdt op te bestaan. De simples vind je via zoek; de landingspagina van de bundel geeft 404.
  8. Downloadable products raken hun bestanden kwijt. De tabellen downloadable_link en downloadable_link_purchased van Magento hebben geen analogon in Shopware. De assistant importeert het product als standaardartikel, zonder digitale vlag, zonder bestand en zonder downloadhistorie voor eerdere klanten.
  9. URL-rewrites en historische 301's. De url_rewrite-tabel van Magento bevat jaren aan categorie-hernoemingen, gewijzigde productslugs en handmatige 301's. De assistant migreert de huidige canonieke slugs en negeert de rewrite-historie. Elke oude URL geeft 404, tenzij je zelf een importer in seo_url schrijft (zie de Shopware SEO-docs).
  10. Fabrikant-attribuut uiteengevallen in duplicaten. Manufacturer in Magento is een EAV-dropdown met optielabels. Shopware heeft een eersteklas manufacturer-entity met naam en slug. De assistant maakt één manufacturer per uniek label. Schrijfvarianten in de bron ('3M', '3M Industrial', '3M ') worden drie aparte merken met drie merkenpagina's.
  11. EAN custom-attribuut niet op de native EAN-kolom gemapt. De meeste Magento-catalogi slaan EAN/GTIN op als custom tekstattribuut genaamd ean of barcode. Shopware 6 heeft een native ean-veld op het product. De assistant mapt custom op custom en laat de native kolom NULL. Je Google Shopping-feed gaat de deur uit zonder GTIN's en Merchant Center vlagt de hele feed.
  12. Layered nav-properties geïmporteerd als niet-filterbaar. Magento-attributen dragen is_filterable=1. Property groups in Shopware hebben een filterable-boolean. De assistant kopieert de property en laat filterable=false staan. Categoriepagina's renderen, de filter-sidebar is leeg, conversie zakt.
  13. Cross-sells en up-sells vallen plat tot lege streams. De catalog_product_link van Magento bewaart related, cross-sell en up-sell paren. Shopware 6 representeert die als cross-selling entities met een product stream of een handmatige lijst. De assistant maakt de entities aan en vergeet de producten te koppelen. De productpagina rendert het cross-sell-blok; het blok is leeg.
  14. Decimaal-attributen met komma als scheidingsteken. Continentale Magento-catalogi slaan decimalen vaak op als '12,5' in varchar-EAV-cellen. Shopware verwacht een punt in decimal-velden. De assistant cast wat kan en schrijft stilletjes 0 voor wat niet kan. Gewichten, afmetingen en literwaardes komen op nul terecht op ongeveer 1% van de rijen.
  15. Custom options op simples. De catalog_product_option van Magento dekt per-product extra's: graveertekst, cadeauverpakking, lengte op maat. Shopware 6 heeft custom field sets en product features, geen van beide een directe match. De assistant gooit de hele catalog_product_option-structuur weg. Het bestelformulier verliest het invoerveld.
  16. Productzichtbaarheid teruggebracht. Magento kent vier visibility-waarden: not visible, catalog only, search only, catalog and search. Shopware 6 heeft één active-boolean plus de categoriekoppeling. De assistant zet elk zichtbaar product op active. Search-only producten die je bewust uit de categoriepagina's hield, staan nu overal.
  17. Gewichtseenheid aangenomen als kg. Magento slaat gewicht op in de eenheid die store-config aangeeft (meestal kg, soms g voor kleine onderdelen). Shopware 6 slaat gewicht op in kg, punt. Een catalogus die op grammen staat, komt binnen alsof elk getal kilo's zijn. Een zakje van 250 g wordt een pallet van 250 kg en de verzendberekening klapt voor de hele categorie.

De pre-flight diff die ons vier dagen had gescheeld

Het patroon onder alle zeventien is hetzelfde: het bronschema heeft structuur die het doel niet native modelleert. De oplossing is geen slimmere importer. Het is een audit van vijf queries die je vóór de migratie op je Magento-database draait en daarna opnieuw op Shopware.

-- Run on Magento 2 source, then compare each count on the Shopware target.
SELECT 'tier_prices' AS k, COUNT(*) AS n FROM catalog_product_entity_tier_price
UNION ALL SELECT 'special_prices', COUNT(*) FROM catalog_product_entity_decimal
  WHERE attribute_id = (SELECT attribute_id FROM eav_attribute
    WHERE attribute_code = 'special_price' AND entity_type_id = 4)
UNION ALL SELECT 'configurables', COUNT(*) FROM catalog_product_entity WHERE type_id = 'configurable'
UNION ALL SELECT 'bundles', COUNT(*) FROM catalog_product_entity WHERE type_id = 'bundle'
UNION ALL SELECT 'downloadables', COUNT(*) FROM catalog_product_entity WHERE type_id = 'downloadable'
UNION ALL SELECT 'msi_stock_rows', COUNT(*) FROM inventory_source_item
UNION ALL SELECT 'url_rewrites', COUNT(*) FROM url_rewrite WHERE entity_type IN ('product','category')
UNION ALL SELECT 'custom_options', COUNT(*) FROM catalog_product_option
UNION ALL SELECT 'cross_sells', COUNT(*) FROM catalog_product_link WHERE link_type_id = 5;

Draai het equivalent na de import op Shopware 6 (product_price voor advanced prices, seo_url voor rewrites, product_cross_selling gejoined met product_cross_selling_assigned_products voor daadwerkelijk gekoppelde cross-sells) en vergelijk regel voor regel. Is een getal kleiner op de target, dan heb je een stille valkuil. De query draait in dertig seconden en levert het contract op waar je importer zich aan moet houden.

Eén voetnoot bij de stack-keuze

Shopware 6 is een geloofwaardig Magento-alternatief in de EU juist omdat het Europees is: hoofdkantoor in Berlijn, GDPR-native, met een prijsmodel dat geen Adobe Commerce-contract vereist. De herpositionering van Magento onder Adobe heeft mid-market merchants in de band van €1M tot €50M GMV serieus naar alternatieven laten kijken, en Shopware is de meest voor de hand liggende bestemming. Groothandels in Antwerpen, Eindhoven en Düsseldorf volgen dezelfde redenering om dezelfde reden, en de bovenstaande catalogus-valkuilen zijn de tol die ze onderweg betalen.

Het kleinste wat je vandaag kunt doen

Heb je een Magento 2 naar Shopware 6 op de roadmap staan? Draai de audit-query hierboven vanmiddag op je bron-database en plak de negen getallen in een gedeelde sheet. Toen wij de migratie naar Shopware 6 voor de Antwerpse groothandel deden, was de valkuil die het hardst beet de netto-versus-bruto-vlag op klantgroepen. De fix kostte twintig minuten zodra we wisten welke producten geraakt waren; uitzoeken welke producten geraakt waren, kostte zonder die pre-flight diff vier dagen.

Kern

De succes-teller van de Shopware Migration Assistant meet weggeschreven rijen, niet behouden betekenis. Vergelijk de database voordat je het groene vinkje vertrouwt.

FAQ

Waarschuwt de Shopware Migration Assistant je voor stille drops?

Nee. De Assistant logt alleen harde fouten zoals kapotte foreign keys, ontbrekende verplichte velden of encoding-problemen. Alles wat naar een default-waarde of een ontbrekend doelveld mapt, importeert als succes.

Heb je de Shopware B2B Suite nodig om prijzen per klantgroep te behouden?

Voor staffelprijzen per groep op productniveau: ja. Zonder B2B Suite is Rule Builder de dichtstbijzijnde native optie, en die prijst op conditie, niet per groep. Reken de licentie van B2B Suite mee in de migratiekosten.

Wat is de veiligste testvolgorde na de import?

Draai eerst de pre-flight count-diff. Steekproef daarna tien SKU's volledig door: prijs per klantgroep, voorraad per magazijn, variantkoppeling, fabrikant-slug, EAN-veld en de 301's van oude URL's. Slagen die, dan kun je de steekproef verbreden.

Kan de Migration Assistant Magento 1-catalogi aan?

Niet rechtstreeks. Magento 1 vergt een tussenstap: export naar CSV via een connector, of eerst naar Magento 2 en dan de Shopware-assistant. De catalogus-valkuilen gelden ook bij die tweede hop.

Hoe lang duurt zo'n migratie van 6.000 SKU's in de praktijk?

De technische import draait in uren. De semantische audit, de mapping-fixes, het opnieuw inladen van B2B-prijzen, de redirect-map voor URL's en de afstemming van klantgroepen kostten ons team grofweg drie weken geconcentreerd werk.

magentomigratione-commercelegacy sitesarchitecture

Iets bouwen?

Start een project