Giter Site home page Giter Site logo

factur-x's Introduction

PHP Factur-X library

Factur-X is a Franco-German e-invoicing standard which complies with the European e-invoicing standard EN 16931. The Factur-X specifications are available on the FNFE-MPE website in English and French. The Factur-X standard is also called ZUGFeRD 2.2 in Germany.

This library enable you to manage your Factur-X PDF invoices files :

  • Generate Factur-X PDF invoice from regular PDF invoice and Factur-X XML file
  • Extract Factur-X XML from Factur-X PDF invoice
  • Validate Factur-X XML against the official Factur-X XML Schema Definition

Table of contents:

Requirements

  • PHP 7.4+
  • Composer
  • FPDI (MIT License)
  • Smalot (LGPL License)

Installation

Install with Composer

composer require atgp/factur-x

Usage

You can see the code from test page from "tests" directory, also here some simple examples of implementation :

<?php
// Include or autoload (with Composer) all library classes

// Generates Factur-X PDF invoice from PDF and Factur-X XML
$writer = new \Atgp\FacturX\Writer();
$facturxPdf = $writer->generate($pdf, $facturxXml);

// Extracts Factur-X XML
$reader = new \Atgp\FacturX\Reader();
$facturxXml = $reader->extractXML($facturxPdf);

