array('Codice' => 'TD01', 'Descrizione' => 'Fattura'), 'TD02' => array('Codice' => 'TD02', 'Descrizione' => 'Acconto/Anticipo su fattura'), 'TD03' => array('Codice' => 'TD03', 'Descrizione' => 'Acconto/Anticipo su parcella'), 'TD04' => array('Codice' => 'TD04', 'Descrizione' => 'Nota di credito'), 'TD05' => array('Codice' => 'TD05', 'Descrizione' => 'Nota di debito'), 'TD06' => array('Codice' => 'TD06', 'Descrizione' => 'Parcella') ); public function __construct() { $this->_ipManager = new App_Service_IpManager(); } public function getCredenzialiUtente() { return $this->_credenzialiUtente; } public function setCredenzialiUtente($credenzialiUtente) { if (!isset($credenzialiUtente['CustomerCode'])) throw new Exception("Errore campo 'customerCode' non impostato nelle credenziali"); if (!isset($credenzialiUtente['Password'])) throw new Exception("Errore campo 'Password' non impostato nelle credenziali"); $this->_credenzialiUtente = $credenzialiUtente; } /************************ FUNZIONI FATTURE INVIATE ********************************************************/ public function verificaStatoServizioFeInviateServer() { $this->setCredenzialiUtente(array( 'CustomerCode' => '', 'Password' => '' )); $this->_soapClient = new App_Service_SoapFeInviate($this->getCredenzialiUtente()); $result = $this->_soapClient->ContattoHub(); //Controllo eventuali errori sulla rispsota if ($result->ContattoHubResult != '0') { return false; } else { return true; } } public function getFatturaInviata($idSdi){ $this->_soapClient = new App_Service_SoapFeInviate($this->getCredenzialiUtente()); $params = array( 'paramFilter' => array( 'IdSdi' => $idSdi, 'DataCustomerServicesConsumption' => false, 'DataFullInvoices' => true )); $result = $this->_soapClient->GetElectronicInvoices($this->_soapClient->mergeParamsCredenziali($params)); //Controllo eventuali errori sulla rispsota if ($result->GetElectronicInvoicesResult->ResultCode != 'Success') { $this->SoapErrorResultHandler($result->GetElectronicInvoicesResult); } if (is_object($result->GetElectronicInvoicesResult->ElectronicInvoices->ElectronicInvoice)) { $data = array(0 => (array)$result->GetElectronicInvoicesResult->ElectronicInvoices->ElectronicInvoice); } elseif (is_array($result->GetElectronicInvoicesResult->ElectronicInvoices->ElectronicInvoice)) { $data = $result->GetElectronicInvoicesResult->ElectronicInvoices->ElectronicInvoice; } else { $data = array(); } // Zend_Registry::get('log')->info(print_r($this->_soapClient->getLastRequest(),true)); // Zend_Registry::get('log')->info(print_r($data,true)); return $data; } public function getEsitoFatturaInviata($idEsito, $tipoMessaggiOEsito, $getXmlData = false) { $this->_soapClient = new App_Service_SoapFeInviate($this->getCredenzialiUtente()); $params = array( 'paramFileOutcome' => array( 'IdOutcome' => $idEsito )); $result = $this->_soapClient->GetFileElectronicInvoiceOutcome($this->_soapClient->mergeParamsCredenziali($params)); //Controllo eventuali errori sulla rispsota if ($result->GetFileElectronicInvoiceOutcomeResult->ResultCode != 'Success') { $this->SoapErrorResultHandler($result->GetFileElectronicInvoiceOutcomeResult); } $xmlCode = $result->GetFileElectronicInvoiceOutcomeResult->File; $responseData = array( 'xmlFile' => $this->addXslTagToXml($xmlCode, $this->getXslByTipoMessaggioEsito($tipoMessaggiOEsito)), 'filename' => $result->GetFileElectronicInvoiceOutcomeResult->Filename ); if ($getXmlData) { $responseData['xmlData'] = simplexml_load_string($xmlCode); } return $responseData; } /** * @param $idFatt - Id della fattura da recuparare dai server della 2C * @param bool $xmlData - true: restiuisce i dati in formato xml della fattura elettronica | false: non li restituisce (DEFAULT: false) * @param bool $onlyXmlData - restituisce solo i dati xml della fattura elettronica (DEFAULT: false) * @param bool $fileFirmato - true: resituisce il file firmato .p7m (DEFAULT: false) * @param bool $getXslProcessed - restituisce l'html della fattura elettronica elaborato con il foglio di stile (DEFAULT: false) * @param string $xslFile - Indica il file del foglio di stile da utilizzare (DEFAULT: "fatturaordinaria_v1_2_1.xsl") * @return array|bool|SimpleXMLElement * @throws App_Controller_Errors_WebServiceError * @throws Zend_Exception */ public function getFatturaInviataXml($idFatt, $xmlData = false, $onlyXmlData = false, $fileFirmato = false, $getXslProcessed = false, $xslFile = "fatturaordinaria_v1_2_1.xsl") { $this->_soapClient = new App_Service_SoapFeInviate($this->getCredenzialiUtente()); $params = array( 'paramFileInvoice' => array( 'IdInvoice' => $idFatt, 'ExtractionP7M' => !$fileFirmato )); $result = $this->_soapClient->GetFileElectronicInvoice($this->_soapClient->mergeParamsCredenziali($params)); Zend_Registry::get('log')->info(print_r($result,true)); //Controllo eventuali errori sulla rispsota if ($result->GetFileElectronicInvoiceResult->ResultCode != 'Success') { $this->SoapErrorResultHandler($result->GetFileElectronicInvoiceResult); } if ($xmlData && !$fileFirmato) { $xmlData = simplexml_load_string($result->GetFileElectronicInvoiceResult->File); //Elimino eventuali allegati dall'xml data per non appesantire la chiamata foreach ($xmlData->FatturaElettronicaBody as $body) { if (isset($body->Allegati)) { foreach ($body->Allegati as $allegato) { unset($allegato->Attachment); } } } } if (!$fileFirmato) $filename = $xmlData->FatturaElettronicaHeader->DatiTrasmissione->IdTrasmittente->IdPaese . $xmlData->FatturaElettronicaHeader->DatiTrasmissione->IdTrasmittente->IdCodice . '_' . $xmlData->FatturaElettronicaHeader->DatiTrasmissione->ProgressivoInvio . ".xml"; else $filename = $result->GetFileElectronicInvoiceResult->Filename; if ($onlyXmlData && !$getXslProcessed) { return $xmlData; } if ($getXslProcessed) { $tipoFattura = self::TipiDocumentoFatturaElettronica[$xmlData->FatturaElettronicaBody->DatiGenerali->DatiGeneraliDocumento->TipoDocumento . ""]; $dataDocumento = implode('/', array_reverse(explode("-", $xmlData->FatturaElettronicaBody->DatiGenerali->DatiGeneraliDocumento->Data . ""))); $nomeFileFattura = $tipoFattura['Descrizione'] . " " . $xmlData->FatturaElettronicaBody->DatiGenerali->DatiGeneraliDocumento->Numero . " del " . $dataDocumento; return array( 'htmlProcessed' => $this->getXslCodeProcessed($result->GetFileElectronicInvoiceResult->File, $xslFile), 'Filename' => $nomeFileFattura ); } //Se il file è firmato (p7m) allora non elaboro il file xml per aggiungere il foglio di stile altrimenti si $elaboraXml = !preg_match('/.p7m/', $filename); if ($elaboraXml) { $file = $this->addXslTagToXml($result->GetFileElectronicInvoiceResult->File, $xslFile); $allegati = $this->estraiAllegatoDaXml($result->GetFileElectronicInvoiceResult->File); } else { $file = $result->GetFileElectronicInvoiceResult->File; $allegati = array(); } return array( 'File' => $file, 'Filename' => $filename, 'XmlData' => $xmlData, 'Allegati' => $allegati, ); } /**********************************************************/ private function getXslByTipoMessaggioEsito($tipo) { switch ($tipo) { case'MC': case'MT': case'NS': case'RC': return $tipo . "_v1_1.xsl"; break; case'DT': return $tipo . "_v1_0.xsl"; break; default: return "NE_v1_0.xsl"; break; } } private function addXslTagToXml($xmlCode, $xslFileName) { $doc = new DOMDocument(); $doc->loadXML($xmlCode); if ($doc->firstChild->nodeName == 'xml-stylesheet') { $doc->firstChild->nodeValue = 'type="text/xsl" href="' . $xslFileName . '"'; return $doc->saveXML(); } $newDoc = new DOMDocument('1.0', 'UTF-8'); $newDoc->preserveWhiteSpace = true; $newDoc->formatOutput = true; $newDoc->createElement("xml"); $styleSheet = $newDoc->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="' . $xslFileName . '"'); $newDoc->appendChild($styleSheet); $newNode = $newDoc->importNode($doc->firstChild, true); $newDoc->appendChild($newNode); return $newDoc->saveXML(); } private function estraiAllegatoDaXml($xmlCode) { $doc = new DOMDocument(); $doc->loadXML($xmlCode); $allegati = $doc->getElementsByTagName('Allegati'); $allegatiTmp = array(); foreach ($allegati as $allegato) { array_push($allegatiTmp, array( 'NomeFile' => $allegato->getElementsByTagName('NomeAttachment')[0]->nodeValue, 'FormatoAttachment' => $allegato->getElementsByTagName('FormatoAttachment')[0]->nodeValue, 'File' => $allegato->getElementsByTagName('Attachment')[0]->nodeValue )); } return $allegatiTmp; } private function SoapErrorResultHandler($result) { if (trim(str_replace('Errore -->', '', trim($result->ResultMessage))) == 'Impossibile recuperare il cliente') { throw new Exception("Credenziali servizio FatturaFE non valide"); } else throw new Exception(trim($result->ResultMessage)); } private function xml2array($xmlObject, $out = array()) { foreach ((array)$xmlObject as $index => $node) $out[$index] = (is_object($node)) ? $this->xml2array($node) : $node; return $out; } private function getXslCodeProcessed($xmlCode, $xslFile) { $xslPath = APPLICATION_PATH . "/../../docs/xsl/"; $tmpFile = APPLICATION_PATH . "/../../docs/tmp/" . date('d_m_Hisu') . ".xml"; $myfile = fopen($tmpFile, "w"); fwrite($myfile, $xmlCode); fclose($myfile); // Load the XML source $xml = new DOMDocument; $xml->load($tmpFile); unlink($tmpFile); $xsl = new DOMDocument; $XslPath = $xslPath . $xslFile; if (!file_exists($XslPath)) { throw new Exception("File xsl non trovato"); } $xsl->load($XslPath); // Configure the transformer $proc = new XSLTProcessor; $proc->importStyleSheet($xsl); // attach the xsl rules return $proc->transformToXML($xml); } /** * Questa funzione passato un filename e un array contente i filename già utilizzati ne rinomina i duplicati aggiungendo "(incremento)" alla fine del nomefile * * @param $filename * @param $listFileNamePresent * @param int $x * @param null $filenameOriginal * @return string */ private function checkDuplicatedFileName($filename, &$listFileNamePresent, $x = 0, $filenameOriginal = null) { if (!in_array(strtolower($filename), $listFileNamePresent)) { array_push($listFileNamePresent, strtolower($filename)); return $filename; } if ($x == 0) $filenameOriginal = pathinfo($filename, PATHINFO_FILENAME); $x++; $filename = $filenameOriginal . "($x)." . pathinfo($filename, PATHINFO_EXTENSION); //Ricorsione return $this->checkDuplicatedFileName($filename, $listFileNamePresent, $x, $filenameOriginal); } private function getFileSizeInByte($base64string) { $bytes = strlen(base64_decode($base64string)); return round($bytes, 2); } }