Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ BuyButton
CDN
CDNs
CHANGELOG
CII
CKEditor
CLI
CMS
Expand Down Expand Up @@ -350,6 +351,7 @@ Dockerfile
Dockware
DomainException
DomainExceptions
Dompdf
Dotenv
DynamoDB
ECDSA
Expand Down Expand Up @@ -1172,6 +1174,7 @@ XLIFF
XMLHttpRequest
XPath
XQuartz
XRechnung
XSS
XVFB
Xdebug
Expand All @@ -1181,6 +1184,7 @@ XorRule
YYYY
YamlFileLoader
ZSH
ZUGFeRD
accel
acl
aclfacade
Expand Down Expand Up @@ -2174,3 +2178,4 @@ zipignore
zlib
zsh
zstd
zugferd
132 changes: 132 additions & 0 deletions concepts/commerce/checkout-concept/document/architecture.md
Original file line number Diff line number Diff line change
@@ -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<br>orderId, documentType, formats"] --> B[DocumentGenerator]
B --> C["DocumentDependencyResolver<br>sorts requested formats into a render plan"]
B --> D["Data providers<br>every provider supporting the type"]
D --> E["Typed render data<br>one entry per provider key"]
C --> F["Render loop<br>one renderer per planned format"]
E --> F

Check warning on line 22 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L22

Possible typo: you repeated a word (ENGLISH_WORD_REPEAT_RULE) Suggestions: `F` Rule: https://community.languagetool.org/rule/show/ENGLISH_WORD_REPEAT_RULE?lang=en-US Category: MISC
Raw output
concepts/commerce/checkout-concept/document/architecture.md:22:10: Possible typo: you repeated a word (ENGLISH_WORD_REPEAT_RULE)
 Suggestions: `F`
 Rule: https://community.languagetool.org/rule/show/ENGLISH_WORD_REPEAT_RULE?lang=en-US
 Category: MISC
F --> G["RenderState<br>collects one result per format"]
G --> H["DocumentPersister<br>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_<technicalName>`, 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"]

Check warning on line 57 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L57

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `HTML` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
concepts/commerce/checkout-concept/document/architecture.md:57:16: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `HTML`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING

Check warning on line 57 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L57

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `PDF` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
concepts/commerce/checkout-concept/document/architecture.md:57:35: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `PDF`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING
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 |

Check warning on line 85 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L85

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `HTML` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
concepts/commerce/checkout-concept/document/architecture.md:85:92: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `HTML`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING

Check warning on line 85 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L85

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `PDF` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
concepts/commerce/checkout-concept/document/architecture.md:85:98: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `PDF`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING
| `delivery_note` | Accompanies the shipment. Requires a delivery date in the generation request | html, pdf |

Check warning on line 86 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L86

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `HTML` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
concepts/commerce/checkout-concept/document/architecture.md:86:91: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `HTML`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING

Check warning on line 86 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L86

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `PDF` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
concepts/commerce/checkout-concept/document/architecture.md:86:97: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `PDF`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING
| `credit_note` | Credits the credit line items of a referenced invoice | html, pdf, zugferd_xml, zugferd_embedded_pdf |

Check warning on line 87 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L87

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `HTML` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
concepts/commerce/checkout-concept/document/architecture.md:87:92: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `HTML`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING

Check warning on line 87 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L87

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `PDF` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
concepts/commerce/checkout-concept/document/architecture.md:87:98: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `PDF`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING
| `storno` | Cancels a referenced invoice by inverting its amounts | html, pdf, zugferd_xml, zugferd_embedded_pdf |

Check warning on line 88 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L88

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `HTML` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
concepts/commerce/checkout-concept/document/architecture.md:88:92: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `HTML`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING

Check warning on line 88 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L88

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `PDF` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
concepts/commerce/checkout-concept/document/architecture.md:88:98: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `PDF`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING

`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.

Check warning on line 92 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L92

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `HTML` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
concepts/commerce/checkout-concept/document/architecture.md:92:26: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `HTML`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING

Check warning on line 92 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L92

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `PDF` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
concepts/commerce/checkout-concept/document/architecture.md:92:95: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `PDF`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING

`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/<technical_name>.html.twig`, with shared partials under `@Framework/documents/includes/`.

The ZUGFeRD XML has its own template set at `@Framework/documents/zugferd/<technical_name>.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

<PageRef page="./extension-points" title="Document extension points" />