// Validates Factur-X XML against official Factur-X XML Schema Definition 
$validator = new \Atgp\FacturX\XsdValidator();
if (false === ($isValid = $validator->validate($facturxXml)) {
    var_dump($validator->getErrors());
}
// ... or throw exceptions if error(s) are occurred
$validator->validateWithException($facturxXml);

More options are available, look at source code for more information.

License

This project is licensed under MIT License

Changelog

  • v2.0.0 [BC] : 2023-11-06
    • Requires php 7.4+
    • Refactor classes to clarify uses
    • Simplify requirements for "smalot/pdfparser"
    • Import external links on generated factur-x pdf
  • v1.1.0 : 2019-01-09
    • Upgrade Factur-x xsd to v1.0.06
    • Fix PDF-A compliance regarding endobj and ICC profile
  • v1.0.0 : 2019-01-09
    • Requires php 5.6+
    • First version of the library to read, check and write factur-x documents

factur-x's People

Contributors

aegypius avatar benito103e avatar caugner avatar crozet-magenta avatar dsampaolo avatar greggythefly avatar lucas-gp avatar mahdiabderraouf avatar nathan-de-pachtere avatar nykopol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

factur-x's Issues

Hyperlinks in PDF

Hi,
I'am using this library which is really nice by the way.
I found an issue when the source pdf contains hyperlinks.
factur-x library seems to broke the hyperlinks in the PDF document.

The blue color and the underline style are still on the links but hitbox is removed to, so it is not possible to click on it anyome.

For information i use the following code :

`
// 1. generate the pdf with dompdf
$html = "my pdf with a <a href="https://github.com/atgp/factur-x/issues/new\">here link";

$options = new \Dompdf\Options();
$options->set('enable_php', true);
$options->set('enable_html5_parser', true);
$options->set('isRemoteEnabled', true);
$options->set('dpi', 192);
$dompdf = new \Dompdf\Dompdf($options);
$dompdf->setHttpContext(stream_context_create([
'ssl' => [
'verify_peer' => FALSE,
'verify_peer_name' => FALSE,
'allow_self_signed'=> TRUE
],
]));
$dompdf->loadHtml($html);
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
pdfoutput = $dompdf->output(); // links in this pdf works

//2. factur x

$facturex_xml = "...custom code here to generate the right xml as string, using \horstoeko\zugferd\ZugferdDocumentBuilder library...";
$facturx = new \Atgp\FacturX\Facturx();
$facturxPdf = $facturx->generateFacturxFromFiles($pdfoutput, $facturex_xml); // links are now broken
`

Is it a but to fix, or maybe i need to add some options in my code ?
Thanks a lot for your help.

Multiple warnings occur parsing incorrect XML data

When incorrect XML data is passed to the function validate() (atgp/factur-x/src/XsdValidator.php:47), multiple warnings occur:

atgp/factur-x/src/XsdValidator.php:53:
"Warning: DOMDocument::loadXML(): Start tag expected, '<' not found in Entity, line: 1".

atgp/factur-x/src/Utils/ProfileHandler.php:26:
"Warning: DOMXPath::query(): Undefined namespace prefix" ()

atgp/factur-x/src/Utils/ProfileHandler.php:27:
"Warning: Attempt to read property "length" on bool"

We are currently using PHP 8.2.

Unfortunately, for privacy reasons, I cannot attach an example file. I still hope that this information is enough to fix the problem and improve factur-x.

Deprecated warning

Deprecated warning (using PHP 8.2.0):

PHP Deprecated:  Function utf8_encode() is deprecated in .../vendor/atgp/factur-x/src/Fpdi/FdpiFacturx.php on line 65
PHP Deprecated:  Function utf8_encode() is deprecated in .../vendor/atgp/factur-x/src/Fpdi/FdpiFacturx.php on line 133

Glyph widths in font dictionary are not consistent with embedded font program widths

I have generated a PDF and i submit this one on https://services.fnfe-mpe.org/ to audit the PDF, I have this error :

Spec. ISO_19005_3 clause 6.2.11.5 For every font embedded in a conforming file and used for rendering, the glyph width information in the font dictionary and in the embedded font program shall be consistent. Level: CosDocument

Context:
root/document[0]/pages[0](3 0 obj PDPage)/contentStream[0](4 0 obj PDContentStream)/operators[9]/xObject[0](5 0 obj PDXForm)/contentStream[0](5 0 obj PDContentStream)/operators[2027]/usedGlyphs[0](TimesNewRomanNormal 32 0 0)
root/document[0]/pages[0](3 0 obj PDPage)/contentStream[0](4 0 obj PDContentStream)/operators[9]/xObject[0](5 0 obj PDXForm)/contentStream[0](5 0 obj PDContentStream)/operators[2001]/usedGlyphs[0](TimesNewRomanNormal 15 0 0)
root/document[0]/pages[0](3 0 obj PDPage)/contentStream[0](4 0 obj PDContentStream)/operators[9]/xObject[0](5 0 obj PDXForm)/contentStream[0](5 0 obj PDContentStream)/operators[2017]/usedGlyphs[0](TimesNewRomanNormal 8 0 0)
root/document[0]/pages[0](3 0 obj PDPage)/contentStream[0](4 0 obj PDContentStream)/operators[9]/xObject[0](5 0 obj PDXForm)/contentStream[0](5 0 obj PDContentStream)/operators[1507]/usedGlyphs[0](TimesNewRomanNormal 59 0 0)
root/document[0]/pages[0](3 0 obj PDPage)/contentStream[0](4 0 obj PDContentStream)/operators[9]/xObject[0](5 0 obj PDXForm)/contentStream[0](5 0 obj PDContentStream)/operators[1172]/usedGlyphs[0](TimesNewRomanNormal 22 0 0)

I don't understand the error and how to solve it.
Thank you for your help

Error when I do not check the xsd

When I do not check the xsd, there is a small bug.

Doing that

$pdfInvoiceFile = '/var/pdf/f4/invoice-' . $invoice->id . '.pdf';
$pdfInvoicexFile = '/var/pdf/f4/invoicex-' . $invoice->id . '.pdf';

$facturx = new Facturx();
$generatedFacturxFile = $facturx->generateFacturxFromFiles(
  $pdfInvoiceFile,
  $xmlInvoiceFile,
  'autodetect', // facturxProfil
  false, // checkXsd
  '/var/pdf/f4/xml', // outputFilePath
  [], // additionalAttachments
  true, // addFacturxLogo
  'Data' // relationship
);

I get this error:

Un erreur s'est produite ! 500 Internal Server Error - Error details: [0] FPDF error: Unsupported image type: /img/ in /var/web/f4/www/vendor/setasign/fpdf/fpdf.php on line 273. Backtrace: 
#0 /var/web/f4/www/vendor/setasign/fpdf/fpdf.php(888): FPDF->Error() 
#1 /var/web/f4/www/vendor/atgp/factur-x/src/Facturx.php(234): FPDF->Image() 
#2 /var/web/f4/www/src/Services/InvoiceService.php(110): Atgp\FacturX\Facturx->generateFacturxFromFiles() 
#3 /var/web/f4/www/src/Actions/Invoice/UserInvoiceController.php(113): App\Services\InvoiceService->generateInvoicePdf() 
#4 /var/web/f4/www/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php(43): 

Actually, it is because $this->profil is null here:

$pdfWriter->Image(__DIR__.'/../img/'.static::FACTURX_LOGO[$this->profil], 197, 2.5, 7);

It is null because checkXsd is false, and profil is set in checkFacturxXsd().

Th.

Issue on installation via composer

When I do a "composer require atgp/factur-x" inside my projet I have the following errors (cf my composer.json content at the bottom)

Your requirements could not be resolved to an installable set of packages.

Problem 1
- Conclusion: don't install atgp/factur-x v1.0.1
- Conclusion: remove setasign/fpdi 1.6.2
- Installation request for atgp/factur-x ^1.0 -> satisfiable by atgp/factur-x[v1.0.0, v1.0.1].
- Conclusion: don't install setasign/fpdi 1.6.2
- atgp/factur-x v1.0.0 requires setasign/fpdi-fpdf ^2.0 -> satisfiable by setasign/fpdi-fpdf[v2.0.0, v2.1.0].
- setasign/fpdi-fpdf v2.0.0 requires setasign/fpdi ^2.0 -> satisfiable by setasign/fpdi[v2.0.0, v2.0.1, v2.0.2, v2.0.3, v2.1.0, v2.1.1].
- setasign/fpdi-fpdf v2.1.0 requires setasign/fpdi ^2.1 -> satisfiable by setasign/fpdi[v2.1.0, v2.1.1].
- Can only install one of: setasign/fpdi[v2.0.0, 1.6.2].
- Can only install one of: setasign/fpdi[v2.0.1, 1.6.2].
- Can only install one of: setasign/fpdi[v2.0.2, 1.6.2].
- Can only install one of: setasign/fpdi[v2.0.3, 1.6.2].
- Can only install one of: setasign/fpdi[v2.1.0, 1.6.2].
- Can only install one of: setasign/fpdi[v2.1.1, 1.6.2].
- Installation request for setasign/fpdi (locked at 1.6.2) -> satisfiable by setasign/fpdi[1.6.2].

{
  "name": "factomos",
  "description": "factomos",
  "license": "MIT",
  "config": {
    "preferred-install": "dist"
  },
  "authors": [
    {
      "name": "Fredrik Liljegren",
      "email": "[email protected]"
    }
  ],
  "repositories": [
    {
      "type": "vcs",
      "url": "https://github.com/copromatic/maileva"
    }
  ],
  "require": {
    "gocardless/gocardless-pro": "0.9.0",
    "wisembly/elephant.io": "~3.0",
    "ezyang/htmlpurifier": "^4.8",
    "spipu/html2pdf": "^4.6",
    "mpdf/mpdf": "^7.1",
    "nesbot/carbon": "^1.22",
    "copromatic/maileva": "dev-master",
    "knplabs/knp-snappy": "^1.0",
    "wildbit/postmark-php": "^2.5",
    "jjaffeux/postmark-inbound-php": ">=3.0",
    "stripe/stripe-php": "^6.17",
    "jenssegers/date": "^3.4"
  },
  "require-dev": {
    "phpunit/phpunit": "^5.7"
  }
}

checkFacturxXsd returns true for wrong profiles if XML is valid

Bug description

the method checkFacturxXsd returns true for any wrong profile if the given XML is valid.

How to reproduce ?

call the method checkFacturxXsd with a wrong profil and a valid XML.

$facturx = new Facturx();
$isXSDValid = $facturx->checkFacturxXsd($validXml, 'anywrongprofile');
echo (string) $isXSDValid; // "true"

Solution

Detect profil automaticly only if the given profil is "autodetect". A pull-request has been created for the give solution.

Extended missing in FACTURX_PROFIL_TO_XMP

Hi,

I'm using your awesome code to generate facturX from PDF and xml (from easybill/zugferd-php).

Just missing this line to make it work with extended XML data.

//Facturx.php

const FACTURX_PROFIL_TO_XMP = array(
        'minimum' => 'MINIMUM',
        'basicwl' => 'BASIC WL',
        'basic' => 'BASIC',
        'en16931' => 'EN 16931',
        'extended' => 'EXTENDED', //without this line the generateFacturxFromFiles function crash on line 340
    );

Could you validate your pull requests

Hello,

I'm using this lib as it is recommended by FNFE MPE to manage factux files. But it is not compatible with the format 'extended'. I saw that another user submitted you two pull request with these improvements, but you didn't looked at them, as they are open since more than one year. Could you please have a look on them.

For the moment, I don't use lib anymore, and use the fork of this user to have a full compatibility.

Regards
Sebastien

Generated file name

Is it possible to add code to specify the wanted name (next to outputFilePath) for the generated file?

Now, I have to copy the file to change the name:

$pdfInvoiceFile = '/var/pdf/f4/invoice-' . $invoice->id . '.pdf';
$pdfInvoicexFile = '/var/pdf/f4/invoicex-' . $invoice->id . '.pdf';
$facturx = new Facturx();
$generatedFacturxFile = $facturx->generateFacturxFromFiles(
  $pdfInvoiceFile,
  $xmlInvoiceFile,
  'autodetect', // facturxProfil
  false, // checkXsd
  '/var/pdf/f4/xml', // outputFilePath
  [], // additionalAttachments
  true, // addFacturxLogo
  'Data' // relationship
);
// rename($generatedFacturxFile, $pdfInvoicexFile);
copy($generatedFacturxFile, $pdfInvoicexFile);

Problèmes sur les schémas XSD (BasicWL et Basic)

Bonjour,

J'ai relevé 2 problèmes sur les schémas XSD des profils Basic WL et Basic selon la documentation 1.0.06 du FNFE :

BT-20 : Description des conditions de paiement
La description des conditions de paiement doit figurer sur les profils BasicWL et Basic.
facturx_bt-20

BT-148-00
Le prix unitaire brut de la ligne de l'article doit figurer sur le profil Basic.
facturx_bt-148

Merci pour votre travail,

Bien cordialement

Conflict due to dependency on old package

When installing with composer, there is a conflict since an obviously very old version of smalot/pdfparser (main version 0) is required.
A neuer version should be included to allow for projects which also require a newer smalot/pdfparser version (currently main version 2).

➜  composer require atgp/factur-x
Info from https://repo.packagist.org: #StandWithUkraine
./composer.json has been updated
Running composer update atgp/factur-x
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - atgp/factur-x[dev-develop, v1.0.0, ..., v1.0.1] require smalot/pdfparser ^0.13.2 -> found smalot/pdfparser[v0.13.2, v0.13.3] but it conflicts with your root composer.json require (^2.2).
    - atgp/factur-x[dev-master, v1.0.2, ..., v1.0.3] require smalot/pdfparser ^0.19.0 -> found smalot/pdfparser[v0.19.0] but it conflicts with your root composer.json require (^2.2).
    - Root composer.json requires atgp/factur-x * -> satisfiable by atgp/factur-x[dev-master, dev-develop, v1.0.0, v1.0.1, v1.0.2, v1.0.3, 9999999-dev].

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.
You can also try re-running composer require with an explicit version constraint, e.g. "composer require atgp/factur-x:*" to figure out if any version is installable, or "composer require atgp/factur-x:^2.1" if you know which you need.

Installation failed, reverting ./composer.json and ./composer.lock to their original content.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.