From 774c72721efce889bc9afd74411d3b1e477d0ece Mon Sep 17 00:00:00 2001 From: Lars Kemper Date: Fri, 7 Aug 2026 15:16:06 +0200 Subject: [PATCH 1/4] feat: add document v2 dev docs --- .wordlist.txt | 6 + .../checkout-concept/document/architecture.md | 132 ++++++++++++++ .../document/extension-points.md | 47 +++++ .../checkout-concept/document/index.md | 38 +++++ guides/plugins/apps/checkout/document.md | 117 +++++++++++++ .../document-v2/add-a-document-type.md | 161 ++++++++++++++++++ .../document-v2/add-a-format-renderer.md | 93 ++++++++++ .../customize-document-data-and-templates.md | 110 ++++++++++++ .../plugins/checkout/document-v2/index.md | 33 ++++ .../document/add-custom-document-type.md | 4 + .../checkout/document/add-custom-document.md | 4 + .../plugins/checkout/document/index.md | 8 +- 12 files changed, 751 insertions(+), 2 deletions(-) create mode 100644 concepts/commerce/checkout-concept/document/architecture.md create mode 100644 concepts/commerce/checkout-concept/document/extension-points.md create mode 100644 concepts/commerce/checkout-concept/document/index.md create mode 100644 guides/plugins/apps/checkout/document.md create mode 100644 guides/plugins/plugins/checkout/document-v2/add-a-document-type.md create mode 100644 guides/plugins/plugins/checkout/document-v2/add-a-format-renderer.md create mode 100644 guides/plugins/plugins/checkout/document-v2/customize-document-data-and-templates.md create mode 100644 guides/plugins/plugins/checkout/document-v2/index.md diff --git a/.wordlist.txt b/.wordlist.txt index c1c9880664..f2fa4206cf 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -131,6 +131,7 @@ BuyButton CDN CDNs CHANGELOG +CII CKEditor CLI CMS @@ -350,6 +351,7 @@ Dockerfile Dockware DomainException DomainExceptions +Dompdf Dotenv DynamoDB ECDSA @@ -420,6 +422,7 @@ FLAC FPM FQCN FQDN +Factur FastRoute Fastly Fastly's @@ -1172,6 +1175,7 @@ XLIFF XMLHttpRequest XPath XQuartz +XRechnung XSS XVFB Xdebug @@ -1181,6 +1185,7 @@ XorRule YYYY YamlFileLoader ZSH +ZUGFeRD accel acl aclfacade @@ -2174,3 +2179,4 @@ zipignore zlib zsh zstd +zugferd diff --git a/concepts/commerce/checkout-concept/document/architecture.md b/concepts/commerce/checkout-concept/document/architecture.md new file mode 100644 index 0000000000..c9a7e56f7a --- /dev/null +++ b/concepts/commerce/checkout-concept/document/architecture.md @@ -0,0 +1,132 @@ +--- +nav: + title: Architecture + position: 20 +--- + +# Document generation architecture + +::: warning This page documents the new Document System (v2) +The reworked document generation is an experimental feature. Activate it with the `DOCUMENT_GENERATION_REWORK` feature flag. Its API can change until it becomes the default with Shopware 6.8. +::: + +## The generation pipeline + +```mermaid +flowchart TD + A["Generation request
orderId, documentType, formats"] --> B[DocumentGenerator] + B --> C["DocumentDependencyResolver
sorts requested formats into a render plan"] + B --> D["Data providers
every provider supporting the type"] + D --> E["Typed render data
one entry per provider key"] + C --> F["Render loop
one renderer per planned format"] + E --> F + F --> G["RenderState
collects one result per format"] + G --> H["DocumentPersister
document + document_file + media"] +``` + +A generation request carries an order ID, a document type, and the requested formats. `DocumentGenerator` orchestrates the rest. It loads the order once, with every matching data provider's search criteria merged in. + +The `DocumentDependencyResolver` turns the requested formats into a render plan, an ordered list that includes any formats other formats depend on. In parallel, `DocumentGenerator` asks every data provider (`AbstractDocumentDataProvider`) that supports the document type for its typed render data, keyed by provider key. + +The render loop then runs each renderer (`AbstractDocumentRenderer`) in the plan, writing its result into `RenderState`. Finally, `DocumentPersister` stores the document together with one `document_file` and one media entry per requested format. + +The document number comes from the number range type `document_`, unless the caller passes one explicitly. + +## Registries + +Three registries form the backbone of the domain. Each one is built from tagged services, so code defines what the system can generate. + +| Registry | Service tag | Resolution rule | +| ------------------------------ | ------------------------------- | --------------------------------------------------------------------------------------- | +| `DocumentTypeRegistry` | `shopware.document_v2.type` | One type per technical name. Validates that requested formats are supported by the type | +| `DocumentDataProviderRegistry` | `shopware.document_v2.provider` | All providers whose `supports()` matches the type run. Duplicate provider keys throw | +| `DocumentRendererRegistry` | `shopware.document_v2.renderer` | First renderer per format wins, ordered by tag priority | + +The renderer rule doubles as the override mechanism: register a renderer for an existing format with a higher tag priority, and it replaces the built-in one. + +## Render plans and format dependencies + +Renderers declare the formats they need through `getDependencies()`. A PDF renderer, for example, depends on the HTML renderer it prints from. The `DocumentDependencyResolver` reads these declarations and topologically sorts them into a render plan, so every prerequisite renders before the format that consumes it. + +```mermaid +flowchart LR + subgraph Requested + REQ[zugferd_embedded_pdf] + end + subgraph Render plan + H1["1 — html"] --> P1["2 — pdf"] + X1["3 — zugferd_xml"] + P1 --> Z1["4 — zugferd_embedded_pdf"] + X1 --> Z1 + end + REQ -. resolves to .-> H1 +``` + +## Render state + +Each generation run owns one `RenderState`. Every renderer in the plan writes exactly one result into it and reads its declared dependencies from it. + +The state lives only for the duration of the run: `DocumentPersister` copies the requested formats out of it, and dependency only intermediates are discarded with it. + +## Order versions and referenced documents + +Generating a document creates a new order version, which freezes the order state the document was generated from. A preview skips this and renders against the live version instead. + +Some document types render against another document rather than the current order. Credit notes and cancellation invoices reference an existing invoice through `referencedDocumentId` in the generation request. Their data providers declare this by implementing the `ReferencesDocument` marker interface. + +The `RendersReferencedSnapshot` interface goes one step further: a provider implementing it renders against the order version the referenced invoice was generated from. A cancellation invoice must invert exactly what the invoice billed, even if the order changed since. + +## Document types and formats + +Every document type supports a fixed set of formats. `storno` is the technical name for the cancellation invoice type: + +| Document type | Purpose | Formats | +| --------------- | ----------------------------------------------------------------------------- | -------------------------------------------- | +| `invoice` | Bills the order | html, pdf, zugferd_xml, zugferd_embedded_pdf | +| `delivery_note` | Accompanies the shipment. Requires a delivery date in the generation request | html, pdf | +| `credit_note` | Credits the credit line items of a referenced invoice | html, pdf, zugferd_xml, zugferd_embedded_pdf | +| `storno` | Cancels a referenced invoice by inverting its amounts | html, pdf, zugferd_xml, zugferd_embedded_pdf | + +`DocumentTypeRegistry` in code is the source of truth for this table and is the successor to the `document_type` database row for a type that remains to satisfy the foreign key. + +The formats build on each other. `html` is the base: a Twig template rendered with the document data. `pdf` prints that HTML through Dompdf. + +`zugferd_xml` is a structured e-invoice (EN 16931 CII syntax, XRechnung profile), meant for accounting software instead of human readers. `zugferd_embedded_pdf` combines both: a PDF/A-3 file with the ZUGFeRD XML embedded, readable as a normal PDF by humans and through the attached XML by machines. + +## Templates + +Every format that renders from a template does so through Twig. HTML templates live at `@Framework/documents/.html.twig`, with shared partials under `@Framework/documents/includes/`. + +The ZUGFeRD XML has its own template set at `@Framework/documents/zugferd/.xml.twig`. + +Both template sets are overridable with `sw_extends`, like any other template in Shopware. + +## Configuration + +`DocumentConfigLoader` builds the configuration a document is rendered with. It merges the global `document_base_config` row, the sales-channel override for the same row, and the company data from the `core.basicInformation` system config, then returns a typed `DocumentConfigBundle`. The loader reads the typed columns on `document_base_config` first and falls back to the legacy JSON `config` blob. + +## Storage + +```mermaid +erDiagram + document ||--o{ document_file : "one row per format" + document_file ||--|| media : "file content" + document { + uuid order_id + uuid order_version_id + string document_number + } + document_file { + uuid document_id + uuid media_id + string document_format + } +``` + +A `document` row represents one logical document: one order, one order version, one document number. Each requested format becomes its own `document_file` row, linked to the media entry that holds the actual file content. + +## Next steps + + + + diff --git a/concepts/commerce/checkout-concept/document/extension-points.md b/concepts/commerce/checkout-concept/document/extension-points.md new file mode 100644 index 0000000000..9452b8bb52 --- /dev/null +++ b/concepts/commerce/checkout-concept/document/extension-points.md @@ -0,0 +1,47 @@ +--- +nav: + title: Extension Points + position: 30 +--- + +# Document extension points + +::: warning This page documents the new Document System (v2) +The reworked document generation is an experimental feature. Activate it with the `DOCUMENT_GENERATION_REWORK` feature flag. Its API can change until it becomes the default with Shopware 6.8. +::: + +Document System (v2) extends through three tagged Symfony services and Twig template overrides. There is no service decoration. + +| You want to | Mechanism | +| -------------------------------- | ----------------------------- | +| Change how a document looks | Override a document template | +| Add data to an existing document | Enrich document data | +| Change how a format is produced | Override a built-in renderer | +| Output a new file format | Add a document format | +| Create a new kind of document | Add a document type | + +```mermaid +flowchart TD + A[Generation request] --> B[Render plan] + B --> C[Data providers] + C --> D[Renderers] + D --> E[Persistence] + T1(["Add a document type
shopware.document_v2.type"]) -.-> B + T2(["Enrich or provide data
shopware.document_v2.provider"]) -.-> C + T3(["Add or override a format
shopware.document_v2.renderer"]) -.-> D + T4(["Override Twig templates"]) -.-> D +``` + +Each extension point attaches to one stage of the pipeline: a document type shapes the render plan, a data provider feeds the render loop, and a renderer or a template override changes what that loop produces. + +## Extend with a plugin + +Plugins register the tagged services and override the templates directly: + + + +## Extend with an app + +Apps extend documents declaratively: the manifest registers a document type, Twig templates render it, and the `document-generation` script hook provides the data. Apps cannot add custom formats, renderers, or typed data providers, those stay plugin-only. + + diff --git a/concepts/commerce/checkout-concept/document/index.md b/concepts/commerce/checkout-concept/document/index.md new file mode 100644 index 0000000000..5b740a8243 --- /dev/null +++ b/concepts/commerce/checkout-concept/document/index.md @@ -0,0 +1,38 @@ +--- +nav: + title: Document (v2) + position: 40 +--- + +# Document (v2) + +::: warning This page documents the new Document System (v2) +The reworked document generation is an experimental feature. Activate it with the `DOCUMENT_GENERATION_REWORK` feature flag. Its API can change until it becomes the default with Shopware 6.8. +::: + +## What it is + +The Document System (v2) generates order related business documents: invoices, delivery notes, credit notes, and cancellation invoices. + +Each document can be generated in one or more file formats: HTML, PDF, ZUGFeRD XML, or ZUGFeRD-embedded PDF. Shopware stores the generated files per order. + +## Why a rewrite + +The previous document system (v1) coupled document type and file format, so every combination of type and format needed its own renderer. Adding a format meant touching every type, and adding a type meant touching every format. + +The Document System (v2) splits generation into three independent axes instead: + +```mermaid +flowchart TB + T["Document type
defines what is generated"] --> G[DocumentGenerator] + P["Data provider
defines which data goes in"] --> G + R["Renderer
defines which file format comes out"] --> G + G --> O["Stored document
one file per format"] +``` + +## ADRs + +- [Refactor of document generation](../../../../resources/references/adr/2026-03-17-refactor-of-document-generation.md): why v1 needed a rewrite and the goals for the new implementation. +- [New document generation architecture](../../../../resources/references/adr/2026-03-18-new-document-generation-architecture.md): the entity model and generation flow behind the v2 architecture. +- [New document generation extension points](../../../../resources/references/adr/2026-03-19-new-document-generation-extension-points.md): how plugins and apps add document types, data providers, and renderers. +- [Document generation v1 to v2 migration strategy](../../../../resources/references/adr/2026-08-05-document-generation-v1-to-v2-migration-strategy.md): how v1 and v2 coexist until v1 is removed in Shopware 6.9. diff --git a/guides/plugins/apps/checkout/document.md b/guides/plugins/apps/checkout/document.md new file mode 100644 index 0000000000..82b3bdc056 --- /dev/null +++ b/guides/plugins/apps/checkout/document.md @@ -0,0 +1,117 @@ +--- +nav: + title: Document (v2) + position: 120 +--- + +# Documents (v2) in apps + +::: warning This page documents the new Document System (v2) +The reworked document generation is an experimental feature. Activate it with the `DOCUMENT_GENERATION_REWORK` feature flag. Its API can change until it becomes the default with Shopware 6.8. +::: + +Apps extend the Document System (v2) declaratively: the manifest registers a document type, Twig templates render it, and an app script provides the data. + +**Prerequisites**: a running app (see the [app base guide](../app-base-guide)) and the `DOCUMENT_GENERATION_REWORK` feature flag enabled for testing. + +## Register a document type + +Declare the document type in the manifest. `identifier`, `label`, and `formats` are required. `config` is optional and falls back to defaults. + +```xml + + + swag_warranty + + + + html + pdf + + + a4 + portrait + 10 + true + true + + + +``` + +`formats` accepts the built-in formats only: `html`, `pdf`, `zugferd_xml`, and `zugferd_embedded_pdf`. + +Installing the app merges the type into the document type registry and seeds a number range of type `document_`. On update, changed manifest declarations are synchronized. Removed ones are deleted. + +The identifier is globally unique across all apps, installing an app that claims an identifier another app already registered fails. + +## Add the templates + +Templates ship with the app, in the same locations plugins use. The HTML template renders the `html`, `pdf`, and `zugferd_embedded_pdf` formats: + +::: code-group + +```twig [Resources/views/documents/swag_warranty.html.twig] +{% sw_extends '@Framework/documents/base.html.twig' %} + +{% block document_headline %} +

