Search


(press enter to search)

WPXOrder is a collection of Delphi units to create X-Factur (ZUGFeRD) XML data.

It was created to load, process and save such data. It does not include E-Invoice standard yet and is focussed to create the XML data to be embedded inside PDF invoices. To create such Invoices you can use the porwerful PDF creation VCL wPDF. To read such Invoices you can use WPViewPDF PLUS which can not only extract X-Factur Data but also attach it.

 

Please review the source code on our WPXOrder GitHub page.

 

WPXOrder was developed by WPCubed GmbH and Julian Ziersch.

 

Purpose and Licensing

WPXOrder is designed to create XML attachments for invoices distributed as PDFs. It is developed in Delphi 10.1 and works best with our products, wPDF or WPViewPDF PLUS. It can also be used to read such XML data and access all the properties with ease. It can also be used to verify the calculation (total sums) - however, please note that we cannot guarantee that such calculations work correctly in any case.

 

Using the provided EXE, you can open the example PDFs and compare the internal calculations with the numbers stored in the PDFs. With ony click you can create Delphi code which will create the data as loaded in the invoice. This will help you greatly to understand the XML format better and to convert your invoice writing software

 

Please review the source code on our GitHub page.

You can use the component without any licensing cost if you incorporate it into an open-source project that is distributed under the GNU license - except for components of any kind or "forks".

 

If you need to use it commercially in-house or in any closed-source product, a commercial license is required. This license is available at a reasonable cost per company (named license). The commercial license also contains support for 60 days after purchase.

Please note that we cannot comment on any legal and most calculation questions involved with X-Factur.

 

How WPXOrder operates

Convert XML data to Delphi objects

When loading XML data or when the invoice is created by code, in memory Delphi objects will be initialized. Each of the objects use a class which matches the property inside the XML document. This means such classes have subproperties with the name of each of the possible sub elements. This provides typesavety and consitency of code vs XML data. You are also protected against typing errors. The component even knows the order in which the objects are supposed to be written to XML - which is important for propper verification of the invoice. The moste inner elements of the object-tree are datatype objects. Those have properties to read and assign theit value, i.e. ValueStr, Value, AsBoolean. We use a lot of overloading to let you code the way you are used to.

Heavy use of generics

Each class representing an invoice property was implemented using class inheritance and generics. This approach allowed us to create the basic architecture based on the official ZUGFeRD XML scheme, saving time and reducing typing errors. It is possible to extend the classes with helper functions, if needed. However, please note that a modern Delphi compiler is required; we recommend Delphi 10.1 or later.

Writing XML as simple top-bottom export

When saving the loaded data to XML, we use a straightforward method to recursively write all objects from top to bottom. The code is efficient and quick, achieving this without using any XML writing classes. A simple string list is sufficient to write the code. Thanks to this approach, we can use the same procedure to alternatively generate Delphi code to produce the same invoice data, including all the text and number values. We find this extremely practical, and it has been helpful during development to verify that a specific example invoice can be recreated using our component, with only minor differences in the digits of numbers (such as "12.34" vs "12.3400").

 

Usage

General

We assume you will use the component in a program that is based on a database. For this description we assume in the database there is a table containing customer address data, a table with invoice data, and a table linked to the latter that includes each item included in the invoice. We recommend creating the XML when you calculate the invoice and saving it as text. You can later embed this XML into the PDF.

Required classes

You need some working classes which hold important information for the invoice:

WPXSeller : TCompanyData - this holds the address and tax information of the seller.

WPXBuyer  : TCompanyData - this holds the address and tax information of the buyer.

WPXShipTo : TCompanyData - this holds the address where the invoice is shipped to..

WPXPaymentData : TPaymentData - here you store some payment terms, due time and the tax category

WPXOrderData : TOrderData - here currently there is just a field for the order data;

 

If course you need an instance of the TWPXFactur class which creates the invoice.

WPXFactur : TWPXFactur

Start Invoice

First you need to populate the objects which hold the addresses. Please note that you need to provide a country ID (i.e. "DE") and a ZIP code. The VAT ID is required for any EU invoice. Also do not forget the data and the due date.

 

