Creating XML Documents - horstoeko/zugferd GitHub Wiki
- Related issues
- Additional documentation
- Examples
- Write a xml file
- Using the document
- #18 Not compatible with xrechnung_2.3 and xrechnung_3.0
- #49 AllowanceCharge on LineItem
- #101 setDocumentShipToAddress() adds no shipping data
- A valid example for ZugferdDocumentBuilder in EN16931 profile
- A valid example for ZugferdDocumentBuilder in XRECHNUNG3.x profile
If you want to create a new electronic document, please use the class horstoeko\zugferd\ZugferdDocumentBuilder
. This provides all the possibilities to create a compliant electronic document in the form of an XML. It is very easy to get started:
$document = ZugferdDocumentBuilder::CreateNew(ZugferdProfiles::PROFILE_EN16931)
When instantiating the class, you just have to be clear about which profile you want to use. The currently supported profiles are defined in the class horstoeko\zugferd\ZugferdProfiles
. The following profiles are offered at the moment:
Identifier | Description |
---|---|
PROFILE_MINIMUM | The MINIMUM profile includes the main information about the purchaser and vendor, the total invoice amount, and the total sales tax (VAT). Only the purchaser s reference can be given at item level. A breakdown of the sales tax (VAT) is not supported. It is therefore a booking aid. |
PROFILE_BASIC | The BASIC profile is a subset of EN 16931-1 and can be used for simple VAT-compliant invoices |
PROFILE_BASICWL | The BASIC WL profile does not contain any invoice items and therefore cannot display any VAT-compliant invoices. However, it contains all the information at document level that is required to post the invoice. It is therefore a booking aid |
PROFILE_EN16931 | The EN 16931 (COMFORT) profile completely maps the EN 16931-1 and focuses on the core elements of an electronic invoice |
PROFILE_EXTENDED | The EXTENDED profile is an extension of EN 16931-1 to support more complex business processes (invoices in which several deliveries / delivery locations are billed, structured payment conditions, further information at tem level to support warehousing, etc.) |
PROFILE_XRECHNUNG | The reference profile is based on the CIUS XRechnung, which is maintained by KoSIT. It represents an extension of EN 16931-1 with its own business rules, the national German laws and regulations. It is therefore more specific than the EN 16931 (COMFORT) profile. |
PROFILE_XRECHNUNG_2 | Version 2.0 of the profile PROFILE_XRECHNUNG |
PROFILE_XRECHNUNG_2_1 | Version 2.1 of the profile PROFILE_XRECHNUNG |
PROFILE_XRECHNUNG_2_2 | Version 2.2 of the profile PROFILE_XRECHNUNG |
PROFILE_XRECHNUNG_2_3 | Version 2.3 of the profile PROFILE_XRECHNUNG |
PROFILE_XRECHNUNG_3 | Version 3.0 of the profile PROFILE_XRECHNUNG |
You can find more in-depth information on the following websites:
There is a setDocumentInformation
method that takes the general invoice information, such as the invoice number and date, but also other information such as the invoice currency:
$document->setDocumentInformation("471102", "380", \DateTime::createFromFormat("Ymd", "20180305"), "EUR");
This call will render
<rsm:ExchangedDocument>
<ram:ID>471102</ram:ID>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20180305</udt:DateTimeString>
</ram:IssueDateTime>
</rsm:ExchangedDocument>
Depending on the profile used, there are a different number of parties. The two most important ones, which must always be indicated, are the buyer party and the seller party:
Seller
$document->setDocumentSeller("Lieferant GmbH", "549910");
$document->addDocumentSellerGlobalId("4000001123452", "0088");
$document->addDocumentSellerTaxRegistration("FC", "201/113/40209");
$document->addDocumentSellerTaxRegistration("VA", "DE123456789");
$document->setDocumentSellerAddress("Lieferantenstraße 20", "", "", "80333", "München", "DE");
$document->setDocumentSellerContact("Heinz Müller", "Buchhaltung", "+49-111-2222222", "+49-111-3333333","[email protected]");
These calls will render
<ram:SellerTradeParty>
<ram:ID>549910</ram:ID>
<ram:GlobalID schemeID="0088">4000001123452</ram:GlobalID>
<ram:Name>Lieferant GmbH</ram:Name>
<ram:DefinedTradeContact>
<ram:PersonName>Heinz Müller</ram:PersonName>
<ram:DepartmentName>Buchhaltung</ram:DepartmentName>
<ram:TelephoneUniversalCommunication>
<ram:CompleteNumber>+49-111-2222222</ram:CompleteNumber>
<ram:URIID>[email protected]</ram:URIID>
</ram:EmailURIUniversalCommunication>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>80333</ram:PostcodeCode>
<ram:LineOne>Lieferantenstraße 20</ram:LineOne>
<ram:CityName>München</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="FC">201/113/40209</ram:ID>
</ram:SpecifiedTaxRegistration>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">DE123456789</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:SellerTradeParty>
Buyer
$document->setDocumentBuyer("Kunden AG Mitte", "GE2020211");
$document->setDocumentBuyerReference("34676-342323");
$document->setDocumentBuyerAddress("Kundenstraße 15", "", "", "69876", "Frankfurt", "DE");
These calls will render
<ram:BuyerTradeParty>
<ram:ID>GE2020211</ram:ID>
<ram:Name>Kunden AG Mitte</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>69876</ram:PostcodeCode>
<ram:LineOne>Kundenstraße 15</ram:LineOne>
<ram:CityName>Frankfurt</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:BuyerTradeParty>
All methods that add a trading party to the document have in common that the corresponding setDocumentXXXXX
must always be called first. For example, if addDocumentSellerGlobalId
is called before setDocumentSeller
, nothing happens. Let's have a look at
the following example:
$document = ZugferdDocumentBuilder::CreateNew(ZugferdProfiles::PROFILE_EN16931);
$document
->setDocumentInformation("471102", "380", \DateTime::createFromFormat("Ymd", "20180305"), "EUR")
->addDocumentSellerGlobalId("4000001123452", "0088")
->addDocumentSellerTaxRegistration("FC", "201/113/40209")
->addDocumentSellerTaxRegistration("VA", "DE123456789")
->setDocumentSellerAddress("Lieferantenstraße 20", "", "", "80333", "München", "DE")
->setDocumentSellerContact("Heinz Mükker", "Buchhaltung", "+49-111-2222222", "+49-111-3333333","[email protected]")
->writeFile(dirname(__FILE__) . "/factur-x.xml");
... will output...
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:a="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:10" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<rsm:ExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID>471102</ram:ID>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20180305</udt:DateTimeString>
</ram:IssueDateTime>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:ApplicableHeaderTradeAgreement/>
<ram:ApplicableHeaderTradeDelivery/>
<ram:ApplicableHeaderTradeSettlement>
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>
Call setDocumentSeller
before the call to addDocumentSellerGlobalId
....
$document = ZugferdDocumentBuilder::CreateNew(ZugferdProfiles::PROFILE_EN16931);
$document
->setDocumentInformation("471102", "380", \DateTime::createFromFormat("Ymd", "20180305"), "EUR")
->setDocumentSeller("Lieferant GmbH", "549910")
->addDocumentSellerGlobalId("4000001123452", "0088")
->addDocumentSellerTaxRegistration("FC", "201/113/40209")
->addDocumentSellerTaxRegistration("VA", "DE123456789")
->setDocumentSellerAddress("Lieferantenstraße 20", "", "", "80333", "München", "DE")
->setDocumentSellerContact("Heinz Mükker", "Buchhaltung", "+49-111-2222222", "+49-111-3333333","[email protected]")
->writeFile(dirname(__FILE__) . "/factur-x.xml");
... will output...
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:a="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:10" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<rsm:ExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID>471102</ram:ID>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20180305</udt:DateTimeString>
</ram:IssueDateTime>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:ApplicableHeaderTradeAgreement>
<ram:SellerTradeParty>
<ram:ID>549910</ram:ID>
<ram:GlobalID schemeID="0088">4000001123452</ram:GlobalID>
<ram:Name>Lieferant GmbH</ram:Name>
<ram:DefinedTradeContact>
<ram:PersonName>Heinz Mükker</ram:PersonName>
<ram:DepartmentName>Buchhaltung</ram:DepartmentName>
<ram:TelephoneUniversalCommunication>
<ram:CompleteNumber>+49-111-2222222</ram:CompleteNumber>
</ram:TelephoneUniversalCommunication>
<ram:EmailURIUniversalCommunication>
<ram:URIID>[email protected]</ram:URIID>
</ram:EmailURIUniversalCommunication>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>80333</ram:PostcodeCode>
<ram:LineOne>Lieferantenstraße 20</ram:LineOne>
<ram:CityName>München</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="FC">201/113/40209</ram:ID>
</ram:SpecifiedTaxRegistration>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">DE123456789</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:SellerTradeParty>
</ram:ApplicableHeaderTradeAgreement>
<ram:ApplicableHeaderTradeDelivery/>
<ram:ApplicableHeaderTradeSettlement>
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>
Depending on the profile used, additional parties can be specified:
On document level
Method | Description |
---|---|
setDocumentSeller | Detailed information about the seller (service provider) |
setDocumentBuyer | Detailed information about the buyer (service recipient) |
setDocumentSellerTaxRepresentativeTradeParty | Shall be provided in the invoice if the seller has a tax representative who is liable to pay the VAT due. When this is the case, the tax representative’s VAT identifier, name and postal address are required components in the invoice. |
setDocumentProductEndUser | Detailed information on the deviating End consumer |
setDocumentShipTo | Detailed information of the alternative consignee |
setDocumentUltimateShipTo | Detailed information on the deviating final recipient |
setDocumentShipFrom | Detailed information on the the deviating consignor |
setDocumentInvoicer | Detailed information on the different invoicing party |
setDocumentInvoicee | Detailed information on the different invoice recipient, |
setDocumentPayee | Detailed information about the payee, i.e. about the place that receives the payment. The role of the payee may also be performed by a party other than the seller, e.g. by a factoring service. |
On position level
Method | Description |
---|---|
setDocumentPositionShipTo | Detailed information on the different ship-to party at item level |
setDocumentPositionUltimateShipTo | Detailed information on the different end recipient at item level |
Each invoice document has a total of the line items with net, VAT and gross totals. This can be achieved with the setDocumentSummation
method:
$document->setDocumentSummation(529.87, 529.87, 473.00, 0.0, 0.0, 473.00, 56.87, null, 0.0);
This call will render
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount>473.00</ram:LineTotalAmount>
<ram:ChargeTotalAmount>0.00</ram:ChargeTotalAmount>
<ram:AllowanceTotalAmount>0.00</ram:AllowanceTotalAmount>
<ram:TaxBasisTotalAmount>473.00</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">56.87</ram:TaxTotalAmount>
<ram:GrandTotalAmount>529.87</ram:GrandTotalAmount>
<ram:TotalPrepaidAmount>0.00</ram:TotalPrepaidAmount>
<ram:DuePayableAmount>529.87</ram:DuePayableAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
As a rule, an invoice document must at least include one VAT statement. A statement can be added using the addDocumentTax
method. This method can be called several times. It makes sense to group the VAT statements according to tax category, tax type and VAT rate:
$document->addDocumentTax("S", "VAT", 275.0, 19.25, 7.0);
$document->addDocumentTax("S", "VAT", 198.0, 37.62, 19.0);
These calls will render
<ram:ApplicableTradeTax>
<ram:CalculatedAmount>19.25</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount>275.00</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount>37.62</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount>198.00</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
Explanation of terms
-
Tax Category
Coded description of a sales tax category
Each VAT breakdown must be identified by a VAT category code. See the code list UNTDID 5305 for other possible values
-
Tax Type
Coded description of a sales tax type
In EN 16931, only the tax type with the code "VAT" is supported. If other tax types are to be specified, such as insurance tax or mineral oil tax, the EXTENDED profile must be used. The code for the tax type must then be taken from the code list UNTDID 5153.
Note
Please note that for each combination of tax category and tax type, the sum of the corresponding line amounts must be entered separately as a tax statement. You can find a very good and simple example of this in the examples folder in En16931Simple.php.
Here you can see that two items are added to the document - position 1 with a tax rate of 19 percent and position 2 with a tax rate of 7 percent. Position 1 has a line amount of 198.00 €, position 2 has a line amount of 275.00 €. This results in the following tax statement:
$document->addDocumentTax("S", "VAT", 198.0, 37.62, 19.0);
$document->addDocumentTax("S", "VAT", 275.0, 19.25, 7.0);
Each invoice usually contains at least one invoice item. Often several items are indicated. A new invoice item is initialised with the addNewPosition
method. This method takes the identification of the position as the first parameter. Please note that all other available methods - starting with setDocumentPosition
and addDocumentPosition
- require the previous call of addNewPosition
:
$document->addNewPosition("1")
$document->setDocumentPositionNote("Bemerkung zu Zeile 1")
$document->setDocumentPositionProductDetails("Trennblätter A4", "", "TB100A4", null, "0160", "4012345001235")
$document->addDocumentPositionProductCharacteristic("Farbe", "Gelb")
$document->addDocumentPositionProductClassification("ClassCode", "ClassName", "ListId", "ListVersionId")
$document->setDocumentPositionProductOriginTradeCountry("CN")
$document->setDocumentPositionGrossPrice(9.9000)
$document->setDocumentPositionNetPrice(9.9000)
$document->setDocumentPositionQuantity(20, "H87")
$document->addDocumentPositionTax('S', 'VAT', 19)
$document->setDocumentPositionLineSummation(198.0)
These calls will render
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>1</ram:LineID>
<ram:IncludedNote>
<ram:Content>Bemerkung zu Zeile 1</ram:Content>
</ram:IncludedNote>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0160">4012345001235</ram:GlobalID>
<ram:SellerAssignedID>TB100A4</ram:SellerAssignedID>
<ram:Name>Trennblätter A4</ram:Name>
<ram:ApplicableProductCharacteristic>
<ram:Description>Farbe</ram:Description>
<ram:Value>Gelb</ram:Value>
</ram:ApplicableProductCharacteristic>
<ram:DesignatedProductClassification>
<ram:ClassCode listID="ListId" listVersionID="ListVersionId">ClassCode</ram:ClassCode>
</ram:DesignatedProductClassification>
<ram:OriginTradeCountry>
<ram:ID>CN</ram:ID>
</ram:OriginTradeCountry>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount>9.90</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>9.90</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="H87">20.00</ram:BilledQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>198.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
There are many methods that start with setDocumentPosition
and addDocumentPosition
. To discuss them all here would go too far. Please consult the documentation that accompanies each release. But a few essential methods should be briefly clarified:
-
setDocumentPositionProductDetails
Adds product details to the last created position (line) in the document
Parameters (in order of method declaration)
Name Description Optional name A name of the item (item name) description A description of the item, the item description makes it possible to describe the item and its properties in more detail than is possible with the item name. X sellerAssignedID An identifier assigned to the item by the seller X buyerAssignedID An identifier assigned to the item by the buyer. The article number of the buyer is a clear, bilaterally agreed identification of the product. It can, for example, be the customer article number or the article number assigned by the manufacturer. X globalIDType The identifier for the identification scheme of the identifier of an item according to registered scheme. The identification scheme shall be specified from the entries in the list published by the ISO/IEC 6523 Maintenance Agency. See ISO/IEC 17 6523 X globalID Identification of an article according to the registered scheme (Global identifier of the product, GTIN, ...) X -
setDocumentPositionGrossPrice
Set the unit price excluding sales tax before deduction of the discount on the item price.
Parameters (in order of method declaration)
Name Description Optional amount The unit price excluding sales tax before deduction of the discount on the item price. If the price is shown according to the net calculation, the price must also be shown according to the gross calculation. basisQuantity The number of item units for which the price applies (price base quantity) X basisQuantityUnitCode The unit code of the number of item units for which the price applies (price base quantity) X -
setDocumentPositionNetPrice
Set detailed information on the net price of the item. The net price includes all surcharges and discounts, but not VAT.
Parameters (in order of method declaration)
Name Description Optional amount The price of an item excluding VAT after deduction of the discount on the item price. basisQuantity The number of item units for which the price applies (price base quantity) X basisQuantityUnitCode The unit code of the number of item units for which the price applies (price base quantity) X -
addDocumentPositionAllowanceCharge
Add surcharges and discounts on position level
Parameters (in order of method declaration)
Name Description Optional actualAmount The surcharge/discount amount excluding sales tax isCharge Switch that indicates whether the following data refer to an allowance or a discount calculationPercent The percentage that may be used in conjunction with the base invoice line discount amount to calculate the invoice line discount amount X basisAmount The base amount that may be used in conjunction with the invoice line discount percentage to calculate the invoice line discount amount X reasonCode The reason given as a code for the invoice line discount. Use entries from the UNTDID 5189 code list (discounts) or the UNTDID 7161 code list (surcharges). The invoice line discount reason code and the invoice line discount reason must match. In the case of a discount, the code list UNTDID 5189 must be used. In the case of a surcharge, the code list UNTDID 7161 must be used. X reason The reason given in text form for the invoice item discount/surcharge X -
setDocumentPositionQuantity
Sets the quantity of the individual items (goods or services) invoiced in the relevant line.
Parameters (in order of method declaration)
Name Description Optional billedQuantity The quantity of individual items (goods or services) billed in the relevant line billedQuantityUnitCode The unit of measure applicable to the amount billed. The unit of measurement must be taken from the lists from UN/ECE Recommendation N°20 "Codes for Units of Measure Used in International Trade" and UN/ECE Recommendation N°21 "Codes for Passengers, Types of Cargo, Packages and Packaging Materials" using the UN/ECE Rec No. 20 Intro 2.a) chargeFreeQuantity Quantity, free of charge X chargeFreeQuantityUnitCode Unit of measure code for the quantity free of charge. The unit of measurement must be taken from the lists from UN/ECE Recommendation N°20 "Codes for Units of Measure Used in International Trade" and UN/ECE Recommendation N°21 "Codes for Passengers, Types of Cargo, Packages and Packaging Materials" using the UN/ECE Rec No. 20 Intro 2.a) X packageQuantity Number of packages X packageQuantityUnitCode Unit of measure code for number of packages. The unit of measurement must be taken from the lists from UN/ECE Recommendation N°20 "Codes for Units of Measure Used in International Trade" and UN/ECE Recommendation N°21 "Codes for Passengers, Types of Cargo, Packages and Packaging Materials" using the UN/ECE Rec No. 20 Intro 2.a) X -
addDocumentPositionTax
Add information about the sales tax that applies to the goods and services invoiced in the relevant invoice line
Parameters (in order of method declaration)
Name Description Optional categoryCode Coded description of a sales tax category (see Specifying a VAT breakdown) typeCode Coded description of a sales tax type (see Specifying a VAT breakdown) rateApplicablePercent The VAT rate applicable to the item invoiced and expressed as a percentage. For example, the value 20 is given for 20% (and not 0.2) calculatedAmount Tax amount. Information only for taxes that are not VAT. X exemptionReason Reason for tax exemption (free text) X exemptionReasonCode Reason given in code form for the exemption of the amount from VAT. Note: Code list issued and maintained by the Connecting Europe Facility. (See: VATEX Code List) X -
setDocumentPositionLineSummation
Set information on line/position totals
Parameters (in order of method declaration)
Name Description Optional lineTotalAmount The total amount of the invoice item. This is the "net" amount, that is, excluding sales tax, but including all surcharges totalAllowanceChargeAmount Total amount of item surcharges and discounts X
As there are always misunderstandings regarding the handling of discounts and surcharges, I have outlined 3 options below:
A "gross" unit price of 14 euros is first defined here. If the customer is to be charged a lower unit price (of 10 euros per item), the unit price is simply reduced by calling addDocumentPositionGrossPriceAllowanceCharge
and the "correct" "net" unit price of 10 euros is also specified by calling setDocumentPositionNetPrice
$document = ZugferdDocumentBuilder::CreateNew(ZugferdProfiles::PROFILE_EN16931);
$document
->setDocumentInformation("471102", "380", \DateTime::createFromFormat("Ymd", "20180305"), "EUR")
->addDocumentNote('Rechnung gemäß Bestellung vom 01.03.2018.')
->addDocumentNote('Lieferant GmbH' . PHP_EOL . 'Lieferantenstraße 20' . PHP_EOL . '80333 München' . PHP_EOL . 'Deutschland' . PHP_EOL . 'Geschäftsführer: Hans Muster' . PHP_EOL . 'Handelsregisternummer: H A 123' . PHP_EOL . PHP_EOL, null, 'REG')
->setDocumentSupplyChainEvent(\DateTime::createFromFormat('Ymd', '20180305'))
->addDocumentPaymentMean(ZugferdPaymentMeans::UNTDID_4461_58, null, null, null, null, null, "DE12500105170648489890", null, null, null)
->setDocumentSeller("Lieferant GmbH", "549910")
->addDocumentSellerGlobalId("4000001123452", "0088")
->addDocumentSellerTaxRegistration("FC", "201/113/40209")
->addDocumentSellerTaxRegistration("VA", "DE123456789")
->setDocumentSellerAddress("Lieferantenstraße 20", "", "", "80333", "München", "DE")
->setDocumentSellerContact("Heinz Mükker", "Buchhaltung", "+49-111-2222222", "+49-111-3333333","[email protected]")
->setDocumentBuyer("Kunden AG Mitte", "GE2020211")
->setDocumentBuyerReference("34676-342323")
->setDocumentBuyerAddress("Kundenstraße 15", "", "", "69876", "Frankfurt", "DE")
->addDocumentPaymentTerm("Zahlbar innerhalb 30 Tagen netto bis 04.04.2018, 3% Skonto innerhalb 10 Tagen bis 15.03.2018")
->addNewPosition("1")
->setDocumentPositionProductDetails("Hosting", "", "HST0000")
->setDocumentPositionGrossPrice(14.0)
->addDocumentPositionGrossPriceAllowanceCharge(4.00, false)
->setDocumentPositionNetPrice(10.0)
->setDocumentPositionQuantity(1, "XPP")
->addDocumentPositionTax('S', 'VAT', 19)
->setDocumentPositionLineSummation(10)
->addDocumentTax("S", "VAT", 10, 1.90, 19.0)
->setDocumentSummation(11.90, 11.90, 10.00, 0.0, 0.0, 10.0, 1.90, 0.0, 0.0)
->writeFile(dirname(__FILE__) . "/discount_2.xml");
By calling addDocumentPositionAllowanceCharge
, the total line amount (net unit price * billing quantity) can be reduced or charged. In the following, the corresponding reduced or increased amount must of course also be specified in the call to setDocumentPositionLineSummation
. This then also has an effect on the entries when calling addDocumentTax
and setDocumentSummation
$document = ZugferdDocumentBuilder::CreateNew(ZugferdProfiles::PROFILE_EN16931);
$document
->setDocumentInformation("471102", "380", \DateTime::createFromFormat("Ymd", "20180305"), "EUR")
->addDocumentNote('Rechnung gemäß Bestellung vom 01.03.2018.')
->addDocumentNote('Lieferant GmbH' . PHP_EOL . 'Lieferantenstraße 20' . PHP_EOL . '80333 München' . PHP_EOL . 'Deutschland' . PHP_EOL . 'Geschäftsführer: Hans Muster' . PHP_EOL . 'Handelsregisternummer: H A 123' . PHP_EOL . PHP_EOL, null, 'REG')
->setDocumentSupplyChainEvent(\DateTime::createFromFormat('Ymd', '20180305'))
->addDocumentPaymentMean(ZugferdPaymentMeans::UNTDID_4461_58, null, null, null, null, null, "DE12500105170648489890", null, null, null)
->setDocumentSeller("Lieferant GmbH", "549910")
->addDocumentSellerGlobalId("4000001123452", "0088")
->addDocumentSellerTaxRegistration("FC", "201/113/40209")
->addDocumentSellerTaxRegistration("VA", "DE123456789")
->setDocumentSellerAddress("Lieferantenstraße 20", "", "", "80333", "München", "DE")
->setDocumentSellerContact("Heinz Mükker", "Buchhaltung", "+49-111-2222222", "+49-111-3333333","[email protected]")
->setDocumentBuyer("Kunden AG Mitte", "GE2020211")
->setDocumentBuyerReference("34676-342323")
->setDocumentBuyerAddress("Kundenstraße 15", "", "", "69876", "Frankfurt", "DE")
->addDocumentPaymentTerm("Zahlbar innerhalb 30 Tagen netto bis 04.04.2018, 3% Skonto innerhalb 10 Tagen bis 15.03.2018")
->addNewPosition("1")
->setDocumentPositionProductDetails("Hosting", "", "HST0000")
->setDocumentPositionGrossPrice(10.0)
->setDocumentPositionNetPrice(10.0)
->setDocumentPositionQuantity(1, "XPP")
->addDocumentPositionTax('S', 'VAT', 19)
->addDocumentPositionAllowanceCharge(1.00, false, null, null, null, "Discount")
->setDocumentPositionLineSummation(9)
->addDocumentTax("S", "VAT", 9.00, 1.71, 19.0)
->setDocumentSummation(10.71, 10.71, 9.00, 0.0, 0.0, 9.0, 1.71, 0.0, 0.0)
->writeFile(dirname(__FILE__) . "/discount_3.xml");
If an invoice surcharge or discount is to be used for the entire invoice, the addDocumentAllowanceCharge
method can be used. The reducing or increasing amount is specified here. Please note that the specification of tax information is mandatory. Invoice surcharges/discounts must always be specified for a group of tax type, tax category and tax percentage. This then also has an effect on the entries when calling addDocumentTax
and setDocumentSummation
$document = ZugferdDocumentBuilder::CreateNew(ZugferdProfiles::PROFILE_EN16931);
$document
->setDocumentInformation("471102", "380", \DateTime::createFromFormat("Ymd", "20180305"), "EUR")
->addDocumentNote('Rechnung gemäß Bestellung vom 01.03.2018.')
->addDocumentNote('Lieferant GmbH' . PHP_EOL . 'Lieferantenstraße 20' . PHP_EOL . '80333 München' . PHP_EOL . 'Deutschland' . PHP_EOL . 'Geschäftsführer: Hans Muster' . PHP_EOL . 'Handelsregisternummer: H A 123' . PHP_EOL . PHP_EOL, null, 'REG')
->setDocumentSupplyChainEvent(\DateTime::createFromFormat('Ymd', '20180305'))
->addDocumentPaymentMean(ZugferdPaymentMeans::UNTDID_4461_58, null, null, null, null, null, "DE12500105170648489890", null, null, null)
->setDocumentSeller("Lieferant GmbH", "549910")
->addDocumentSellerGlobalId("4000001123452", "0088")
->addDocumentSellerTaxRegistration("FC", "201/113/40209")
->addDocumentSellerTaxRegistration("VA", "DE123456789")
->setDocumentSellerAddress("Lieferantenstraße 20", "", "", "80333", "München", "DE")
->setDocumentSellerContact("Heinz Mükker", "Buchhaltung", "+49-111-2222222", "+49-111-3333333","[email protected]")
->setDocumentBuyer("Kunden AG Mitte", "GE2020211")
->setDocumentBuyerReference("34676-342323")
->setDocumentBuyerAddress("Kundenstraße 15", "", "", "69876", "Frankfurt", "DE")
->addDocumentPaymentTerm("Zahlbar innerhalb 30 Tagen netto bis 04.04.2018, 3% Skonto innerhalb 10 Tagen bis 15.03.2018")
->addNewPosition("1")
->setDocumentPositionProductDetails("Hosting", "", "HST0000")
->setDocumentPositionGrossPrice(10.0)
->setDocumentPositionNetPrice(10.0)
->setDocumentPositionQuantity(1, "XPP")
->addDocumentPositionTax('S', 'VAT', 19)
->setDocumentPositionLineSummation(10)
->addDocumentAllowanceCharge(1.00, false, "S", "VAT", 19.0, null, null, null, null, null, null, "Discount")
->addDocumentTax("S", "VAT", 9, 1.71, 19.0)
->setDocumentSummation(10.71, 10.71, 10.00, 0.0, 1.0, 9.0, 1.71, 0.0, 0.0)
->writeFile(dirname(__FILE__) . "/discount_4.xml");