Warranty for order {{ order.orderNumber }}

+{% endblock %} +``` + +::: + +If the type offers `zugferd_xml` or `zugferd_embedded_pdf`, add the XML template as well: + +::: code-group + +```twig [Resources/views/documents/zugferd/swag_warranty.xml.twig] + + + {{ order.orderNumber }} + {{ meta.documentNumber }} + +``` + +::: + +App document types have no typed render data. Templates work with the loaded `order`, the shared document meta data, and whatever the app's script attaches to the order (next section). + +## Provide data with the document-generation script + +The `document-generation` script hook fires once per generation, after the order is loaded and the document number is allocated, before rendering starts. It exposes `order`, `documentType`, `documentNumber`, `formats`, and `context`, plus the `repository` and `config` facades for loading additional data. + +The script attaches data to the order as an extension: + +::: code-group + +```twig [Resources/scripts/document-generation/document-data.twig] +{% set order = hook.order %} + +{% do order.addArrayExtension('swag_warranty_data', { + 'warrantyEnd': order.orderDate|date_modify('+2 years')|date('Y-m-d'), + 'documentNumber': hook.documentNumber +}) %} +``` + +::: + +The document template reads the extension: + +```twig +

Warranty valid until {{ order.extensions.swag_warranty_data.get('warrantyEnd') }}

