fatturaelettronicaphp / FatturaElettronica

Pacchetto PHP per la lettura, la generazione e la validazione della fattura elettronica, sia per la Pubblica Amministrazione che tra privati (B2B)
https://fatturaelettronicaphp.github.io/FatturaElettronica
MIT License
40 stars 14 forks source link

[FEATURE] Invio Fatture Elettroniche a Intermediari #40

Closed Skullbock closed 2 years ago

Skullbock commented 2 years ago

Come da PR inviata: https://github.com/fatturaelettronicaphp/FatturaElettronica/pull/39 (grazie @KristianLentino99) l'idea è di introdurre la possibilità di inviare le fatture elettroniche tramite una libreria PHP ai vari intermediari.

In questa Issue vorremmo definire le modalità in cui tale feature potrebbe essere implementata.

A. Integrata direttamente nel pacchetto

Introdurre la soluzione come da PR #39 , con l'aggiunta di un'interfaccia generica al posto della classe astratta.

In questa soluzione, che risulterebbe la più facile da implementare, ci sarebbe la problematica di aggiunta di varie dipendenze possibilmente non necessarie e la necessità di rilasciare una nuova versione ad ogni nuovo driver pubblicato o ad ogni modifica di driver esistenti.

Inoltre risulterebbe impossibile inviare fatture non prodotte dal pacchetto stesso, a meno di non caricarle tramite la libreria stessa per poi inviarle.

B. Pacchetto separato, con vari driver

In questo scenario, si creerebbe un nuovo pacchetto sotto la stessa organizzazione (fatturaelettronicaphp/fatturaelettronica-sender o una cosa così) che si occupa di inviare fatture elettroniche allo SDI. Tali fatture potranno essere inviate direttamente come file xml o passando attraverso la libreria "core". Anche qui però i driver sarebbero tutti accorpati in un pacchetto unico.

C. Pacchetto separato, e pacchetti separati per vari driver.

Questa è la soluzione che preferisco, dove si creerebbe un pacchetto "base" per l'invio astratto, e poi un pacchetto per ogni driver, così ognuno può scegliere solo il suo driver e avere il minor numero di dipendenze possibile (ie: fatturaelettronicaphp-sender-aruba, fatturaelettronicaphp-sender-shellrent, etc)

Pingo @KristianLentino99 e @tobispace per ulteriori opinioni al riguardo

Esempio di Interfaccia:

<?php 

namespace FatturaElettronicaPhp\Sender;

interface DigitalDocumentSender 
{
       /** @throws CannotSendDigitalDocumentException **/
       public function send(\SimpleXmlElement $xml): void;
}
KristianLentino99 commented 2 years ago

@Skullbock credo che la soluzione migliore sia la C come indicato da te, tuttavia io penso che sia meglio che la fattura passi sempre dalla libreria "padre" ovvero la vostra così che abbiamo sempre un modo "standard" , prevedibile e testato di avere la fattura. Mi spiego meglio , se nella funzione send accettiamo solo un'istanza della vostra classe DigitalDocument siamo sempre sicuri di ricevere un XML più o meno coerente con quello che serve per la fatturazione elettronica , mentre se accettasimo qualsiasi tipo di XML no. Io penso che la soluzione C sia la migliore ma bloccando l'utente ad utilizzare la libreria "padre" per generare l'xml . Inoltre penso sia meglio una classe astratta per lo scopo dato che ho gestito anche "l'environment" della fattura, ovvero, ambiente di test e produzione image

image

Skullbock commented 2 years ago

@KristianLentino99 si avere la validazione è sicuramente utile, ma non tutti potrebbero usare la li regia madre per questo, o hanno già validato in altri modi.

Una soluzione intermedia potrebbe essere avere la libreria "generica" che manda tramite stringa, e poi una libreria che utilizzi entrambe librerie per mandare un digital document con la nuova libreria, convertendola prima in stringa.

Per quanto riguarda gli environment, sono d'accordo che è una funzionalità utile, ma credo che così implementata sia un po' restrittiva. Non tutti i sender potrebbero avere tali environment, o potrebbero non essere solo due, o comportarsi diversamente. Credo che convenga spostare quella funzionalità in un trait e aggiungere un'interfaccia che aiuti a dichiarare quando tali environment sono presenti, ma senza limitare nome e o numero di environment presenti.

KristianLentino99 commented 2 years ago

@Skullbock per il discorso degli environment effettivamente si hai ragione, serve un qualcosa di più strutturato. Più che un trait per gli environment forse serve qualcosa di più strutturato come gli Enum già presenti nella vostra libreria , per cui per ogni servizio si dichiarano gli enum dei possibili environment.

