Пример #1
0
 /**
  * Método principal del comando
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-12-15
  */
 public function main()
 {
     // cargar XML y extraer arreglo con datos de carátula y DTEs
     $EnvioDte = new \sasco\LibreDTE\Sii\EnvioDte();
     $EnvioDte->loadXML(file_get_contents($this->args['xml']));
     $Caratula = $EnvioDte->getCaratula();
     $Documentos = $EnvioDte->getDocumentos();
     // procesar cada DTEs e ir creando los archivos PDF
     foreach ($Documentos as $DTE) {
         if (!$DTE->getDatos()) {
             $this->error('No se pudieron obtener los datos de uno de los DTE del XML');
         }
         $this->out('Generando PDF para DTE ' . $DTE->getID());
         $pdf = new \sasco\LibreDTE\Sii\PDF\Dte($this->args['papel']);
         $pdf->setFooterText();
         if ($this->args['logo']) {
             $pdf->setLogo($this->args['logo']);
         }
         $pdf->setResolucion(['FchResol' => $Caratula['FchResol'], 'NroResol' => $Caratula['NroResol']]);
         $pdf->setWebVerificacion($this->args['web']);
         $pdf->agregar($DTE->getDatos(), $DTE->getTED());
         if (isset($this->args['cedible'])) {
             $pdf->setCedible(true);
             $pdf->agregar($DTE->getDatos(), $DTE->getTED());
         }
         $pdf->Output($this->args['dir'] . '/dte_' . $Caratula['RutEmisor'] . '_' . $DTE->getID() . '.pdf', 'F');
     }
     return 0;
 }
Пример #2
0
 /**
  * Método que genera el XML de EnvioDTE a partir de los datos ya
  * normalizados de un DTE temporal
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
  * @version 2016-01-02
  */
 public function getEnvioDte($folio = 0, \sasco\LibreDTE\Sii\Folios $Folios = null, \sasco\LibreDTE\FirmaElectronica $Firma = null)
 {
     $dte = json_decode($this->datos, true);
     if (!$dte) {
         return false;
     }
     $dte['Encabezado']['IdDoc']['Folio'] = $folio;
     $Dte = new \sasco\LibreDTE\Sii\Dte($dte, false);
     if ($Folios and !$Dte->timbrar($Folios)) {
         return false;
     }
     if ($Firma and !$Dte->firmar($Firma)) {
         return false;
     }
     $EnvioDte = new \sasco\LibreDTE\Sii\EnvioDte();
     $EnvioDte->agregar($Dte);
     if ($Firma) {
         $EnvioDte->setFirma($Firma);
     }
     $Emisor = $this->getEmisor();
     $EnvioDte->setCaratula(['RutEnvia' => $Firma ? $Firma->getID() : false, 'RutReceptor' => $Emisor->certificacion ? '60803000-K' : $Dte->getReceptor(), 'FchResol' => $Emisor->certificacion ? $Emisor->certificacion_resolucion : $Emisor->resolucion_fecha, 'NroResol' => $Emisor->certificacion ? 0 : $Emisor->resolucion_numero]);
     return $EnvioDte;
 }
 * un EnvioDTE, el XML generado deberá ser subido "a mano" a
 * https://www4.sii.cl/pfeInternet
 *
 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
 * @version 2015-09-16
 */
// respuesta en texto plano
header('Content-type: text/plain; charset=ISO-8859-1');
// incluir archivos php de la biblioteca y configuraciones
include 'inc.php';
// datos para validar
$archivo_recibido = 'xml/intercambio/ENVIO_DTE_420328.xml';
$RutReceptor_esperado = '76192083-9';
$RutEmisor_esperado = '88888888-8';
// Cargar EnvioDTE y extraer arreglo con datos de carátula y DTEs
$EnvioDte = new \sasco\LibreDTE\Sii\EnvioDte();
$EnvioDte->loadXML(file_get_contents($archivo_recibido));
$Caratula = $EnvioDte->getCaratula();
$Documentos = $EnvioDte->getDocumentos();
// caratula
$caratula = ['RutResponde' => $RutReceptor_esperado, 'RutRecibe' => $Caratula['RutEmisor'], 'IdRespuesta' => 1];
// objeto para la respuesta
$RespuestaEnvio = new \sasco\LibreDTE\Sii\RespuestaEnvio();
// procesar cada DTE
$i = 1;
foreach ($Documentos as $DTE) {
    $estado = !$DTE->getEstadoValidacion(['RUTEmisor' => $RutEmisor_esperado, 'RUTRecep' => $RutReceptor_esperado]) ? 0 : 2;
    $RespuestaEnvio->agregarRespuestaDocumento(['TipoDTE' => $DTE->getTipo(), 'Folio' => $DTE->getFolio(), 'FchEmis' => $DTE->getFechaEmision(), 'RUTEmisor' => $DTE->getEmisor(), 'RUTRecep' => $DTE->getReceptor(), 'MntTotal' => $DTE->getMontoTotal(), 'CodEnvio' => $i++, 'EstadoDTE' => $estado, 'EstadoDTEGlosa' => \sasco\LibreDTE\Sii\RespuestaEnvio::$estados['respuesta_documento'][$estado]]);
}
// asignar carátula y Firma
$RespuestaEnvio->setCaratula($caratula);
 /**
  * Acción para la etapa de certificación de intercambio de DTEs
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-11
  */
 public function intercambio()
 {
     $this->set(['nav' => $this->nav]);
     if (!isset($_POST['submit'])) {
         return;
     }
     // verificar que se hayan pasado los datos requeridos
     if (!isset($_FILES['xml']) or $_FILES['xml']['error']) {
         \sowerphp\core\Model_Datasource_Session::message('Hubo algún problema al subir el XML EnvioDTE', 'error');
         return;
     }
     if (empty($_POST['emisor'])) {
         \sowerphp\core\Model_Datasource_Session::message('RUT emisor esperado no puede estar en blanco', 'error');
         return;
     }
     if (empty($_POST['receptor'])) {
         \sowerphp\core\Model_Datasource_Session::message('RUT receptor esperado no puede estar en blanco', 'error');
         return;
     }
     if (!isset($_FILES['firma']) or $_FILES['firma']['error']) {
         \sowerphp\core\Model_Datasource_Session::message('Hubo algún problema al subir la firma electrónica', 'error');
         return;
     }
     // Cargar EnvioDTE y extraer arreglo con datos de carátula y DTEs
     $EnvioDte = new \sasco\LibreDTE\Sii\EnvioDte();
     $EnvioDte->loadXML(file_get_contents($_FILES['xml']['tmp_name']));
     $Caratula = $EnvioDte->getCaratula();
     // objeto firma electrónica
     try {
         $Firma = new \sasco\LibreDTE\FirmaElectronica(['data' => file_get_contents($_FILES['firma']['tmp_name']), 'pass' => $_POST['contrasenia']]);
     } catch (\Exception $e) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible abrir la firma digital, quizás contraseña incorrecta', 'error');
         return;
     }
     // generar XML RecepcionDTE.xml
     $RecepcionDTE = $this->intercambio_RecepcionDTE($EnvioDte, $_POST['emisor'], $_POST['receptor'], ['RutResponde' => $_POST['receptor'], 'RutRecibe' => $Caratula['RutEmisor'], 'IdRespuesta' => 1, 'NmbContacto' => $Firma->getName(), 'MailContacto' => $Firma->getEmail()], $Firma);
     if (!$RecepcionDTE) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible generar RecepcionDTE.xml', 'error');
         return;
     }
     // generar XML EnvioRecibos.xml
     $EnvioRecibos = $this->intercambio_EnvioRecibos($EnvioDte, ['RutResponde' => $_POST['receptor'], 'RutRecibe' => $Caratula['RutEmisor'], 'NmbContacto' => $Firma->getName(), 'MailContacto' => $Firma->getEmail()], $Firma);
     if (!$EnvioRecibos) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible generar EnvioRecibos.xml', 'error');
         return;
     }
     // generar XML ResultadoDTE.xml
     $ResultadoDTE = $this->intercambio_ResultadoDTE($EnvioDte, $_POST['emisor'], $_POST['receptor'], ['RutResponde' => $_POST['receptor'], 'RutRecibe' => $Caratula['RutEmisor'], 'IdRespuesta' => 1, 'NmbContacto' => $Firma->getName(), 'MailContacto' => $Firma->getEmail()], $Firma);
     if (!$ResultadoDTE) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible generar ResultadoDTE.xml', 'error');
         return;
     }
     // aquí se tienen los 3 XML, se guardan en un único directorio
     $dir = TMP . '/intercambio_' . $Caratula['RutEmisor'] . '_' . date('U');
     if (!mkdir($dir)) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible generar el archivo comprimido con los XML', 'error');
         return;
     }
     file_put_contents($dir . '/1_RecepcionDTE.xml', $RecepcionDTE);
     file_put_contents($dir . '/2_EnvioRecibos.xml', $EnvioRecibos);
     file_put_contents($dir . '/3_ResultadoDTE.xml', $ResultadoDTE);
     unset($RecepcionDTE, $EnvioRecibos, $ResultadoDTE);
     // entregar archivos XML comprimidos al usuario
     \sasco\LibreDTE\File::compress($dir, ['format' => 'zip', 'delete' => true]);
 }