+``` + +## Enrich built-in documents + +The same combination works for documents the app did not register: the script's `supports` check is up to you, `hook.documentType` tells you which type is being generated, and the visual side is a regular Twig override of the built-in template. + +## Limits + +**No custom formats or renderers.** Apps choose from the four built-in formats. + +**No typed data providers.** The script hook and order extensions replace the plugin-side `AbstractDocumentDataProvider`. + +**No configuration UI.** The `config` block in the manifest is the only configuration surface for app document types. + +**Number ranges persist.** Uninstalling the app deletes its document types, but never the number ranges, reinstalling must not reuse document numbers. diff --git a/guides/plugins/plugins/checkout/document-v2/add-a-document-type.md b/guides/plugins/plugins/checkout/document-v2/add-a-document-type.md new file mode 100644 index 0000000000..c73f0020be --- /dev/null +++ b/guides/plugins/plugins/checkout/document-v2/add-a-document-type.md @@ -0,0 +1,161 @@ +--- +nav: + title: Add a Document Type + position: 20 +--- + +# Add a document type + +::: warning This page documents the new Document System (v2) +The reworked document generation is an experimental feature. Activate it with the `DOCUMENT_GENERATION_REWORK` feature flag. Its API can change until it becomes the default with Shopware 6.8. +::: + +You define the type, provide the data it renders, register both as services and add a template. + +## Create the document type + +A document type declares its technical name and the formats it can be rendered in. + +::: code-group + +```php [PLUGIN_ROOT/src/Core/Checkout/Document/ExampleDocumentType.php] +addAssociation('lineItems'); + } + + public function provideRenderingData(ProviderInput $input, Context $context): AbstractRenderData + { + return new ExampleRenderData( + noteText: 'Thank you for your order!', + ); + } +} +``` + +::: + +## Register the services + +Tag the type and the provider so the registries in Document v2 pick them up. + +::: code-group + +```php [PLUGIN_ROOT/src/Resources/config/services.php] +services(); + + $services->set(ExampleDocumentType::class) + ->tag('shopware.document_v2.type'); + + $services->set(ExampleDocumentDataProvider::class) + ->tag('shopware.document_v2.provider'); +}; +``` + +::: + +## Add the template + +The HTML renderer resolves `@Framework/documents/.html.twig` for the technical name you declared. The DTO's `noteText` from above renders as `config.noteText`. + +::: code-group + +```twig [PLUGIN_ROOT/src/Resources/views/documents/example_document.html.twig] +{% sw_extends '@Framework/documents/base.html.twig' %} + +{% block document_headline %} +

Example document {{ documentNumber }}

+

{{ config.noteText }}