Per il discorso del documento come stringa non ho ben chiaro il flusso, alla fine basta che loro istanzino l'oggetto partendo da un XML (non ci interessa da dove venga questo XML) come nel seguente esempio:

image

Skullbock commented 2 years ago

Il motivo per cui l'esempio in oggetto può essere scomodo è che per inviare un xml che chi userebbe la libreria di sending potrebbe aver già validato per conto suo, o vuole lasciare che sia l'intermediario a validare, dovrebbe creare un oggetto della libreria core, caricare in memoria l'intero xml per poi serializzarlo nuovamente in stringa per inviarlo, visto che tutti i sender vogliono una stringa. Non sempre può essere quei che si vuole o necessario.

Di contro, chi vuole invece usare la validazione della libreria core, può sempre includerla, e dare come giustamente dimostri tu nel tuo esempio, visto che il Documento si può convertire in stringa in ogni momento.

In questo modo ci sono meno Inter-dipendenze e ogni libreria può essere usata autonomamente o in combinata, a scelta.

KristianLentino99 commented 2 years ago

Ok ho capito il tuo punto di vista, hai perfettamente ragione effettivamente , ho ancora tanto da imparare 😂 si potrebbe procedere così

Skullbock commented 2 years ago

La funzionalità ora è in fase beta (non ancora pubblicata su packagist) su

https://github.com/fatturaelettronicaphp/FatturaElettronica/sender.

Ho lasciato anche i crediti a te @KristianLentino99 per i tuoi adapter. Non avendo accessi a tali SDI HUB non ho modo di testarli, per cui ti chiedo di inviare PR al pacchetto se vedi errori nei sender a cui hai accesso

KristianLentino99 commented 2 years ago

Ciao @Skullbock è possibile entrare come contributor e creare repository? volevo provare a implementare anche il sender per fatture24 https://www.fattura24.com/api-documentazione/ Comunque a stretto giro testo quello di Acube dato che ho delle credenziali di test, scusami per il ritardo nel rispondere.

KristianLentino99 commented 2 years ago

o lavoro direttamente sulla libreria sender generica?

Skullbock commented 2 years ago

Sono tutti subsplit quindi basta una pr qui! Riesci per caso a testare i due esistenti? Grazie 🙏🏻

KristianLentino99 commented 2 years ago

Per acube sto testando proprio in questo momento , in ogni subsplit carico nella cartella tests una cartella samples con dei xml di prova, va bene?

Skullbock commented 2 years ago

Ottimo 🙏🏻

KristianLentino99 commented 2 years ago

@Skullbock ho dovuto correggere due cose, ma mi sembra andare acube , una domanda, perchè la funzione send è void? il response della funzione send serve nel return solitamente

KristianLentino99 commented 2 years ago

nel caso di acube ti viene tornato lo UID della fatture che potrebbe far comodo salvarsi da qualche parte (o controllare se viene tornato per sapere che è andato tutto a buon fine)

KristianLentino99 commented 2 years ago

@Skullbock per le fatture semplificate Acube prevede un endpoint diverso da quello di una fattura classica, per ora i test sono stati un successo su fattura semplice con una linea e multilinea, fallisce con fattura semplificata

Skullbock commented 2 years ago

L'idea è che send non debba ritornare niente in caso di successo, e emettere un'eccezione in caso di errore. Essendo che ogni sender può tornare dati diversi sarebbe impossibile standardizzare il tipo di output.

L'idea originale è che ogni sender implementi altri metodi per leggere eventuali dati ritornati, che andrebbero quindi salvati in locale nella classe sender.

Diciamo che l'ideale sarebbe che una volta sviluppati 3/4 sender, di trovare un'interfaccia comune anche per il "risultato" del send.

KristianLentino99 commented 2 years ago

@Skullbock ho capito, la mia esperienza tuttavia mi dice che già e Acube e Aruba tornano dati abbastanza diversi tra loro . sto elaborando una PR per gestire le fatture semplificate con Acube

KristianLentino99 commented 2 years ago

image ho risolto per la fattura semplificata, tuttavia, ai fini di creare degli unit test , ho dovuto modificare il ritorno della funzione send di Acube, può andare per ora o faccio tornare void?

Skullbock commented 2 years ago

Fai pure la PR che domani ci do un occhio e vediamo come integrare al meglio 👍🏻

Occhio a non pubblicare i dati di connessione a Acube nella Pr 😅

KristianLentino99 commented 2 years ago

no no tranquillo ho già tolto tutto 😂 , faccio un po' di check al codice e invio la pr