// caratula para el envío de los dte
$caratula = ['RutReceptor' => '60803000-K', 'FchResol' => '2014-12-05', 'NroResol' => 0];
// datos del emisor
$Emisor = ['RUTEmisor' => '76192083-9', 'RznSoc' => 'SASCO SpA', 'GiroEmis' => 'Servicios integrales de informática', 'Acteco' => 726000, 'DirOrigen' => 'Santiago', 'CmnaOrigen' => 'Santiago'];
// datos el recepor
$Receptor = ['RUTRecep' => '55666777-8', 'RznSocRecep' => 'Cliente S.A.', 'DirRecep' => 'Santiago', 'CmnaRecep' => 'Santiago'];
// datos de las boletas (cada elemento del arreglo $set_pruebas es una boleta)
$set_pruebas = [['Encabezado' => ['IdDoc' => ['TipoDTE' => 39, 'Folio' => $folios[39]], 'Emisor' => $Emisor, 'Receptor' => $Receptor], 'Detalle' => [['NmbItem' => 'Punto de Acceso WAP54G', 'QtyItem' => 4, 'PrcItem' => 35000], ['NmbItem' => 'Router WRT54GL', 'QtyItem' => 1, 'PrcItem' => 55000]]], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 39, 'Folio' => $folios[39] + 1], 'Emisor' => $Emisor, 'Receptor' => $Receptor], 'Detalle' => [['NmbItem' => 'Cables de red UTP CAT6 1.5m', 'QtyItem' => 20, 'PrcItem' => 1500]]], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 39, 'Folio' => $folios[39] + 2], 'Emisor' => $Emisor, 'Receptor' => $Receptor], 'Detalle' => [['NmbItem' => 'Rack 45U', 'QtyItem' => 1, 'PrcItem' => 650000], ['NmbItem' => 'Bandejas 19"', 'QtyItem' => 4, 'PrcItem' => 27000]]], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 39, 'Folio' => $folios[39] + 3], 'Emisor' => $Emisor, 'Receptor' => $Receptor], 'Detalle' => [['NmbItem' => 'Servidor HP Proliant XYZ', 'QtyItem' => 1, 'PrcItem' => 1500000], ['IndExe' => 1, 'NmbItem' => 'Intalación sistema operativo', 'QtyItem' => 1, 'PrcItem' => 8000], ['IndExe' => 1, 'NmbItem' => 'Instalación servicios ambiente web', 'QtyItem' => 1, 'PrcItem' => 50000]]], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 39, 'Folio' => $folios[39] + 4], 'Emisor' => $Emisor, 'Receptor' => $Receptor], 'Detalle' => [['NmbItem' => 'Pendrive con Debian GNU/Linux', 'QtyItem' => 1, 'PrcItem' => 10000]]], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 39, 'Folio' => $folios[39] + 5], 'Emisor' => $Emisor, 'Receptor' => $Receptor], 'Detalle' => [['NmbItem' => 'Tarjeta de red 100/1000 Mbps', 'QtyItem' => 2, 'PrcItem' => 5000], ['IndExe' => 1, 'NmbItem' => 'Instalación tarjeta de red y puesta en marcha VLANs', 'QtyItem' => 1, 'PrcItem' => 200000]]], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 39, 'Folio' => $folios[39] + 6], 'Emisor' => $Emisor, 'Receptor' => $Receptor], 'Detalle' => [['NmbItem' => 'Antena yagi 13 dBi', 'QtyItem' => 2, 'PrcItem' => 34000]]], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 39, 'Folio' => $folios[39] + 7], 'Emisor' => $Emisor, 'Receptor' => $Receptor], 'Detalle' => [['NmbItem' => 'Antena yagi 11 dBi', 'QtyItem' => 1, 'PrcItem' => 30000], ['NmbItem' => 'Antena omnidirecional 16 dBi', 'QtyItem' => 1, 'PrcItem' => 70000]]], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 39, 'Folio' => $folios[39] + 8], 'Emisor' => $Emisor, 'Receptor' => $Receptor], 'Detalle' => [['NmbItem' => 'Cable de red UTP cat6 1.5 m', 'QtyItem' => 10, 'PrcItem' => 1500], ['NmbItem' => 'Teléfono VoIP', 'QtyItem' => 10, 'PrcItem' => 45000], ['NmbItem' => 'Adaptador enchufe', 'QtyItem' => 10, 'PrcItem' => 250]]], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 39, 'Folio' => $folios[39] + 9], 'Emisor' => $Emisor, 'Receptor' => $Receptor], 'Detalle' => [['NmbItem' => 'Cable de red sin conectores', 'QtyItem' => 17, 'UnmdItem' => 'm', 'PrcItem' => 400]]]];
// Objetos de Firma y Folios
$Firma = new \sasco\LibreDTE\FirmaElectronica($config['firma']);
$Folios = [];
foreach ($folios as $tipo => $cantidad) {
    $Folios[$tipo] = new \sasco\LibreDTE\Sii\Folios(file_get_contents('xml/folios/' . $tipo . '.xml'));
}
// generar cada DTE, timbrar, firmar y agregar al sobre de EnvioBOLETA
$EnvioDTE = new \sasco\LibreDTE\Sii\EnvioDte();
foreach ($set_pruebas as $documento) {
    $DTE = new \sasco\LibreDTE\Sii\Dte($documento);
    if (!$DTE->timbrar($Folios[$DTE->getTipo()])) {
        break;
    }
    if (!$DTE->firmar($Firma)) {
        break;
    }
    $EnvioDTE->agregar($DTE);
}
$EnvioDTE->setFirma($Firma);
$EnvioDTE->setCaratula($caratula);
$EnvioDTE->generar();
if ($EnvioDTE->schemaValidate()) {
    echo $EnvioDTE->generar();
Пример #6
0
    $EnvioDTE->agregar($DTE);
}
$EnvioDTE->setFirma($Firma);
$EnvioDTE->setCaratula($caratula);
$EnvioDTE->generar();
if ($EnvioDTE->schemaValidate()) {
    if (is_writable('xml/EnvioBOLETA.xml')) {
        file_put_contents('xml/EnvioBOLETA.xml', $EnvioDTE->generar());
    }
    // guardar XML en sistema de archivos
    echo $EnvioDTE->generar();
}
// crear notas de crédito para el set de prueba
$notas_credito = [\sasco\LibreDTE\Arreglo::mergeRecursiveDistinct($set_pruebas[0], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 61, 'Folio' => $folios[61], 'MntBruto' => 1], 'Totales' => ['MntNeto' => 0, 'TasaIVA' => \sasco\LibreDTE\Sii::getIVA(), 'IVA' => 0, 'MntTotal' => 0]], 'Referencia' => ['TpoDocRef' => $set_pruebas[0]['Encabezado']['IdDoc']['TipoDTE'], 'FolioRef' => $set_pruebas[0]['Encabezado']['IdDoc']['Folio'], 'CodRef' => 1, 'RazonRef' => 'ANULA BOLETA']]), \sasco\LibreDTE\Arreglo::mergeRecursiveDistinct($set_pruebas[2], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 61, 'Folio' => $folios[61] + 1, 'MntBruto' => 1], 'Totales' => ['MntNeto' => 0, 'TasaIVA' => \sasco\LibreDTE\Sii::getIVA(), 'IVA' => 0, 'MntTotal' => 0]], 'Referencia' => ['TpoDocRef' => $set_pruebas[2]['Encabezado']['IdDoc']['TipoDTE'], 'FolioRef' => $set_pruebas[2]['Encabezado']['IdDoc']['Folio'], 'CodRef' => 1, 'RazonRef' => 'ANULA BOLETA']]), \sasco\LibreDTE\Arreglo::mergeRecursiveDistinct($set_pruebas[4], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 61, 'Folio' => $folios[61] + 2, 'MntBruto' => 1], 'Totales' => ['MntNeto' => 0, 'TasaIVA' => \sasco\LibreDTE\Sii::getIVA(), 'IVA' => 0, 'MntTotal' => 0]], 'Referencia' => ['TpoDocRef' => $set_pruebas[4]['Encabezado']['IdDoc']['TipoDTE'], 'FolioRef' => $set_pruebas[4]['Encabezado']['IdDoc']['Folio'], 'CodRef' => 1, 'RazonRef' => 'ANULA BOLETA']]), \sasco\LibreDTE\Arreglo::mergeRecursiveDistinct($set_pruebas[6], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 61, 'Folio' => $folios[61] + 3, 'MntBruto' => 1], 'Totales' => ['MntNeto' => 0, 'TasaIVA' => \sasco\LibreDTE\Sii::getIVA(), 'IVA' => 0, 'MntTotal' => 0]], 'Detalle' => [['QtyItem' => $set_pruebas[6]['Detalle'][0]['QtyItem'] * 0.4]], 'Referencia' => ['TpoDocRef' => $set_pruebas[6]['Encabezado']['IdDoc']['TipoDTE'], 'FolioRef' => $set_pruebas[6]['Encabezado']['IdDoc']['Folio'], 'CodRef' => 3, 'RazonRef' => 'SE REBAJA EN UN 40%']]), \sasco\LibreDTE\Arreglo::mergeRecursiveDistinct($set_pruebas[9], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 61, 'Folio' => $folios[61] + 4, 'MntBruto' => 1], 'Totales' => ['MntNeto' => 0, 'TasaIVA' => \sasco\LibreDTE\Sii::getIVA(), 'IVA' => 0, 'MntTotal' => 0]], 'Detalle' => [['QtyItem' => $set_pruebas[9]['Detalle'][0]['QtyItem'] * 0.4]], 'Referencia' => ['TpoDocRef' => $set_pruebas[9]['Encabezado']['IdDoc']['TipoDTE'], 'FolioRef' => $set_pruebas[9]['Encabezado']['IdDoc']['Folio'], 'CodRef' => 3, 'RazonRef' => 'SE REBAJA EN UN 40%']])];
// generar cada DTE, timbrar, firmar y agregar al sobre de EnvioDTE
$EnvioDTE = new \sasco\LibreDTE\Sii\EnvioDte();
foreach ($notas_credito as $documento) {
    $DTE = new \sasco\LibreDTE\Sii\Dte($documento);
    if (!$DTE->timbrar($Folios[$DTE->getTipo()])) {
        break;
    }
    if (!$DTE->firmar($Firma)) {
        break;
    }
    $EnvioDTE->agregar($DTE);
}
$EnvioDTE->setFirma($Firma);
$EnvioDTE->setCaratula($caratula);
$EnvioDTE->generar();
if ($EnvioDTE->schemaValidate()) {
    if (is_writable('xml/EnvioDTE.xml')) {
 /**
  * Método que entrega el arreglo con los datos que se usaron para generar el
  * XML del DTE
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-24
  */
 public function getDatos()
 {
     if (!$this->datos) {
         $EnvioDte = new \sasco\LibreDTE\Sii\EnvioDte();
         $EnvioDte->loadXML(base64_decode($this->xml));
         $datos = $EnvioDte->getDocumentos()[0]->getDatos();
     }
     return $datos;
 }
 * Ejemplo que genera el XML de respuesta a la recepción de un DTE, el XML
 * generado deberá ser subido "a mano" a https://www4.sii.cl/pfeInternet
 *
 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
 * @version 2015-09-16
 */
// respuesta en texto plano
header('Content-type: text/plain; charset=ISO-8859-1');
// incluir archivos php de la biblioteca y configuraciones
include 'inc.php';
// datos para validar
$archivo_recibido = 'xml/intercambio/ENVIO_DTE_420328.xml';
$RutReceptor_esperado = '76192083-9';
$RutEmisor_esperado = '88888888-8';
// Cargar EnvioDTE y extraer arreglo con datos de carátula y DTEs
$EnvioDte = new \sasco\LibreDTE\Sii\EnvioDte();
$EnvioDte->loadXML(file_get_contents($archivo_recibido));
$Caratula = $EnvioDte->getCaratula();
$Documentos = $EnvioDte->getDocumentos();
// caratula
$caratula = ['RutResponde' => $RutReceptor_esperado, 'RutRecibe' => $Caratula['RutEmisor'], 'IdRespuesta' => 1];
// procesar cada DTE
$RecepcionDTE = [];
foreach ($Documentos as $DTE) {
    $estado = $DTE->getEstadoValidacion(['RUTEmisor' => $RutEmisor_esperado, 'RUTRecep' => $RutReceptor_esperado]);
    $RecepcionDTE[] = ['TipoDTE' => $DTE->getTipo(), 'Folio' => $DTE->getFolio(), 'FchEmis' => $DTE->getFechaEmision(), 'RUTEmisor' => $DTE->getEmisor(), 'RUTRecep' => $DTE->getReceptor(), 'MntTotal' => $DTE->getMontoTotal(), 'EstadoRecepDTE' => $estado, 'RecepDTEGlosa' => \sasco\LibreDTE\Sii\RespuestaEnvio::$estados['documento'][$estado]];
}
// armar respuesta de envío
$estado = $EnvioDte->getEstadoValidacion(['RutReceptor' => $RutReceptor_esperado]);
$RespuestaEnvio = new \sasco\LibreDTE\Sii\RespuestaEnvio();
$RespuestaEnvio->agregarRespuestaEnvio(['NmbEnvio' => basename($archivo_recibido), 'CodEnvio' => 1, 'EnvioDTEID' => $EnvioDte->getID(), 'Digest' => $EnvioDte->getDigest(), 'RutEmisor' => $EnvioDte->getEmisor(), 'RutReceptor' => $EnvioDte->getReceptor(), 'EstadoRecepEnv' => $estado, 'RecepEnvGlosa' => \sasco\LibreDTE\Sii\RespuestaEnvio::$estados['envio'][$estado], 'NroDTE' => count($RecepcionDTE), 'RecepcionDTE' => $RecepcionDTE]);
 /**
  * Recurso de la API que genera el PDF de los DTEs contenidos en un EnvioDTE
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2016-01-15
  */
 public function _api_generar_pdf_POST()
 {
     // verificar si se pasaron credenciales de un usuario
     $User = $this->Api->getAuthUser();
     if (is_string($User)) {
         $this->Api->send($User, 401);
     }
     // si hubo problemas al subir el archivo error
     if (!isset($this->Api->data['xml']) and (!isset($_FILES['xml']) or $_FILES['xml']['error'])) {
         $this->Api->send('Hubo algún problema al recibir el archivo XML con el EnvioDTE', 500);
     }
     // recuperar contenido del archivo xml
     if (isset($this->Api->data['xml'])) {
         $xml = base64_decode($this->Api->data['xml']);
     } else {
         $xml = file_get_contents($_FILES['xml']['tmp_name']);
     }
     // recuperar contenido del logo (si existe)
     if (isset($this->Api->data['logo'])) {
         $logo = base64_decode($this->Api->data['logo']);
     } else {
         if (isset($_FILES['logo']) and !$_FILES['logo']['error']) {
             $logo = file_get_contents($_FILES['logo']['tmp_name']);
         }
     }
     // crear flag cedible
     $cedible = !empty($this->Api->data['cedible']) ? $this->Api->data['cedible'] : false;
     // crear flag papel continuo
     $papelContinuo = !empty($this->Api->data['papelContinuo']) ? $this->Api->data['papelContinuo'] : false;
     // crear opción para web de verificación
     $webVerificacion = !empty($this->Api->data['webVerificacion']) ? $this->Api->data['webVerificacion'] : false;
     // sin límite de tiempo para generar documentos
     set_time_limit(0);
     // Cargar EnvioDTE y extraer arreglo con datos de carátula y DTEs
     $EnvioDte = new \sasco\LibreDTE\Sii\EnvioDte();
     $EnvioDte->loadXML($xml);
     $Caratula = $EnvioDte->getCaratula();
     $Documentos = $EnvioDte->getDocumentos();
     // directorio temporal para guardar los PDF
     $dir = sys_get_temp_dir() . '/dte_' . $Caratula['RutEmisor'] . '_' . $Caratula['RutReceptor'] . '_' . str_replace(['-', ':', 'T'], '', $Caratula['TmstFirmaEnv']);
     if (is_dir($dir)) {
         \sasco\LibreDTE\File::rmdir($dir);
     }
     if (!mkdir($dir)) {
         $this->Api->send('No fue posible crear directorio temporal para DTEs', 500);
     }
     // procesar cada DTEs e ir agregándolo al PDF
     foreach ($Documentos as $DTE) {
         if (!$DTE->getDatos()) {
             $this->Api->send('No se pudieron obtener los datos de un DTE', 500);
         }
         // generar PDF
         $pdf = new \sasco\LibreDTE\Sii\PDF\Dte($papelContinuo);
         $pdf->setFooterText();
         if (isset($logo)) {
             $pdf->setLogo('@' . $logo);
         }
         $pdf->setResolucion(['FchResol' => $Caratula['FchResol'], 'NroResol' => $Caratula['NroResol']]);
         if ($webVerificacion) {
             $pdf->setWebVerificacion($webVerificacion);
         }
         $pdf->agregar($DTE->getDatos(), $DTE->getTED());
         if ($cedible and $DTE->esCedible()) {
             $pdf->setCedible(true);
             $pdf->agregar($DTE->getDatos(), $DTE->getTED());
         }
         $file = $dir . '/dte_' . $Caratula['RutEmisor'] . '_' . $DTE->getID() . '.pdf';
         $pdf->Output($file, 'F');
     }
     // si solo es un archivo y se pidió no comprimir se entrega directamente
     if (isset($this->Api->data['compress']) and !$this->Api->data['compress'] and !isset($Documentos[1])) {
         $this->response->sendFile($file, ['disposition' => 'attachement', 'exit' => false]);
         \sowerphp\general\Utility_File::rmdir($dir);
         exit(0);
     } else {
         \sasco\LibreDTE\File::compress($dir, ['format' => 'zip', 'delete' => true]);
     }
 }
 * electrónicas y notas de crédito electrónicas del set de prueba de boletas
 *
 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
 * @version 2015-12-14
 */
// respuesta en texto plano
header('Content-type: text/plain; charset=ISO-8859-1');
// incluir archivos php de la biblioteca y configuraciones
include 'inc.php';
// archivos
$boletas = 'xml/EnvioBOLETA.xml';
$notas_credito = 'xml/EnvioDTE.xml';
// cargar XML boletas y notas
$EnvioBOLETA = new \sasco\LibreDTE\Sii\EnvioDte();
$EnvioBOLETA->loadXML(file_get_contents($boletas));
$EnvioDTE = new \sasco\LibreDTE\Sii\EnvioDte();
$EnvioDTE->loadXML(file_get_contents($notas_credito));
// crear objeto para consumo de folios
$ConsumoFolio = new \sasco\LibreDTE\Sii\ConsumoFolio();
$ConsumoFolio->setFirma(new \sasco\LibreDTE\FirmaElectronica($config['firma']));
// agregar detalle de boletas
foreach ($EnvioBOLETA->getDocumentos() as $Dte) {
    $ConsumoFolio->agregar($Dte->getResumen());
}
// agregar detalle de notas de crédito
foreach ($EnvioDTE->getDocumentos() as $Dte) {
    $ConsumoFolio->agregar($Dte->getResumen());
}
// crear carátula para el envío (se hace después de agregar los detalles ya que
// así se obtiene automáticamente la fecha inicial y final de los documentos)
$CaratulaEnvioBOLETA = $EnvioBOLETA->getCaratula();
include 'inc.php';
// primer folio a usar para envio de set de pruebas
$folios = [33 => 21, 56 => 5, 61 => 13];
// caratula para el envío de los dte
$caratula = ['RutEnvia' => '11222333-4', 'RutReceptor' => '60803000-K', 'FchResol' => '2014-12-05', 'NroResol' => 0];
// datos del emisor
$Emisor = ['RUTEmisor' => '76192083-9', 'RznSoc' => 'SASCO SpA', 'GiroEmis' => 'Servicios integrales de informática', 'Acteco' => 726000, 'DirOrigen' => 'Santiago', 'CmnaOrigen' => 'Santiago'];
// datos de los DTE (cada elemento del arreglo $set_pruebas es un DTE)
$set_pruebas = [['Encabezado' => ['IdDoc' => ['TipoDTE' => 33, 'Folio' => $folios[33]], 'Emisor' => $Emisor, 'Receptor' => ['RUTRecep' => '55666777-8', 'RznSocRecep' => 'Empresa S.A.', 'GiroRecep' => 'Servicios jurídicos', 'DirRecep' => 'Santiago', 'CmnaRecep' => 'Santiago']], 'Detalle' => [['NmbItem' => 'Cajón AFECTO', 'QtyItem' => 123, 'PrcItem' => 923], ['NmbItem' => 'Relleno AFECTO', 'QtyItem' => 53, 'PrcItem' => 1473]], 'Referencia' => ['TpoDocRef' => 'SET', 'FolioRef' => $folios[33], 'RazonRef' => 'CASO 414175-1']], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 33, 'Folio' => $folios[33] + 1], 'Emisor' => $Emisor, 'Receptor' => ['RUTRecep' => '55666777-8', 'RznSocRecep' => 'Empresa S.A.', 'GiroRecep' => 'Servicios jurídicos', 'DirRecep' => 'Santiago', 'CmnaRecep' => 'Santiago']], 'Detalle' => [['NmbItem' => 'Pañuelo AFECTO', 'QtyItem' => 235, 'PrcItem' => 1926, 'DescuentoPct' => 4], ['NmbItem' => 'ITEM 2 AFECTO', 'QtyItem' => 161, 'PrcItem' => 990, 'DescuentoPct' => 5]], 'Referencia' => ['TpoDocRef' => 'SET', 'FolioRef' => $folios[33] + 1, 'RazonRef' => 'CASO 414175-2']], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 33, 'Folio' => $folios[33] + 2], 'Emisor' => $Emisor, 'Receptor' => ['RUTRecep' => '55666777-8', 'RznSocRecep' => 'Empresa S.A.', 'GiroRecep' => 'Servicios jurídicos', 'DirRecep' => 'Santiago', 'CmnaRecep' => 'Santiago']], 'Detalle' => [['NmbItem' => 'Pintura B&W AFECTO', 'QtyItem' => 24, 'PrcItem' => 1937], ['NmbItem' => 'ITEM 2 AFECTO', 'QtyItem' => 149, 'PrcItem' => 2975], ['IndExe' => 1, 'NmbItem' => 'ITEM 3 SERVICIO EXENTO', 'QtyItem' => 1, 'PrcItem' => 34705]], 'Referencia' => ['TpoDocRef' => 'SET', 'FolioRef' => $folios[33] + 2, 'RazonRef' => 'CASO 414175-3']], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 33, 'Folio' => $folios[33] + 3], 'Emisor' => $Emisor, 'Receptor' => ['RUTRecep' => '55666777-8', 'RznSocRecep' => 'Empresa S.A.', 'GiroRecep' => 'Servicios jurídicos', 'DirRecep' => 'Santiago', 'CmnaRecep' => 'Santiago']], 'Detalle' => [['NmbItem' => 'ITEM 1 AFECTO', 'QtyItem' => 81, 'PrcItem' => 1672], ['NmbItem' => 'ITEM 2 AFECTO', 'QtyItem' => 35, 'PrcItem' => 1405], ['IndExe' => 1, 'NmbItem' => 'ITEM 3 SERVICIO EXENTO', 'QtyItem' => 2, 'PrcItem' => 6767]], 'DscRcgGlobal' => ['TpoMov' => 'D', 'TpoValor' => '%', 'ValorDR' => 6], 'Referencia' => ['TpoDocRef' => 'SET', 'FolioRef' => $folios[33] + 3, 'RazonRef' => 'CASO 414175-4']], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 61, 'Folio' => $folios[61]], 'Emisor' => $Emisor, 'Receptor' => ['RUTRecep' => '55666777-8', 'RznSocRecep' => 'Empresa S.A.', 'GiroRecep' => 'Servicios jurídicos', 'DirRecep' => 'Santiago', 'CmnaRecep' => 'Santiago'], 'Totales' => ['MntTotal' => 0]], 'Detalle' => [['NmbItem' => 'Cajón AFECTO']], 'Referencia' => [['TpoDocRef' => 'SET', 'FolioRef' => $folios[61], 'RazonRef' => 'CASO 414175-5'], ['TpoDocRef' => 33, 'FolioRef' => $folios[33], 'CodRef' => 2, 'RazonRef' => 'CORRIGE GIRO DEL RECEPTOR']]], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 61, 'Folio' => $folios[61] + 1], 'Emisor' => $Emisor, 'Receptor' => ['RUTRecep' => '55666777-8', 'RznSocRecep' => 'Empresa S.A.', 'GiroRecep' => 'Servicios jurídicos', 'DirRecep' => 'Santiago', 'CmnaRecep' => 'Santiago'], 'Totales' => ['MntNeto' => 0, 'TasaIVA' => \sasco\LibreDTE\Sii::getIVA(), 'IVA' => 0, 'MntTotal' => 0]], 'Detalle' => [['NmbItem' => 'Pañuelo AFECTO', 'QtyItem' => 86, 'PrcItem' => 1926, 'DescuentoPct' => 4], ['NmbItem' => 'ITEM 2 AFECTO', 'QtyItem' => 109, 'PrcItem' => 990, 'DescuentoPct' => 5]], 'Referencia' => [['TpoDocRef' => 'SET', 'FolioRef' => $folios[61] + 1, 'RazonRef' => 'CASO 414175-6'], ['TpoDocRef' => 33, 'FolioRef' => $folios[33] + 1, 'CodRef' => 3, 'RazonRef' => 'DEVOLUCION DE MERCADERIAS']]], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 61, 'Folio' => $folios[61] + 2], 'Emisor' => $Emisor, 'Receptor' => ['RUTRecep' => '55666777-8', 'RznSocRecep' => 'Empresa S.A.', 'GiroRecep' => 'Servicios jurídicos', 'DirRecep' => 'Santiago', 'CmnaRecep' => 'Santiago'], 'Totales' => ['MntNeto' => 0, 'MntExe' => 0, 'TasaIVA' => \sasco\LibreDTE\Sii::getIVA(), 'IVA' => 0, 'MntTotal' => 0]], 'Detalle' => [['NmbItem' => 'Pintura B&W AFECTO', 'QtyItem' => 24, 'PrcItem' => 1937], ['NmbItem' => 'ITEM 2 AFECTO', 'QtyItem' => 149, 'PrcItem' => 2975], ['IndExe' => 1, 'NmbItem' => 'ITEM 3 SERVICIO EXENTO', 'QtyItem' => 1, 'PrcItem' => 34705]], 'Referencia' => [['TpoDocRef' => 'SET', 'FolioRef' => $folios[61] + 2, 'RazonRef' => 'CASO 414175-7'], ['TpoDocRef' => 33, 'FolioRef' => $folios[33] + 2, 'CodRef' => 1, 'RazonRef' => 'ANULA FACTURA']]], ['Encabezado' => ['IdDoc' => ['TipoDTE' => 56, 'Folio' => $folios[56]], 'Emisor' => $Emisor, 'Receptor' => ['RUTRecep' => '55666777-8', 'RznSocRecep' => 'Empresa S.A.', 'GiroRecep' => 'Servicios jurídicos', 'DirRecep' => 'Santiago', 'CmnaRecep' => 'Santiago'], 'Totales' => ['MntTotal' => 0]], 'Detalle' => [['NmbItem' => 'Cajón AFECTO']], 'Referencia' => [['TpoDocRef' => 'SET', 'FolioRef' => $folios[56], 'RazonRef' => 'CASO 414175-8'], ['TpoDocRef' => 61, 'FolioRef' => $folios[61], 'CodRef' => 1, 'RazonRef' => 'ANULA NOTA DE CREDITO ELECTRONICA']]]];
// Objetos de Firma, Folios y EnvioDTE
$Firma = new \sasco\LibreDTE\FirmaElectronica($config['firma']);
$Folios = [];
foreach ($folios as $tipo => $cantidad) {
    $Folios[$tipo] = new \sasco\LibreDTE\Sii\Folios(file_get_contents('xml/folios/' . $tipo . '.xml'));
}
$EnvioDTE = new \sasco\LibreDTE\Sii\EnvioDte();
// generar cada DTE, timbrar, firmar y agregar al sobre de EnvioDTE
foreach ($set_pruebas as $documento) {
    $DTE = new \sasco\LibreDTE\Sii\Dte($documento);
    if (!$DTE->timbrar($Folios[$DTE->getTipo()])) {
        break;
    }
    if (!$DTE->firmar($Firma)) {
        break;
    }
    $EnvioDTE->agregar($DTE);
}
// enviar dtes y mostrar resultado del envío: track id o bien =false si hubo error
$EnvioDTE->setCaratula($caratula);
$EnvioDTE->setFirma($Firma);
//file_put_contents('xml/EnvioDTE.xml', $EnvioDTE->generar()); // guardar XML en sistema de archivos
/**
 * @file 031-libro_boleta.php
 *
 * Ejemplo que genera el XML de LibroBoleta para boletas electrónicas
 *
 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
 * @version 2015-12-14
 */