+{% endblock %} +``` + +::: + +Types that offer the `zugferd_xml` format additionally need an XML template at `PLUGIN_ROOT/src/Resources/views/documents/zugferd/example_document.xml.twig`, resolved the same way. + +## Create the database entries + +Two database rows are still required outside of the code above: a `document_type` row whose `technical_name` matches your type, since the `document` table has a foreign key on it, and a number range of type `document_example_document` to number the generated documents. + +The migration code is identical to v1. Reuse the [document type migration](../document/add-custom-document-type#adding-a-custom-document-type-and-its-own-base-configuration-to-the-database) and the [number range migration](../document/add-custom-document-type#adding-a-number-range) from the v1 guide, and swap in your own technical name. diff --git a/guides/plugins/plugins/checkout/document-v2/add-a-format-renderer.md b/guides/plugins/plugins/checkout/document-v2/add-a-format-renderer.md new file mode 100644 index 0000000000..39a8e05760 --- /dev/null +++ b/guides/plugins/plugins/checkout/document-v2/add-a-format-renderer.md @@ -0,0 +1,93 @@ +--- +nav: + title: Add a Format Renderer + position: 30 +--- + +# Add a format renderer + +::: warning This page documents the new Document System (v2) +The reworked document generation is an experimental feature. Activate it with the `DOCUMENT_GENERATION_REWORK` feature flag. Its API can change until it becomes the default with Shopware 6.8. +::: + +## Add a new format + +A renderer produces exactly one format. `getDependencies()` lists the formats that must render first, so their results are available in `RenderState` when your renderer runs. + +The example below adds a plain-text format. It depends on `html` and derives its content by stripping tags from the already-rendered HTML result. + +::: code-group + +```php [PLUGIN_ROOT/src/Core/Checkout/Document/TextRenderer.php] +require('html'); + + return new RenderResult( + $this->getFormat(), + strip_tags($html->content), + sprintf('%s_txt', $input->documentNumber), + $this->getFileExtension(), + 'text/plain', + ); + } +} +``` + +```php [PLUGIN_ROOT/src/Resources/config/services.php] +services() + ->set(TextRenderer::class) + ->tag('shopware.document_v2.renderer'); +}; +``` + +::: + +A format only becomes selectable once a document type lists it in `getSupportedFormats()`. See [add a document type](./add-a-document-type) for that step. + +## Override a built-in renderer + +The renderer registry keeps the first renderer registered per format. Renderers are ordered by tag priority. Register your renderer for the same format string with a higher priority to replace a built-in one. + +This replaces v1's `getDecorated()` decoration chains. + +```php +$container->services() + ->set(CustomPdfRenderer::class) + ->tag('shopware.document_v2.renderer', ['priority' => 100]); +``` + +`CustomPdfRenderer` extends `AbstractDocumentRenderer` with `getFormat()` returning `pdf`. It fully replaces the built-in `PdfRenderer`, including its `html` dependency declaration. diff --git a/guides/plugins/plugins/checkout/document-v2/customize-document-data-and-templates.md b/guides/plugins/plugins/checkout/document-v2/customize-document-data-and-templates.md new file mode 100644 index 0000000000..5c875b3bd4 --- /dev/null +++ b/guides/plugins/plugins/checkout/document-v2/customize-document-data-and-templates.md @@ -0,0 +1,110 @@ +--- +nav: + title: Customize Document Data and Templates + position: 40 +--- + +# Customize document data and templates + +::: warning This page documents the new Document System (v2) +The reworked document generation is an experimental feature. Activate it with the `DOCUMENT_GENERATION_REWORK` feature flag. Its API can change until it becomes the default with Shopware 6.8. +::: + +## Add data to an existing document + +Any number of providers can support the same document type. Each provider stores its render data DTO under its own key, and public fields on that DTO are flattened onto the template's `config` variable. + +If a key is already used by another provider for the same document type, generation throws an exception. + +The example below adds a note to the built-in invoice. + +::: code-group + +```php [PLUGIN_ROOT/src/Core/Checkout/Document/InvoiceNoteRenderData.php] +order; + + return new InvoiceNoteRenderData( + invoiceNote: sprintf('Please quote order %s in all correspondence.', $order->getOrderNumber()), + ); + } +} +``` + +```php [PLUGIN_ROOT/src/Resources/config/services.php] +services() + ->set(InvoiceNoteDataProvider::class) + ->tag('shopware.document_v2.provider'); +}; +``` + +::: + +## Override a document template + +Templates live at `@Framework/documents/` and are overridden with `sw_extends`, the same mechanism used everywhere else in Shopware. The invoice template exposes blocks from `base.html.twig` and the `includes/` partials, so overriding `invoice.html.twig` gives access to all of them. + +The same templates render for every format that needs HTML, so a change to `invoice.html.twig` reaches the HTML, PDF, and ZUGFeRD-embedded-PDF output alike. + +The example below appends the note from the provider above to the invoice footer. + +::: code-group + +```twig [PLUGIN_ROOT/src/Resources/views/documents/invoice.html.twig] +{% sw_extends '@Framework/documents/invoice.html.twig' %} + +{% block document_footer %} + {{ parent() }} +

{{ config.invoiceNote }}