Check warning on line 130 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L130

Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
concepts/commerce/checkout-concept/document/architecture.md:130:6: Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION

Check warning on line 130 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L130

Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
concepts/commerce/checkout-concept/document/architecture.md:130:25: Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION

<PageRef page="../../../../guides/plugins/plugins/checkout/documents/v2/" title="Document System (v2) guides" />

Check warning on line 132 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L132

Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
concepts/commerce/checkout-concept/document/architecture.md:132:6: Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION

Check warning on line 132 in concepts/commerce/checkout-concept/document/architecture.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/architecture.md#L132

Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
concepts/commerce/checkout-concept/document/architecture.md:132:64: Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION
47 changes: 47 additions & 0 deletions concepts/commerce/checkout-concept/document/extension-points.md
Original file line number Diff line number Diff line change
@@ -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<br><code>shopware.document_v2.type</code>"]) -.-> B
T2(["Enrich or provide data<br><code>shopware.document_v2.provider</code>"]) -.-> C
T3(["Add or override a format<br><code>shopware.document_v2.renderer</code>"]) -.-> 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:

<PageRef page="../../../../guides/plugins/plugins/checkout/documents/v2/" title="Document System (v2) plugin guides" />

Check warning on line 41 in concepts/commerce/checkout-concept/document/extension-points.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/extension-points.md#L41

Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
concepts/commerce/checkout-concept/document/extension-points.md:41:14: Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION

Check warning on line 41 in concepts/commerce/checkout-concept/document/extension-points.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/extension-points.md#L41

Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
concepts/commerce/checkout-concept/document/extension-points.md:41:72: Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION

## 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.

<PageRef page="../../../../guides/plugins/apps/checkout/document" title="Document System (v2) app guide" />

Check warning on line 47 in concepts/commerce/checkout-concept/document/extension-points.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/extension-points.md#L47

Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
concepts/commerce/checkout-concept/document/extension-points.md:47:14: Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION

Check warning on line 47 in concepts/commerce/checkout-concept/document/extension-points.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/extension-points.md#L47

Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
concepts/commerce/checkout-concept/document/extension-points.md:47:64: Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION
49 changes: 49 additions & 0 deletions concepts/commerce/checkout-concept/document/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
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 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:

```mermaid
flowchart TB
T["Document type<br>defines <i>what</i> is generated"] --> G[DocumentGenerator]
P["Data provider<br>defines <i>which data</i> goes in"] --> G
R["Renderer<br>defines <i>which file format</i> comes out"] --> G

Check warning on line 29 in concepts/commerce/checkout-concept/document/index.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/index.md#L29

Possible typo: you repeated a word (ENGLISH_WORD_REPEAT_RULE) Suggestions: `G` Rule: https://community.languagetool.org/rule/show/ENGLISH_WORD_REPEAT_RULE?lang=en-US Category: MISC
Raw output
concepts/commerce/checkout-concept/document/index.md:29:68: Possible typo: you repeated a word (ENGLISH_WORD_REPEAT_RULE)
 Suggestions: `G`
 Rule: https://community.languagetool.org/rule/show/ENGLISH_WORD_REPEAT_RULE?lang=en-US
 Category: MISC
G --> O["Stored document<br>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 the legacy system.

```mermaid
flowchart LR
A["<b>6.7 — Opt-in</b><br><i>enable</i> DOCUMENT_GENERATION_REWORK<br>legacy stays the default"] --> B["<b>6.8 — Default</b><br>flag on by default, API stabilizes<br>legacy still available"] --> C["<b>6.9 — Only system</b><br>legacy removed"]

Check warning on line 39 in concepts/commerce/checkout-concept/document/index.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/index.md#L39

Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
concepts/commerce/checkout-concept/document/index.md:39:98: Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION

Check warning on line 39 in concepts/commerce/checkout-concept/document/index.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/index.md#L39

Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
concepts/commerce/checkout-concept/document/index.md:39:192: Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION

