Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
#+TITLE: PHP E-invoice It A PHP package for managing italian e-invoice and notice XML formats: - XML management through ~DOMDocument~ and ~DOMXPath~ - full ~FatturaElettronica~ (FatturaPA) XML skeleton - smart simplified xpath strings for getting/setting values (and for adding/getting/removing elements if needed) - multiple bodies (invoice lot) - multiple line items (~DettaglioLinee~) - multiple generic elements with ~setElementCount()~ - XML normalization: remove empty elements and automatically split ~Causale~ in chunks if > 200 characters - optional ~FatturaElettronica~ validation thanks to [[https://github.com/Slamdunk/php-validatore-fattura-elettronica][Slamdunk/php-validatore-fattura-elettronica]] /(Pacchetto PHP per gestire il formato XML di fatture e notifiche come richiesto dal SdI)./ /([[file:README.it.org][Qui]] la documentazione aggiornata in italiano)./ Please refer to - [[https://github.com/taocomp/php-sdicoop-server][PHP SdICoop - Server]] for implementing web services required by the Italian Exchange System (aka "SdI") - [[https://github.com/taocomp/php-sdicoop-client][PHP SdICoop - Client]] to connect to SdI web services See [[https://forum.italia.it/c/fattura-pa][Forum Italia - Fatturazione Elettronica]] for server configuration, interoperability tests, etc. In particular: - Apache configuration :: [[https://forum.italia.it/t/accreditamento-sdicoop-configurazione-ssl-su-apache/3314][Accreditamento SDICoop: configurazione SSL su Apache - Fatturazione Elettroni...]] - Interoperability tests :: [[https://forum.italia.it/t/test-interoperabilita-soluzioni/4370][Test Interoperabilità Soluzioni - Fatturazione Elettronica - Forum Italia]] * Quickstart ** Dependencies - ~php-xml~ - tested for PHP 7+ +should work on PHP 5.5+ +too+ ** Installation *** Composer ~composer require taocomp/php-e-invoice-it~ *** Manually - Clone/download the repository - ~require_once('/path/to/php-e-invoice-it/vendor/autoload.php');~ ** Invoice *** Create a new invoice Create a new FPA12 invoice: #+BEGIN_SRC $invoice = new FatturaElettronica('FPA12'); #+END_SRC Create a new FPR12 invoice: #+BEGIN_SRC $invoice = new FatturaElettronica('FPR12'); #+END_SRC Create a new invoice from file #+BEGIN_SRC $invoice = new FatturaElettronica('/path/to/invoice.xml'); #+END_SRC *** Create a custom template invoice to be used later #+BEGIN_SRC $prefixPath = __DIR__ . '/tmpfiles'; $filename = 'my-custom-template.xml'; $invoice = new FatturaElettronica('FPR12'); $invoice->setValue('IdTrasmittente/IdCodice', '00011122233'); $invoice->setValue('IdTrasmittente/IdPaese', 'IT'); $invoice->setFilename($filename); $invoice->setPrefixPath($prefixPath)->save(); #+END_SRC *** Invoice lot and line items Set 3 bodies: #+BEGIN_SRC $invoice->addBody(2); // or $invoice->setBodyCount(3); #+END_SRC Set 4 line items for second body: #+BEGIN_SRC $invoice->addLineItem(3, 2); // or $invoice->setLineItemCount(4, 2); #+END_SRC *** Get/Set values In general, you can get/set values (and add/get/remove elements) by using a tag/path and an optional /context/. Please note that: - an absolute path is relative to the root element: ~/FatturaElettronicaHeader~ means ~/p:FatturaElettronica/FatturaElettronicaHeader~ - tags and relative paths are prefixed with ~(.)//~ - xpath predicates are allowed: ~$invoice->getValue('DettaglioLinee[2]/NumeroLinea');~ Get a value: #+BEGIN_SRC $invoice->getValue('ModalitaPagamento'); #+END_SRC Get a value with a /context/: #+BEGIN_SRC $invoice->getValue('NumItem', 'DatiContratto'); #+END_SRC Invalid queries (they return more than one element): #+BEGIN_SRC $invoice->getValue('IdPaese'); $invoice->getValue('Sede/Indirizzo', 'FatturaElettronicaHeader'); #+END_SRC Set a value for a specific element: #+BEGIN_SRC $invoice->setValue('ProgressivoInvio', 10001); #+END_SRC Set many single values at once: #+BEGIN_SRC $invoice->setValues('IdTrasmittente', array( 'IdCodice' => '09876543210', 'IdPaese' => 'IT' )); #+END_SRC #+BEGIN_SRC $invoice->setValues('CedentePrestatore/Sede', array( 'Indirizzo' => 'VIA UNIVERSO 1' )); #+END_SRC #+BEGIN_SRC $invoice->setValues('CessionarioCommittente', array( // CessionarioCommittente/DatiAnagrafici/CodiceFiscale 'DatiAnagrafici/CodiceFiscale' => '01234567890', // Denominazione, somewhere inside CessionarioCommittente 'Denominazione' => 'BETA SRL' )); #+END_SRC #+BEGIN_SRC // Set values for second body $body2 = $invoice->getBody(2); $invoice->setValue('Numero', 44, $body2); $invoice->setValue('Data', '2018-12-12', $body2); #+END_SRC Set values to multiple elements at once: #+BEGIN_SRC $invoice->setValuesToAll('DatiGenerali', array( // All "RiferimentoNumeroLinea" somewhere inside DatiGenerali 'RiferimentoNumeroLinea' => 1, // All "IdDocumento" somewhere inside DatiGenerali 'IdDocumento' => 4455, // All "NumItem" somewhere inside DatiGenerali 'NumItem' => 1 )); #+END_SRC Set values from an assoc array: #+BEGIN_SRC $array = array( 'DatiAnagraficiVettore' => array( 'IdFiscaleIVA' => array( 'IdPaese' => 'IT', 'IdCodice' => '09876543210' ), 'Anagrafica' => array( 'Denominazione' => 'TRASPORTO SRLS' ), 'NumeroLicenzaGuida' => 'AA090909' ), 'MezzoTrasporto' => 'Mezzo', 'CausaleTrasporto' => 'La causale del traporto', 'NumeroColli' => '1', 'Descrizione' => 'La descrizione' ); $invoice->setValuesFromArray('DatiTrasporto', $array); #+END_SRC All but ~setValueToAll~ and ~setValuesToAll~ methods will throw an exception if ~$expr/$context~ don't return just one element. *** Set/Unset stylesheet Set: #+BEGIN_SRC $invoice->setStylesheet('/path/to/xsl'); #+END_SRC Unset: #+BEGIN_SRC $invoice->unsetStylesheet(); #+END_SRC *** Validate invoice You need [[https://github.com/Slamdunk/php-validatore-fattura-elettronica][Slamdunk/php-validatore-fattura-elettronica]]. If you install ~php-e-invoice-it~ via-composer, you got it as dependency; otherwise you must download and require it manually. #+BEGIN_SRC $invoice->validate(); #+END_SRC An exception is thrown (with a message) if the XML is not valid, for example: #+BEGIN_SRC DOMDocument::schemaValidateSource(): Element 'DatiTrasmissione': Missing child element(s). Expected is ( CodiceDestinatario ). #+END_SRC *** Save invoice Set an optional default destination dir for all invoices: #+BEGIN_SRC FatturaElettronica::setDefaultPrefixPath('path/to/dir'); #+END_SRC Set an optional destination dir for current invoice: #+BEGIN_SRC $invoice->setPrefixPath('path/to/another/dir'); #+END_SRC Save invoice: #+BEGIN_SRC $invoice->save(); #+END_SRC Specify a custom filename: #+BEGIN_SRC $invoice->setFilename('my-invoice.xml')->save(); #+END_SRC *** Send invoice to SdI Setup a ~\Taocomp\Einvoicing\SdicoopClient\Client~ object (for connecting to webservice SdIRiceviFile): #+BEGIN_SRC use \Taocomp\Einvoicing\SdicoopClient\Client; use \Taocomp\Einvoicing\SdicoopClient\FileSdIBase; use \Taocomp\Einvoicing\SdicoopClient\RispostaSdIRiceviFile; Client::setPrivateKey('/path/to/client.key'); Client::setClientCert('/path/to/client.pem'); Client::setCaCert('/path/to/ca.pem'); $client = new Client(array( 'endpoint' => 'https://testservizi.fatturapa.it/ricevi_file', 'wsdl' => '/path/to/wsdl/SdIRiceviFile_v1.0.wsdl' )); #+END_SRC Send invoice: #+BEGIN_SRC $fileSdI = new FileSdIBase(); $fileSdI->load($invoice); $response = new RispostaSdIRiceviFile($client->RiceviFile($fileSdI)); #+END_SRC ** Notices *** Create a new notice NotificaEsitoCommittente: #+BEGIN_SRC $notice = new EsitoCommittente(); #+END_SRC *** Load a notice from file *** Set values #+BEGIN_SRC // Set some values from invoice, second body: $notice->setValuesFromInvoice($invoice, 2); // Set values $notice->setValue('IdentificativoSdI', 1234567); $notice->setValue('Esito', EsitoCommittente::EC01); #+END_SRC *** Set/Unset stylesheet Set: #+BEGIN_SRC $notice->setStylesheet('/path/to/xsl'); #+END_SRC Unset: #+BEGIN_SRC $notice->unsetStylesheet(); #+END_SRC *** Save notice #+BEGIN_SRC // Set filename from invoice $notice->setFilenameFromInvoice($invoice, '_EC_001'); // Save notice $notice->save(); #+END_SRC *** Send notice to SdI Setup a ~\Taocomp\Einvoicing\SdicoopClient\Client~ object (for connecting to webservice SdIRiceviNotifica): #+BEGIN_SRC use \Taocomp\Einvoicing\SdicoopClient\Client; use \Taocomp\Einvoicing\SdicoopClient\FileSdI; use \Taocomp\Einvoicing\SdicoopClient\RispostaSdINotificaEsito; Client::setPrivateKey('/path/to/client.key'); Client::setClientCert('/path/to/client.pem'); Client::setCaCert('/path/to/ca.pem'); $client = new Client(array( 'endpoint' => 'https://testservizi.fatturapa.it/ricevi_notifica', 'wsdl' => __DIR__ . '/../wsdl/SdIRiceviNotifica_v1.0.wsdl' )); #+END_SRC Send notice: #+BEGIN_SRC $fileSdI = new FileSdI(); $fileSdI->load($notice); $response = new RispostaSdINotificaEsito($client->NotificaEsito($fileSdI)); #+END_SRC * Tests From inside the project root dir: ~./vendor/bin/phpunit --testdox tests~ * Credits We want to thank all contributors of [[https://forum.italia.it/c/fattura-pa][Forum Italia - Fatturazione Elettronica]] who have shared their snippets and any available info. Thanks to @Slamdunk for [[https://github.com/Slamdunk/php-validatore-fattura-elettronica][Slamdunk/php-validatore-fattura-elettronica]]! * License GPLv3.