+{% endblock %} +``` + +::: + +The ZUGFeRD XML templates under `@Framework/documents/zugferd/` are overridden the same way. + +Templates are shared with the v1 document system during the transition, overrides apply to both systems. diff --git a/guides/plugins/plugins/checkout/document-v2/index.md b/guides/plugins/plugins/checkout/document-v2/index.md new file mode 100644 index 0000000000..7abd9cf0f0 --- /dev/null +++ b/guides/plugins/plugins/checkout/document-v2/index.md @@ -0,0 +1,33 @@ +--- +nav: + title: Document (v2) + position: 25 +--- + +# Document (v2) in plugins + +::: warning This page documents the new Document System (v2) +The reworked document generation is an experimental feature. Activate it with the `DOCUMENT_GENERATION_REWORK` feature flag. Its API can change until it becomes the default with Shopware 6.8. +::: + +These guides show how to extend the Document System (v2) as a plugin developer. + +**Prerequisites**: a running plugin (see the [plugin base guide](../../plugin-base-guide)) and the `DOCUMENT_GENERATION_REWORK` feature flag enabled for testing. + +## Add a document type + +Create a new kind of document: a type class, a data provider, a Twig template, and the number range that numbers it. + + + +## Add a format renderer + +Output a new file format, or replace a built-in renderer through tag priority. + + + +## Customize document data and templates + +Add data to documents you did not create, and override the Twig templates that render them. + + diff --git a/guides/plugins/plugins/checkout/document/add-custom-document-type.md b/guides/plugins/plugins/checkout/document/add-custom-document-type.md index cf2d16e4cd..2ee554e89b 100644 --- a/guides/plugins/plugins/checkout/document/add-custom-document-type.md +++ b/guides/plugins/plugins/checkout/document/add-custom-document-type.md @@ -7,6 +7,10 @@ nav: # Add Custom Document Type +::: warning Deprecated for 6.9 +This page documents the v1 document system. It is deprecated and will be removed with Shopware 6.9. Its successor, the Document System (v2), is available as an experimental feature since Shopware 6.7. See the [Document System (v2) concept](../../../../../concepts/commerce/checkout-concept/document/) and the [v2 guides](../document-v2/). +::: + ## Overview This guide will show you how to add a custom document type to your plugin. This includes adding a new document type to the database, creating a renderer for it, and adding a number range. diff --git a/guides/plugins/plugins/checkout/document/add-custom-document.md b/guides/plugins/plugins/checkout/document/add-custom-document.md index ed88f0386a..d1ee97ef39 100644 --- a/guides/plugins/plugins/checkout/document/add-custom-document.md +++ b/guides/plugins/plugins/checkout/document/add-custom-document.md @@ -7,6 +7,10 @@ nav: # Add Custom Document +::: warning Deprecated for 6.9 +This page documents the v1 document system. It is deprecated and will be removed with Shopware 6.9. Its successor, the Document System (v2), is available as an experimental feature since Shopware 6.7. See the [Document System (v2) concept](../../../../../concepts/commerce/checkout-concept/document/) and the [v2 guides](../document-v2/). +::: + ## Overview Using the Shopware Administration, you can easily create new documents. This guide explains how to create a new document using a plugin. diff --git a/guides/plugins/plugins/checkout/document/index.md b/guides/plugins/plugins/checkout/document/index.md index fc78c14fb5..762a566e95 100644 --- a/guides/plugins/plugins/checkout/document/index.md +++ b/guides/plugins/plugins/checkout/document/index.md @@ -1,10 +1,14 @@ --- nav: - title: Document + title: Document (v1) position: 20 --- -# Document +# Document (v1) + +::: warning Deprecated for 6.9 +This page documents the v1 document system. It is deprecated and will be removed with Shopware 6.9. Its successor, the Document System (v2), is available as an experimental feature since Shopware 6.7. See the [Document System (v2) concept](../../../../../concepts/commerce/checkout-concept/document/) and the [v2 guides](../document-v2/). +::: Document as a plugin in Shopware refers to the essential capabilities of generating and managing documents within the e-commerce platform. These functions are typically part of the core Shopware system but can be extended or customized using plugins. From 7ebeff1231bbf7429b1c1a4983b9bdf42390af70 Mon Sep 17 00:00:00 2001 From: Lars Kemper Date: Fri, 7 Aug 2026 15:22:47 +0200 Subject: [PATCH 2/4] fix: spellcheck --- .wordlist.txt | 1 - concepts/commerce/checkout-concept/document/index.md | 11 +++++++++++ .../checkout/document-v2/add-a-document-type.md | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.wordlist.txt b/.wordlist.txt index f2fa4206cf..6e17ab7f34 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -422,7 +422,6 @@ FLAC FPM FQCN FQDN -Factur FastRoute Fastly Fastly's diff --git a/concepts/commerce/checkout-concept/document/index.md b/concepts/commerce/checkout-concept/document/index.md index 5b740a8243..07a088b23a 100644 --- a/concepts/commerce/checkout-concept/document/index.md +++ b/concepts/commerce/checkout-concept/document/index.md @@ -30,6 +30,17 @@ flowchart TB G --> O["Stored document
one file per format"] ``` +## Availability + +The Document System (v2) rolls out over three releases: it starts as an opt-in feature, becomes the default, and finally replaces v1. + +```mermaid +flowchart LR + A["6.7 — Opt-in
enable DOCUMENT_GENERATION_REWORK
v1 stays the default"] --> B["6.8 — Default
flag on by default, API stabilizes
v1 still available"] --> C["6.9 — Only system
v1 removed"] +``` + +The [migration strategy ADR](../../../../resources/references/adr/2026-08-05-document-generation-v1-to-v2-migration-strategy.md) covers how v1 and v2 coexist during this window. + ## ADRs - [Refactor of document generation](../../../../resources/references/adr/2026-03-17-refactor-of-document-generation.md): why v1 needed a rewrite and the goals for the new implementation. diff --git a/guides/plugins/plugins/checkout/document-v2/add-a-document-type.md b/guides/plugins/plugins/checkout/document-v2/add-a-document-type.md index c73f0020be..b00e524a9f 100644 --- a/guides/plugins/plugins/checkout/document-v2/add-a-document-type.md +++ b/guides/plugins/plugins/checkout/document-v2/add-a-document-type.md @@ -137,7 +137,7 @@ return static function (ContainerConfigurator $container): void { ## Add the template -The HTML renderer resolves `@Framework/documents/.html.twig` for the technical name you declared. The DTO's `noteText` from above renders as `config.noteText`. +The HTML renderer resolves `@Framework/documents/.html.twig` for the technical name you declared. The DTOs `noteText` from above renders as `config.noteText`. ::: code-group From 9cb680645d18de847ac80a8a4a8b81eeb513cf54 Mon Sep 17 00:00:00 2001 From: Lars Kemper Date: Tue, 11 Aug 2026 13:52:32 +0200 Subject: [PATCH 3/4] refactor: relocate document plugin docs --- .../checkout-concept/document/architecture.md | 2 +- .../checkout-concept/document/extension-points.md | 2 +- .../commerce/checkout-concept/document/index.md | 12 ++++++------ guides/plugins/plugins/checkout/document/index.md | 14 -------------- guides/plugins/plugins/checkout/documents/index.md | 13 +++++++++++++ .../legacy}/add-custom-document-type.md | 10 +++++----- .../legacy}/add-custom-document.md | 4 ++-- .../plugins/checkout/documents/legacy/index.md | 14 ++++++++++++++ .../v2}/add-a-document-type.md | 2 +- .../v2}/add-a-format-renderer.md | 2 +- .../v2}/customize-document-data-and-templates.md | 2 +- .../{document-v2 => documents/v2}/index.md | 8 ++++---- 12 files changed, 49 insertions(+), 36 deletions(-) delete mode 100644 guides/plugins/plugins/checkout/document/index.md create mode 100644 guides/plugins/plugins/checkout/documents/index.md rename guides/plugins/plugins/checkout/{document => documents/legacy}/add-custom-document-type.md (96%) rename guides/plugins/plugins/checkout/{document => documents/legacy}/add-custom-document.md (90%) create mode 100644 guides/plugins/plugins/checkout/documents/legacy/index.md rename guides/plugins/plugins/checkout/{document-v2 => documents/v2}/add-a-document-type.md (93%) rename guides/plugins/plugins/checkout/{document-v2 => documents/v2}/add-a-format-renderer.md (97%) rename guides/plugins/plugins/checkout/{document-v2 => documents/v2}/customize-document-data-and-templates.md (96%) rename guides/plugins/plugins/checkout/{document-v2 => documents/v2}/index.md (86%) diff --git a/concepts/commerce/checkout-concept/document/architecture.md b/concepts/commerce/checkout-concept/document/architecture.md index c9a7e56f7a..bb81de561b 100644 --- a/concepts/commerce/checkout-concept/document/architecture.md +++ b/concepts/commerce/checkout-concept/document/architecture.md @@ -129,4 +129,4 @@ A `document` row represents one logical document: one order, one order version, - + diff --git a/concepts/commerce/checkout-concept/document/extension-points.md b/concepts/commerce/checkout-concept/document/extension-points.md index 9452b8bb52..b19a48e426 100644 --- a/concepts/commerce/checkout-concept/document/extension-points.md +++ b/concepts/commerce/checkout-concept/document/extension-points.md @@ -38,7 +38,7 @@ Each extension point attaches to one stage of the pipeline: a document type shap Plugins register the tagged services and override the templates directly: - + ## Extend with an app diff --git a/concepts/commerce/checkout-concept/document/index.md b/concepts/commerce/checkout-concept/document/index.md index 07a088b23a..14be60fd78 100644 --- a/concepts/commerce/checkout-concept/document/index.md +++ b/concepts/commerce/checkout-concept/document/index.md @@ -18,7 +18,7 @@ Each document can be generated in one or more file formats: HTML, PDF, ZUGFeRD X ## Why a rewrite -The previous document system (v1) coupled document type and file format, so every combination of type and format needed its own renderer. Adding a format meant touching every type, and adding a type meant touching every format. +The legacy document system coupled document type and file format, so every combination of type and format needed its own renderer. Adding a format meant touching every type, and adding a type meant touching every format. The Document System (v2) splits generation into three independent axes instead: @@ -32,18 +32,18 @@ flowchart TB ## Availability -The Document System (v2) rolls out over three releases: it starts as an opt-in feature, becomes the default, and finally replaces v1. +The Document System (v2) rolls out over three releases: it starts as an opt-in feature, becomes the default, and finally replaces the legacy system. ```mermaid flowchart LR - A["6.7 — Opt-in
enable DOCUMENT_GENERATION_REWORK
v1 stays the default"] --> B["6.8 — Default
flag on by default, API stabilizes
v1 still available"] --> C["6.9 — Only system
v1 removed"] + A["6.7 — Opt-in
enable DOCUMENT_GENERATION_REWORK
legacy stays the default"] --> B["6.8 — Default
flag on by default, API stabilizes
legacy still available"] --> C["6.9 — Only system
legacy removed"] ``` -The [migration strategy ADR](../../../../resources/references/adr/2026-08-05-document-generation-v1-to-v2-migration-strategy.md) covers how v1 and v2 coexist during this window. +The [migration strategy ADR](../../../../resources/references/adr/2026-08-05-document-generation-v1-to-v2-migration-strategy.md) covers how the legacy system and v2 coexist during this window. ## ADRs -- [Refactor of document generation](../../../../resources/references/adr/2026-03-17-refactor-of-document-generation.md): why v1 needed a rewrite and the goals for the new implementation. +- [Refactor of document generation](../../../../resources/references/adr/2026-03-17-refactor-of-document-generation.md): why the legacy system needed a rewrite and the goals for the new implementation. - [New document generation architecture](../../../../resources/references/adr/2026-03-18-new-document-generation-architecture.md): the entity model and generation flow behind the v2 architecture. - [New document generation extension points](../../../../resources/references/adr/2026-03-19-new-document-generation-extension-points.md): how plugins and apps add document types, data providers, and renderers. -- [Document generation v1 to v2 migration strategy](../../../../resources/references/adr/2026-08-05-document-generation-v1-to-v2-migration-strategy.md): how v1 and v2 coexist until v1 is removed in Shopware 6.9. +- [Document generation v1 to v2 migration strategy](../../../../resources/references/adr/2026-08-05-document-generation-v1-to-v2-migration-strategy.md): how the two systems coexist until the legacy one is removed in Shopware 6.9. diff --git a/guides/plugins/plugins/checkout/document/index.md b/guides/plugins/plugins/checkout/document/index.md deleted file mode 100644 index 762a566e95..0000000000 --- a/guides/plugins/plugins/checkout/document/index.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -nav: - title: Document (v1) - position: 20 - ---- - -# Document (v1) - -::: warning Deprecated for 6.9 -This page documents the v1 document system. It is deprecated and will be removed with Shopware 6.9. Its successor, the Document System (v2), is available as an experimental feature since Shopware 6.7. See the [Document System (v2) concept](../../../../../concepts/commerce/checkout-concept/document/) and the [v2 guides](../document-v2/). -::: - -Document as a plugin in Shopware refers to the essential capabilities of generating and managing documents within the e-commerce platform. These functions are typically part of the core Shopware system but can be extended or customized using plugins. diff --git a/guides/plugins/plugins/checkout/documents/index.md b/guides/plugins/plugins/checkout/documents/index.md new file mode 100644 index 0000000000..52421b0b81 --- /dev/null +++ b/guides/plugins/plugins/checkout/documents/index.md @@ -0,0 +1,13 @@ +--- +nav: + title: Documents + position: 20 +--- + +# Documents + +Shopware is moving from the legacy document system to the reworked Document System (v2). Pick the guide for the system you target. + + + + diff --git a/guides/plugins/plugins/checkout/document/add-custom-document-type.md b/guides/plugins/plugins/checkout/documents/legacy/add-custom-document-type.md similarity index 96% rename from guides/plugins/plugins/checkout/document/add-custom-document-type.md rename to guides/plugins/plugins/checkout/documents/legacy/add-custom-document-type.md index 2ee554e89b..ed9eb49cac 100644 --- a/guides/plugins/plugins/checkout/document/add-custom-document-type.md +++ b/guides/plugins/plugins/checkout/documents/legacy/add-custom-document-type.md @@ -8,7 +8,7 @@ nav: # Add Custom Document Type ::: warning Deprecated for 6.9 -This page documents the v1 document system. It is deprecated and will be removed with Shopware 6.9. Its successor, the Document System (v2), is available as an experimental feature since Shopware 6.7. See the [Document System (v2) concept](../../../../../concepts/commerce/checkout-concept/document/) and the [v2 guides](../document-v2/). +This page documents the legacy document system. It is deprecated and will be removed with Shopware 6.9. Its successor, the Document System (v2), is available as an experimental feature since Shopware 6.7. See the [Document System (v2) concept](../../../../../../concepts/commerce/checkout-concept/document/) and the [v2 guides](../v2/). ::: ## Overview @@ -17,7 +17,7 @@ This guide will show you how to add a custom document type to your plugin. This ## Prerequisites -Reviewing the [plugin base guide](../../plugin-base-guide) and the guide on [plugin database migrations](../../database/database-migrations.md) is advisable. +Reviewing the [plugin base guide](../../../plugin-base-guide) and the guide on [plugin database migrations](../../../database/database-migrations.md) is advisable. ## Adding a custom document type and its own base configuration to the database @@ -172,7 +172,7 @@ Your custom document renderer has to implement the `Shopware\Core\Checkout\Docum * `supports`: Has to return a string of the document type it supports. We named our document type "**example**", so our renderer has to return "**example**". * `render`: This needs to return the instance `Shopware\Core\Checkout\Document\Renderer\RendererResult`, which will contain the instance of `Shopware\Core\Checkout\Document\Renderer\RenderedDocument` based on each `orderId`. You will have access to the array of `DocumentGenerateOperation` which contains all respective orderIds, the context and the instance of `Shopware\Core\Checkout\Document\Renderer\DocumentRendererConfig` (additional configuration). -Furthermore, your renderer has to be registered to the [service container](../../services/dependency-injection.md) using the tag `document.renderer`. +Furthermore, your renderer has to be registered to the [service container](../../../services/dependency-injection.md) using the tag `document.renderer`. An example renderer: @@ -421,13 +421,13 @@ In there, you should extend from the default document base template: ::: -The [base.html.twig](https://github.com/shopware/shopware/blob/v6.3.4.1/src/Core/Framework/Resources/views/documents/base.html.twig) template comes with a default templating, which you can now override by using blocks. The guide on [customizing templates](../../storefront/templates/customize-templates.md) provides more details. +The [base.html.twig](https://github.com/shopware/shopware/blob/v6.3.4.1/src/Core/Framework/Resources/views/documents/base.html.twig) template comes with a default templating, which you can now override by using blocks. The guide on [customizing templates](../../../storefront/templates/customize-templates.md) provides more details. ## Adding a number range You are almost done here. You have a new document type in the database, a renderer for your new document type, and it even uses a custom template. However, you also need to add a new number range for your documents; otherwise, a new number wouldn't be generated for your documents. -Adding a new number range is also done by using a [plugin database migration](../../database/database-migrations.md). +Adding a new number range is also done by using a [plugin database migration](../../../database/database-migrations.md). For this we need a few more things: diff --git a/guides/plugins/plugins/checkout/document/add-custom-document.md b/guides/plugins/plugins/checkout/documents/legacy/add-custom-document.md similarity index 90% rename from guides/plugins/plugins/checkout/document/add-custom-document.md rename to guides/plugins/plugins/checkout/documents/legacy/add-custom-document.md index d1ee97ef39..918033edad 100644 --- a/guides/plugins/plugins/checkout/document/add-custom-document.md +++ b/guides/plugins/plugins/checkout/documents/legacy/add-custom-document.md @@ -8,7 +8,7 @@ nav: # Add Custom Document ::: warning Deprecated for 6.9 -This page documents the v1 document system. It is deprecated and will be removed with Shopware 6.9. Its successor, the Document System (v2), is available as an experimental feature since Shopware 6.7. See the [Document System (v2) concept](../../../../../concepts/commerce/checkout-concept/document/) and the [v2 guides](../document-v2/). +This page documents the legacy document system. It is deprecated and will be removed with Shopware 6.9. Its successor, the Document System (v2), is available as an experimental feature since Shopware 6.7. See the [Document System (v2) concept](../../../../../../concepts/commerce/checkout-concept/document/) and the [v2 guides](../v2/). ::: ## Overview @@ -17,7 +17,7 @@ Using the Shopware Administration, you can easily create new documents. This gui ## Prerequisites -Reviewing the [plugin base guide](../../plugin-base-guide) and the guide on [plugin database migrations](../../database/database-migrations.md) is advisable. +Reviewing the [plugin base guide](../../../plugin-base-guide) and the guide on [plugin database migrations](../../../database/database-migrations.md) is advisable. ## Adding a custom document diff --git a/guides/plugins/plugins/checkout/documents/legacy/index.md b/guides/plugins/plugins/checkout/documents/legacy/index.md new file mode 100644 index 0000000000..8260795653 --- /dev/null +++ b/guides/plugins/plugins/checkout/documents/legacy/index.md @@ -0,0 +1,14 @@ +--- +nav: + title: Legacy + position: 20 + +--- + +# Legacy document system + +::: warning Deprecated for 6.9 +This page documents the legacy document system. It is deprecated and will be removed with Shopware 6.9. Its successor, the Document System (v2), is available as an experimental feature since Shopware 6.7. See the [Document System (v2) concept](../../../../../../concepts/commerce/checkout-concept/document/) and the [v2 guides](../v2/). +::: + +Document as a plugin in Shopware refers to the essential capabilities of generating and managing documents within the e-commerce platform. These functions are typically part of the core Shopware system but can be extended or customized using plugins. diff --git a/guides/plugins/plugins/checkout/document-v2/add-a-document-type.md b/guides/plugins/plugins/checkout/documents/v2/add-a-document-type.md similarity index 93% rename from guides/plugins/plugins/checkout/document-v2/add-a-document-type.md rename to guides/plugins/plugins/checkout/documents/v2/add-a-document-type.md index b00e524a9f..4e1d76d68f 100644 --- a/guides/plugins/plugins/checkout/document-v2/add-a-document-type.md +++ b/guides/plugins/plugins/checkout/documents/v2/add-a-document-type.md @@ -158,4 +158,4 @@ Types that offer the `zugferd_xml` format additionally need an XML template at ` Two database rows are still required outside of the code above: a `document_type` row whose `technical_name` matches your type, since the `document` table has a foreign key on it, and a number range of type `document_example_document` to number the generated documents. -The migration code is identical to v1. Reuse the [document type migration](../document/add-custom-document-type#adding-a-custom-document-type-and-its-own-base-configuration-to-the-database) and the [number range migration](../document/add-custom-document-type#adding-a-number-range) from the v1 guide, and swap in your own technical name. +The migration code is identical to the legacy system. Reuse the [document type migration](../legacy/add-custom-document-type#adding-a-custom-document-type-and-its-own-base-configuration-to-the-database) and the [number range migration](../legacy/add-custom-document-type#adding-a-number-range) from the legacy guide, and swap in your own technical name. diff --git a/guides/plugins/plugins/checkout/document-v2/add-a-format-renderer.md b/guides/plugins/plugins/checkout/documents/v2/add-a-format-renderer.md similarity index 97% rename from guides/plugins/plugins/checkout/document-v2/add-a-format-renderer.md rename to guides/plugins/plugins/checkout/documents/v2/add-a-format-renderer.md index 39a8e05760..c7b75facdb 100644 --- a/guides/plugins/plugins/checkout/document-v2/add-a-format-renderer.md +++ b/guides/plugins/plugins/checkout/documents/v2/add-a-format-renderer.md @@ -82,7 +82,7 @@ A format only becomes selectable once a document type lists it in `getSupportedF The renderer registry keeps the first renderer registered per format. Renderers are ordered by tag priority. Register your renderer for the same format string with a higher priority to replace a built-in one. -This replaces v1's `getDecorated()` decoration chains. +This replaces the legacy system's `getDecorated()` decoration chains. ```php $container->services() diff --git a/guides/plugins/plugins/checkout/document-v2/customize-document-data-and-templates.md b/guides/plugins/plugins/checkout/documents/v2/customize-document-data-and-templates.md similarity index 96% rename from guides/plugins/plugins/checkout/document-v2/customize-document-data-and-templates.md rename to guides/plugins/plugins/checkout/documents/v2/customize-document-data-and-templates.md index 5c875b3bd4..356f884ca8 100644 --- a/guides/plugins/plugins/checkout/document-v2/customize-document-data-and-templates.md +++ b/guides/plugins/plugins/checkout/documents/v2/customize-document-data-and-templates.md @@ -107,4 +107,4 @@ The example below appends the note from the provider above to the invoice footer The ZUGFeRD XML templates under `@Framework/documents/zugferd/` are overridden the same way. -Templates are shared with the v1 document system during the transition, overrides apply to both systems. +Templates are shared with the legacy document system during the transition, overrides apply to both systems. diff --git a/guides/plugins/plugins/checkout/document-v2/index.md b/guides/plugins/plugins/checkout/documents/v2/index.md similarity index 86% rename from guides/plugins/plugins/checkout/document-v2/index.md rename to guides/plugins/plugins/checkout/documents/v2/index.md index 7abd9cf0f0..d850cc3a24 100644 --- a/guides/plugins/plugins/checkout/document-v2/index.md +++ b/guides/plugins/plugins/checkout/documents/v2/index.md @@ -1,10 +1,10 @@ --- nav: - title: Document (v2) - position: 25 + title: v2 + position: 10 --- -# Document (v2) in plugins +# Document System (v2) ::: warning This page documents the new Document System (v2) The reworked document generation is an experimental feature. Activate it with the `DOCUMENT_GENERATION_REWORK` feature flag. Its API can change until it becomes the default with Shopware 6.8. @@ -12,7 +12,7 @@ The reworked document generation is an experimental feature. Activate it with th These guides show how to extend the Document System (v2) as a plugin developer. -**Prerequisites**: a running plugin (see the [plugin base guide](../../plugin-base-guide)) and the `DOCUMENT_GENERATION_REWORK` feature flag enabled for testing. +**Prerequisites**: a running plugin (see the [plugin base guide](../../../plugin-base-guide)) and the `DOCUMENT_GENERATION_REWORK` feature flag enabled for testing. ## Add a document type From fa69d65e502f559f1f601983bd0796b90f0c8fa3 Mon Sep 17 00:00:00 2001 From: Lars Kemper Date: Thu, 13 Aug 2026 15:12:17 +0200 Subject: [PATCH 4/4] fix: legacy index Co-authored-by: Micha Hobert --- guides/plugins/plugins/checkout/documents/legacy/index.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/guides/plugins/plugins/checkout/documents/legacy/index.md b/guides/plugins/plugins/checkout/documents/legacy/index.md index 8260795653..f97720b346 100644 --- a/guides/plugins/plugins/checkout/documents/legacy/index.md +++ b/guides/plugins/plugins/checkout/documents/legacy/index.md @@ -10,5 +10,3 @@ nav: ::: warning Deprecated for 6.9 This page documents the legacy document system. It is deprecated and will be removed with Shopware 6.9. Its successor, the Document System (v2), is available as an experimental feature since Shopware 6.7. See the [Document System (v2) concept](../../../../../../concepts/commerce/checkout-concept/document/) and the [v2 guides](../v2/). ::: - -Document as a plugin in Shopware refers to the essential capabilities of generating and managing documents within the e-commerce platform. These functions are typically part of the core Shopware system but can be extended or customized using plugins.