Now you can start the process with StartInvoice:

WPXFactur.StartInvoice(
         TDocumentCode.c380_Commercial_invoice,
         InvoiceDATE.AsDateTime,
         InvoiceORDER_ID.AsString,
         'Rechnung',
         WPXSeller,
         WPXBuyer, 
         WPXShipTo , // or nil
         InvoiceNotes.Lines, // some free text - if required
         WPXOrderData,
         nil, // optional: TDeliveryData
         WPXPaymentData
        );

Add all Items

Now loop through all the items (here "Products") which are connected to the invoice. For each items you can use code like this:

   

     if WPXPaymentData.TAXCategory<>TTaxCategory.S_Standard_rate then 
       vat_pc := 0 else
     vat_pc := ProductsVAT_PC.AsFloat;

     if ProductsNETTO.AsFloat<0 then 
     begin
         WPXFactur.AddAllowanceCharge(
            false,  // false=allowance, true=charge
            100,
            -ProductsNETTO.AsFloat*Form1.ProductsCOUNT.AsFloat,  // negative!
            ProductsDESCRIPTION.AsString,
            vat_pc,
            WPXPaymentData.TAXCategory  )
     end
     else
     begin
         WPXFactur.AddSale(
             ProductsDESCRIPTION.AsString,
             ProductsNETTO.AsFloat,
             ProductsCOUNT.AsFloat,
             vat_pc,
             WPXPaymentData.TAXCategory );
     end;

 

1) Please note that in this examples items with negative values are possible. Such items are usually rebates and have to be added to the invoice as "allowance" - but with a positive value.

2) The above code works well inside of a reporting tool. We used it with our product WPReporter inside the event AfterProcessGroup.

Finalize Invoice

At the end you add the summation to the invoice based on the calculation you did yourself while looping all items:


with WPXFactur.Transaction.ApplicableHeaderTradeSettlement do
begin
	InvoiceCurrencyCode.SetValue(TCurrencyCode.EUR);
	ApplicableTradeTax.CalculatedAmount.SetValue(...);
	ApplicableTradeTax.TypeCode.SetValue('VAT');
	ApplicableTradeTax.BasisAmount.SetValue(...);
	ApplicableTradeTax.CategoryCode.SetValue(WPXPaymentData.TAXCategory);
	ApplicableTradeTax.RateApplicablePercent.SetValue(....);
	SpecifiedTradePaymentTerms.DueDateDateTime.DateTimeString.Value := InvoiceData;
	SpecifiedTradeSettlementHeaderMonetarySummation.LineTotalAmount.SetValue(....);
	SpecifiedTradeSettlementHeaderMonetarySummation.ChargeTotalAmount.SetValue(...);
	SpecifiedTradeSettlementHeaderMonetarySummation.AllowanceTotalAmount.SetValue(....);
	SpecifiedTradeSettlementHeaderMonetarySummation.TaxBasisTotalAmount.SetValue(....);
	SpecifiedTradeSettlementHeaderMonetarySummation.TaxTotalAmount.SetValue(...., 'EUR');
	SpecifiedTradeSettlementHeaderMonetarySummation.GrandTotalAmount.SetValue(....);
	SpecifiedTradeSettlementHeaderMonetarySummation.DuePayableAmount.SetValue(....);
end;

 

or you can simply call the method FinalizeInvoice.

WPXFactur.FinalizeInvoice(true,TCurrencyCode.EUR,0,WPXPaymentData);

 

You can of course read out the created values after FinalizeInvoice. Please make sure to use official verification to check the result. We do not and we cannot guarantee the correctness of the calculation.

 

Another option is to write the elements yourself like in the example above and call VerifySummation to get a comparision of the values using your calculation and our calculation.

WPXFactur.VerifySummation;
ShowMessage(WPXFactur .Messages.Text)

 

Included Sample Project

 
 

This sample allows you to load an invoice in XML format. It can create a new invoice from the data entered in the form and calculate the total values. Additionally, it can save a new XML file.