Check warning on line 39 in concepts/commerce/checkout-concept/document/index.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] concepts/commerce/checkout-concept/document/index.md#L39

Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
concepts/commerce/checkout-concept/document/index.md:39:244: Unpaired symbol: ‘"’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION
```

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 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 the two systems coexist until the legacy one is removed in Shopware 6.9.
117 changes: 117 additions & 0 deletions guides/plugins/apps/checkout/document.md
Original file line number Diff line number Diff line change
@@ -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

Check warning on line 21 in guides/plugins/apps/checkout/document.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] guides/plugins/apps/checkout/document.md#L21

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `XML` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
guides/plugins/apps/checkout/document.md:21:3: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `XML`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING
<documents>
<document-type>
<identifier>swag_warranty</identifier>
<label>Warranty</label>
<label lang="de-DE">Garantie</label>
<formats>
<format>html</format>

Check warning on line 28 in guides/plugins/apps/checkout/document.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] guides/plugins/apps/checkout/document.md#L28

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `HTML` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
guides/plugins/apps/checkout/document.md:28:20: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `HTML`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING
<format>pdf</format>

Check warning on line 29 in guides/plugins/apps/checkout/document.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] guides/plugins/apps/checkout/document.md#L29

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `PDF` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
guides/plugins/apps/checkout/document.md:29:20: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `PDF`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING
</formats>
<config>
<page-size>a4</page-size>
<page-orientation>portrait</page-orientation>
<items-per-page>10</items-per-page>
<display-header>true</display-header>
<display-footer>true</display-footer>
</config>
</document-type>
</documents>
```

`formats` accepts the built-in formats only: `html`, `pdf`, `zugferd_xml`, and `zugferd_embedded_pdf`.

Check warning on line 42 in guides/plugins/apps/checkout/document.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] guides/plugins/apps/checkout/document.md#L42

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `HTML` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
guides/plugins/apps/checkout/document.md:42:46: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `HTML`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING

Check warning on line 42 in guides/plugins/apps/checkout/document.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] guides/plugins/apps/checkout/document.md#L42

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `PDF` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
guides/plugins/apps/checkout/document.md:42:54: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `PDF`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING

Installing the app merges the type into the document type registry and seeds a number range of type `document_<identifier>`. 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:

Check warning on line 50 in guides/plugins/apps/checkout/document.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] guides/plugins/apps/checkout/document.md#L50

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `HTML` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
guides/plugins/apps/checkout/document.md:50:95: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `HTML`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING

Check warning on line 50 in guides/plugins/apps/checkout/document.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] guides/plugins/apps/checkout/document.md#L50

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `PDF` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
guides/plugins/apps/checkout/document.md:50:103: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `PDF`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING

::: code-group

```twig [Resources/views/documents/swag_warranty.html.twig]
{% sw_extends '@Framework/documents/base.html.twig' %}

{% block document_headline %}
<h1 class="headline">Warranty for order {{ order.orderNumber }}</h1>
{% 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]
<?xml version="1.0" encoding="UTF-8"?>

Check warning on line 69 in guides/plugins/apps/checkout/document.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] guides/plugins/apps/checkout/document.md#L69

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `XML` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
guides/plugins/apps/checkout/document.md:69:2: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `XML`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING
<warranty>
<orderNumber>{{ order.orderNumber }}</orderNumber>
<documentNumber>{{ meta.documentNumber }}</documentNumber>
</warranty>
```

:::

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 %}

Check warning on line 89 in guides/plugins/apps/checkout/document.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] guides/plugins/apps/checkout/document.md#L89

If a new sentence starts here, add a space and start with an uppercase letter. (LC_AFTER_PERIOD[1]) Suggestions: ` Order`, ` order` Rule: https://community.languagetool.org/rule/show/LC_AFTER_PERIOD?lang=en-US&subId=1 Category: CASING
Raw output
guides/plugins/apps/checkout/document.md:89:20: If a new sentence starts here, add a space and start with an uppercase letter. (LC_AFTER_PERIOD[1])
 Suggestions: ` Order`, ` order`
 Rule: https://community.languagetool.org/rule/show/LC_AFTER_PERIOD?lang=en-US&subId=1
 Category: CASING

{% do order.addArrayExtension('swag_warranty_data', {
'warrantyEnd': order.orderDate|date_modify('+2 years')|date('Y-m-d'),

Check warning on line 92 in guides/plugins/apps/checkout/document.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] guides/plugins/apps/checkout/document.md#L92

Unpaired symbol: ‘'’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
guides/plugins/apps/checkout/document.md:92:56: Unpaired symbol: ‘'’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION
'documentNumber': hook.documentNumber
}) %}
```

:::

The document template reads the extension:

```twig
<p>Warranty valid until {{ order.extensions.swag_warranty_data.get('warrantyEnd') }}</p>
```

## 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.
10 changes: 0 additions & 10 deletions guides/plugins/plugins/checkout/document/index.md

This file was deleted.

Loading
Loading