Repository: shopware/shopware (PHP)

Issue:
ZUGFeRD LineItem netPrice uses wrong value for basisQuantity
### Shopware Version

6.7.*

### Affected area / extension

Platform(Default)

### Actual behaviour

In this code, `$lineItem->getQuantity()` is used as the second argument. This argument is used to set the [BaseQuantity](https://docs.peppol.eu/poacc/billing/3.0/2023-Q2/syntax/ubl-invoice/cac-InvoiceLine/cac-Price/cbc-BaseQuantity/).
https://github.com/shopware/shopware/blob/e42fcffd5fd780b01dddc04c2c737b875c8b575f/src/Core/Checkout/Document/Zugferd/ZugferdDocument.php#L181

According to the documentation, this quantity represents “The number of item units to which the price applies.” Since the price refers to a single unit of the item, the value should be 1 — not the quantity of the line item.

For example, if you add a line item with a price of €10 and a BaseQuantity of 5, it would technically mean that 5 units cost €10 total, while in reality, it's the price per unit. Therefore, the BaseQuantity should be set to 1, not 5.

I've noticed that most ZUGFeRD renderers do not show or calculate this issue, as they rely only on the numeric values — but it is still technically incorrect.

### Expected behaviour

`1` is used as BaseQuantity

### How to reproduce

Create a ZUGFeRD invoice with a order which contains line items with quantity greater than 1.

### Definition of Done

- [ ] An automated test covers the fix.
- [ ] Integration/E2E testing in staging is done.
- [ ] Changelog markdown file created or updated in /changelog/_unreleased directory.
- [ ] Developer documentation written/updated.
- [ ] End user and/or developer documentation written or updated with clarification.
- [ ] Regression test created to ensure bug does not reappear, and automated regression tests pass.
- [ ] Code changes resolve the reported bug without introducing new issues.


Discussion: Todo: we have to evaluate this, e.g. is this specific to Peppol or did we set the wrong value accoring to our implemented zugferd format. Also we likely don't want to hardcode this to `1` but instead use a shopware product value for it (maybe this is already configurable as "this price applies to x units")



Fix (patch):
diff --git a/src/Core/Checkout/Document/Zugferd/ZugferdDocument.php b/src/Core/Checkout/Document/Zugferd/ZugferdDocument.php
index d8e6f8e8084..a553812591c 100644
--- a/src/Core/Checkout/Document/Zugferd/ZugferdDocument.php
+++ b/src/Core/Checkout/Document/Zugferd/ZugferdDocument.php
@@ -176,9 +176,14 @@ public function withProductLineItem(OrderLineItemEntity $lineItem, string $paren
         if (!Feature::isActive('v6.8.0.0')) {
             $this->addLineTotalAmount($totalNet);
         }
+
         $this->zugferdBuilder
             ->addNewPosition($parentPosition . $lineItem->getPosition())
-            ->setDocumentPositionNetPrice(\round($totalNet / $lineItem->getQuantity(), 2), $lineItem->getQuantity(), ZugferdUnitCodes::REC20_PIECE)
+            ->setDocumentPositionNetPrice(
+                \round($totalNet / $lineItem->getQuantity(), 2),
+                $lineItem->getProduct()?->getPurchaseUnit() ?? 1,
+                ZugferdUnitCodes::REC20_PIECE
+            )
             ->setDocumentPositionQuantity($lineItem->getQuantity(), ZugferdUnitCodes::REC20_PIECE)
             ->addDocumentPositionTax($this->getTaxCode($tax), 'VAT', $tax?->getTaxRate() ?? 0.0)
             ->setDocumentPositionLineSummation($totalNet)