// respuesta en texto plano
header('Content-type: text/plain; charset=ISO-8859-1');
// incluir archivos php de la biblioteca y configuraciones
include 'inc.php';
// archivos
$boletas = 'xml/EnvioBOLETA.xml';
// cargar XML boletas y notas
$EnvioBOLETA = new \sasco\LibreDTE\Sii\EnvioDte();
$EnvioBOLETA->loadXML(file_get_contents($boletas));
// crear objeto para libro de boletas
$LibroBoleta = new \sasco\LibreDTE\Sii\LibroBoleta();
$LibroBoleta->setFirma(new \sasco\LibreDTE\FirmaElectronica($config['firma']));
// agregar detalle de boletas
foreach ($EnvioBOLETA->getDocumentos() as $Dte) {
    $r = $Dte->getResumen();
    $LibroBoleta->agregar(['TpoDoc' => $r['TpoDoc'], 'FolioDoc' => $r['NroDoc'], 'Anulado' => in_array($r['NroDoc'], [1, 3, 5]) ? 'A' : false, 'FchEmiDoc' => $r['FchDoc'], 'RUTCliente' => $r['RUTDoc'], 'MntExe' => $r['MntExe'] ? $r['MntExe'] : false, 'MntTotal' => $r['MntTotal']]);
}
// crear carátula para el libro
$CaratulaEnvioBOLETA = $EnvioBOLETA->getCaratula();
$LibroBoleta->setCaratula(['RutEmisorLibro' => $CaratulaEnvioBOLETA['RutEmisor'], 'FchResol' => $CaratulaEnvioBOLETA['FchResol'], 'NroResol' => $CaratulaEnvioBOLETA['NroResol'], 'FolioNotificacion' => 1]);
// generar, validar schema y mostrar XML
$LibroBoleta->generar();
if ($LibroBoleta->schemaValidate()) {
 /**
  * Acción que procesa y responde al intercambio recibido
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-10-08
  */
 public function responder($codigo)
 {
     $Emisor = $this->getContribuyente();
     // si no se viene por post error
     if (!isset($_POST['submit'])) {
         \sowerphp\core\Model_Datasource_Session::message('No puede acceder de forma directa a ' . $this->request->request, 'error');
         $this->redirect(str_replace('responder', 'ver', $this->request->request));
     }
     // obtener DTE emitido
     $DteIntercambio = new Model_DteIntercambio($Emisor->rut, $codigo, (int) $Emisor->certificacion);
     if (!$DteIntercambio->exists()) {
         \sowerphp\core\Model_Datasource_Session::message('No existe el intercambio solicitado', 'error');
         $this->redirect('/dte/dte_intercambios');
     }
     // obtener firma
     $Firma = $Emisor->getFirma($this->Auth->User->id);
     if (!$Firma) {
         \sowerphp\core\Model_Datasource_Session::message('No hay firma electrónica asociada a la empresa (o bien no se pudo cargar), debe agregar su firma antes de generar DTE', 'error');
         $this->redirect('/dte/admin/firma_electronicas');
     }
     //
     // construir RecepcionDTE
     //
     $RecepcionDTE = [];
     $n_dtes = count($_POST['TipoDTE']);
     for ($i = 0; $i < $n_dtes; $i++) {
         $RecepcionDTE[] = ['TipoDTE' => $_POST['TipoDTE'][$i], 'Folio' => $_POST['Folio'][$i], 'FchEmis' => $_POST['FchEmis'][$i], 'RUTEmisor' => $_POST['RUTEmisor'][$i], 'RUTRecep' => $_POST['RUTRecep'][$i], 'MntTotal' => $_POST['MntTotal'][$i], 'EstadoRecepDTE' => $_POST['EstadoRecepDTE'][$i], 'RecepDTEGlosa' => $_POST['RecepDTEGlosa'][$i]];
     }
     // armar respuesta de envío
     $EnvioDte = new \sasco\LibreDTE\Sii\EnvioDte();
     $EnvioDte->loadXML(base64_decode($DteIntercambio->archivo_xml));
     $Caratula = $EnvioDte->getCaratula();
     $RespuestaEnvio = new \sasco\LibreDTE\Sii\RespuestaEnvio();
     $RespuestaEnvio->agregarRespuestaEnvio(['NmbEnvio' => $DteIntercambio->archivo, 'CodEnvio' => $DteIntercambio->codigo, 'EnvioDTEID' => $EnvioDte->getID(), 'Digest' => $EnvioDte->getDigest(), 'RutEmisor' => $EnvioDte->getEmisor(), 'RutReceptor' => $EnvioDte->getReceptor(), 'EstadoRecepEnv' => $_POST['EstadoRecepEnv'], 'RecepEnvGlosa' => $_POST['RecepEnvGlosa'], 'NroDTE' => count($RecepcionDTE), 'RecepcionDTE' => $RecepcionDTE]);
     // asignar carátula y Firma
     $RespuestaEnvio->setCaratula(['RutResponde' => $Emisor->rut . '-' . $Emisor->dv, 'RutRecibe' => $Caratula['RutEmisor'], 'IdRespuesta' => $DteIntercambio->codigo, 'NmbContacto' => $_POST['NmbContacto'], 'MailContacto' => $_POST['MailContacto']]);
     $RespuestaEnvio->setFirma($Firma);
     // generar y validar XML
     $RecepcionDTE_xml = $RespuestaEnvio->generar();
     if (!$RespuestaEnvio->schemaValidate()) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible generar RecepcionDTE.<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
         $this->redirect(str_replace('responder', 'ver', $this->request->request));
     }
     //
     // generar EnvioRecibos
     //
     $EnvioRecibos = new \sasco\LibreDTE\Sii\EnvioRecibos();
     $EnvioRecibos->setCaratula(['RutResponde' => $Emisor->rut . '-' . $Emisor->dv, 'RutRecibe' => $Caratula['RutEmisor'], 'NmbContacto' => $_POST['NmbContacto'], 'MailContacto' => $_POST['MailContacto']]);
     $EnvioRecibos->setFirma($Firma);
     // procesar cada DTE
     $EnvioRecibos_r = [];
     for ($i = 0; $i < $n_dtes; $i++) {
         if ($_POST['acuse'][$i]) {
             $EnvioRecibos->agregar(['TipoDoc' => $_POST['TipoDTE'][$i], 'Folio' => $_POST['Folio'][$i], 'FchEmis' => $_POST['FchEmis'][$i], 'RUTEmisor' => $_POST['RUTEmisor'][$i], 'RUTRecep' => $_POST['RUTRecep'][$i], 'MntTotal' => $_POST['MntTotal'][$i], 'Recinto' => $_POST['Recinto'], 'RutFirma' => $Firma->getID()]);
             $EnvioRecibos_r[] = 'T' . $_POST['TipoDTE'][$i] . 'F' . $_POST['Folio'][$i];
         }
     }
     // generar y validar XML
     if ($EnvioRecibos_r) {
         $EnvioRecibos_xml = $EnvioRecibos->generar();
         if (!$EnvioRecibos->schemaValidate()) {
             \sowerphp\core\Model_Datasource_Session::message('No fue posible generar EnvioRecibos.<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
             $this->redirect(str_replace('responder', 'ver', $this->request->request));
         }
     }
     //
     // generar ResultadoDTE
     //
     // objeto para la respuesta
     $RespuestaEnvio = new \sasco\LibreDTE\Sii\RespuestaEnvio();
     // procesar cada DTE
     for ($i = 0; $i < $n_dtes; $i++) {
         $estado = !$_POST['EstadoRecepDTE'][$i] ? 0 : 2;
         $RespuestaEnvio->agregarRespuestaDocumento(['TipoDTE' => $_POST['TipoDTE'][$i], 'Folio' => $_POST['Folio'][$i], 'FchEmis' => $_POST['FchEmis'][$i], 'RUTEmisor' => $_POST['RUTEmisor'][$i], 'RUTRecep' => $_POST['RUTRecep'][$i], 'MntTotal' => $_POST['MntTotal'][$i], 'CodEnvio' => $i + 1, 'EstadoDTE' => $estado, 'EstadoDTEGlosa' => \sasco\LibreDTE\Sii\RespuestaEnvio::$estados['respuesta_documento'][$estado]]);
     }
     // asignar carátula y Firma
     $RespuestaEnvio->setCaratula(['RutResponde' => $Emisor->rut . '-' . $Emisor->dv, 'RutRecibe' => $Caratula['RutEmisor'], 'IdRespuesta' => $DteIntercambio->codigo, 'NmbContacto' => $_POST['NmbContacto'], 'MailContacto' => $_POST['MailContacto']]);
     $RespuestaEnvio->setFirma($Firma);
     // generar y validar XML
     $ResultadoDTE_xml = $RespuestaEnvio->generar();
     if (!$RespuestaEnvio->schemaValidate()) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible generar ResultadoDTE.<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
         $this->redirect(str_replace('responder', 'ver', $this->request->request));
     }
     //
     // guardar estado del intercambio y usuario que lo procesó
     //
     $DteIntercambio->estado = (int) $_POST['EstadoRecepEnv'];
     $DteIntercambio->recepcion_xml = base64_encode($RecepcionDTE_xml);
     if (isset($EnvioRecibos_xml)) {
         $DteIntercambio->recibos_xml = base64_encode($EnvioRecibos_xml);
     }
     $DteIntercambio->resultado_xml = base64_encode($ResultadoDTE_xml);
     $DteIntercambio->fecha_hora_respuesta = date('Y-m-d H:i:s');
     $DteIntercambio->usuario = $this->Auth->User->id;
     $DteIntercambio->save();
     //
     // guardar documentos que han sido aceptados con acuse de recibo
     //
     if (isset($EnvioRecibos_xml)) {
         // actualizar datos del emisor si no tine usuario asociado
         $EmisorIntercambio = $DteIntercambio->getEmisor();
         if (!$EmisorIntercambio->usuario) {
             $emisor = $DteIntercambio->getDocumentos()[0]->getDatos()['Encabezado']['Emisor'];
             $EmisorIntercambio->razon_social = $emisor['RznSoc'];
             if (!empty($emisor['GiroEmis'])) {
                 $EmisorIntercambio->giro = $emisor['GiroEmis'];
             }
             if (!empty($emisor['CorreoEmisor'])) {
                 $EmisorIntercambio->email = $emisor['CorreoEmisor'];
             }
             if (!empty($emisor['Acteco'])) {
                 $actividad_economica = $EmisorIntercambio->actividad_economica;
                 $EmisorIntercambio->actividad_economica = $emisor['Acteco'];
                 if (!$EmisorIntercambio->getActividadEconomica()->exists()) {
                     $EmisorIntercambio->actividad_economica = $actividad_economica;
                 }
             }
             $comuna = (new \sowerphp\app\Sistema\General\DivisionGeopolitica\Model_Comunas())->getComunaByName($emisor['CmnaOrigen']);
             if ($comuna) {
                 $EmisorIntercambio->direccion = $emisor['DirOrigen'];
                 $EmisorIntercambio->comuna = $comuna;
             }
             if (!empty($emisor['CdgSIISucur'])) {
                 $EmisorIntercambio->sucursal_sii = (int) $emisor['CdgSIISucur'];
             }
             $EmisorIntercambio->modificado = date('Y-m-d H:i:s');
             $EmisorIntercambio->save();
         }
         // guardar documentos que tienen acuse de recibo como dte recibidos
         $Documentos = $DteIntercambio->getDocumentos();
         foreach ($Documentos as $Dte) {
             if (in_array($Dte->getID(), $EnvioRecibos_r)) {
                 $resumen = $Dte->getResumen();
                 $DteRecibido = new Model_DteRecibido();
                 $DteRecibido->emisor = $DteIntercambio->getEmisor()->rut;
                 $DteRecibido->dte = $resumen['TpoDoc'];
                 $DteRecibido->folio = $resumen['NroDoc'];
                 $DteRecibido->certificacion = (int) $DteIntercambio->certificacion;
                 if (!$DteRecibido->exists()) {
                     $DteRecibido->receptor = $Emisor->rut;
                     $DteRecibido->tasa = (int) $resumen['TasaImp'];
                     $DteRecibido->fecha = $resumen['FchDoc'];
                     $DteRecibido->sucursal_sii = (int) $resumen['CdgSIISucur'];
                     if ($resumen['MntExe']) {
                         $DteRecibido->exento = $resumen['MntExe'];
                     }
                     if ($resumen['MntNeto']) {
                         $DteRecibido->neto = $resumen['MntNeto'];
                     }
                     $DteRecibido->iva = (int) $resumen['MntIVA'];
                     $DteRecibido->total = (int) $resumen['MntTotal'];
                     $DteRecibido->usuario = $this->Auth->User->id;
                     $DteRecibido->intercambio = $DteIntercambio->codigo;
                     $DteRecibido->save();
                 }
             }
         }
     }
     //
     // enviar los 3 XML de respuesta por email
     //
     $email = $Emisor->getEmailSmtp();
     $email->to($_POST['responder_a']);
     $email->subject($Emisor->rut . '-' . $Emisor->dv . ' - Respuesta intercambio N° ' . $DteIntercambio->codigo);
     foreach (['RecepcionDTE', 'EnvioRecibos', 'ResultadoDTE'] as $xml) {
         if (isset(${$xml . '_xml'})) {
             $email->attach(['data' => ${$xml . '_xml'}, 'name' => $xml . '_' . $Emisor->rut . '-' . $Emisor->dv . '_' . $DteIntercambio->codigo . '.xml', 'type' => 'application/xml']);
         }
     }
     // enviar email
     $status = $email->send('Se adjuntan XMLs de respuesta a intercambio de DTE.');
     if ($status === true) {
         \sowerphp\core\Model_Datasource_Session::message('Se procesaron DTEs de intercambio y se envió la respuesta a: ' . $_POST['responder_a'], 'ok');
     } else {
         \sowerphp\core\Model_Datasource_Session::message('Se procesaron DTEs de intercambio, pero no fue posible enviar el email, por favor intente nuevamente.<br /><em>' . $status['message'] . '</em>', 'error');
     }
     $this->redirect(str_replace('responder', 'ver', $this->request->request));
 }