/**
  * Acción que permite subir un caf para un tipo de folio
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-22
  */
 public function subir_caf()
 {
     $Emisor = $this->getContribuyente();
     $this->set(['Emisor' => $Emisor]);
     // procesar solo si se envió el formulario
     if (isset($_POST['submit'])) {
         // verificar que se haya podido subir CAF
         if (!isset($_FILES['caf']) or $_FILES['caf']['error']) {
             \sowerphp\core\Model_Datasource_Session::message('Ocurrió un error al subir el CAF', 'error');
             return;
         }
         if (\sowerphp\general\Utility_File::mimetype($_FILES['caf']['tmp_name']) != 'application/xml') {
             \sowerphp\core\Model_Datasource_Session::message('Formato del archivo ' . $_FILES['caf']['name'] . ' es incorrecto', 'error');
             return;
         }
         // cargar caf
         $caf = file_get_contents($_FILES['caf']['tmp_name']);
         $Folios = new \sasco\LibreDTE\Sii\Folios($caf);
         // si no se pudo validar el caf error
         if (!$Folios->getTipo()) {
             \sowerphp\core\Model_Datasource_Session::message('No fue posible cargar el CAF ' . $_FILES['caf']['name'] . ':<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
             return;
         }
         // verificar que el caf tenga previamente cargado un mantenedor de folio
         $DteFolio = new Model_DteFolio($Emisor->rut, $Folios->getTipo(), (int) $Folios->getCertificacion());
         if (!$DteFolio->exists()) {
             \sowerphp\core\Model_Datasource_Session::message('Primero debe crear el mantenedor de los folios de tipo ' . $Folios->getTipo(), 'error');
             return;
         }
         // verificar que el caf sea del emisor
         if ($Folios->getEmisor() != $Emisor->rut . '-' . $Emisor->dv) {
             \sowerphp\core\Model_Datasource_Session::message('RUT del CAF ' . $Folios->getEmisor() . ' no corresponde con el RUT de la empresa ' . $Emisor->razon_social . ' ' . $Emisor->rut . '-' . $Emisor->dv, 'error');
             return;
         }
         // verificar que el folio que se está subiendo sea para el ambiente actual de la empresa
         $ambiente_empresa = $Emisor->certificacion ? 'certificación' : 'producción';
         $ambiente_caf = $Folios->getCertificacion() ? 'certificación' : 'producción';
         if ($ambiente_empresa != $ambiente_caf) {
             \sowerphp\core\Model_Datasource_Session::message('Empresa está en ambiente de ' . $ambiente_empresa . ' pero folios son de ' . $ambiente_caf, 'error');
             return;
         }
         // crear caf para el folio
         $DteCaf = new Model_DteCaf($DteFolio->emisor, $DteFolio->dte, (int) $Folios->getCertificacion(), $Folios->getDesde());
         if ($DteCaf->exists()) {
             \sowerphp\core\Model_Datasource_Session::message('El CAF para el documento de tipo ' . $DteCaf->dte . ' que inicia en ' . $Folios->getDesde() . ' en ambiente de ' . $ambiente_caf . ' ya estaba cargado', 'warning');
             return;
         }
         $DteCaf->hasta = $Folios->getHasta();
         $DteCaf->xml = \website\Dte\Utility_Data::encrypt($caf);
         try {
             $DteCaf->save();
         } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
             \sowerphp\core\Model_Datasource_Session::message('No fue posible guardar el CAF: ' . $e->getMessage(), 'error');
             return;
         }
         // actualizar mantenedor de folios
         if (!$DteFolio->disponibles) {
             $DteFolio->siguiente = $Folios->getDesde();
             $DteFolio->disponibles = $Folios->getHasta() - $Folios->getDesde() + 1;
         } else {
             $DteFolio->disponibles += $Folios->getHasta() - $Folios->getDesde() + 1;
         }
         $DteFolio->alertado = 'f';
         try {
             $DteFolio->save();
             \sowerphp\core\Model_Datasource_Session::message('El CAF para el documento de tipo ' . $DteCaf->dte . ' que inicia en ' . $Folios->getDesde() . ' en ambiente de ' . $ambiente_caf . ' fue cargado, el siguiente folio disponible es ' . $DteFolio->siguiente, 'ok');
             $this->redirect('/dte/admin/dte_folios');
         } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
             \sowerphp\core\Model_Datasource_Session::message('El CAF se guardó, pero no fue posible actualizar el mantenedor de folios, deberá actualizar manualmente. ' . $e->getMessage(), 'error');
             return;
         }
     }
 }
 /**
  * Método que permite modificar contribuyente previamente registrado
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-29
  */
 public function modificar($rut)
 {
     // crear objeto del contribuyente
     try {
         $Contribuyente = new Model_Contribuyente($rut);
     } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
         \sowerphp\core\Model_Datasource_Session::message('No se encontró la empresa solicitada', 'error');
         $this->redirect('/dte/contribuyentes/seleccionar');
     }
     // verificar que el usuario sea el administrador
     if ($Contribuyente->usuario != $this->Auth->User->id) {
         \sowerphp\core\Model_Datasource_Session::message('Usted no es el administrador de la empresa solicitada', 'error');
         $this->redirect('/dte/contribuyentes/seleccionar');
     }
     // asignar variables para editar
     $this->set(['Contribuyente' => $Contribuyente, 'actividades_economicas' => (new \website\Sistema\General\Model_ActividadEconomicas())->getList(), 'comunas' => (new \sowerphp\app\Sistema\General\DivisionGeopolitica\Model_Comunas())->getList()]);
     // editar
     if (isset($_POST['submit'])) {
         // verificar campos mínimos
         foreach (['razon_social', 'giro', 'actividad_economica', 'direccion', 'comuna', 'certificacion_resolucion'] as $attr) {
             if (empty($_POST[$attr])) {
                 \sowerphp\core\Model_Datasource_Session::message('Debe especificar: ' . $attr, 'error');
                 return;
             }
         }
         // rellenar campos de la empresa
         foreach (array_keys(Model_Contribuyente::$columnsInfo) as $attr) {
             if (!empty($_POST[$attr])) {
                 $Contribuyente->{$attr} = $_POST[$attr];
             }
         }
         $Contribuyente->certificacion = (int) isset($_POST['certificacion']);
         if (!empty($_POST['sii_pass'])) {
             $Contribuyente->sii_pass = Utility_Data::encrypt($_POST['sii_pass']);
         }
         if (!empty($_POST['intercambio_pass'])) {
             $Contribuyente->intercambio_pass = Utility_Data::encrypt($_POST['intercambio_pass']);
         }
         $Contribuyente->usuario = $this->Auth->User->id;
         $Contribuyente->modificado = date('Y-m-d H:i:s');
         $Contribuyente->api_token = !empty($_POST['api_token']) ? Utility_Data::encrypt($_POST['api_token']) : null;
         // si está en producción validar fecha y número de resolución
         if (!$Contribuyente->certificacion and (empty($Contribuyente->resolucion_fecha) or empty($Contribuyente->resolucion_numero))) {
             \sowerphp\core\Model_Datasource_Session::message('Para pasar la empresa a producción debe indicar la fecha y número de resolución que la autoriza', 'error');
             return;
         }
         // si se pasó un logo se guarda
         if (isset($_FILES['logo']) and !$_FILES['logo']['error']) {
             // si el formano no es PNG error
             if (\sowerphp\general\Utility_File::mimetype($_FILES['logo']['tmp_name']) != 'image/png') {
                 \sowerphp\core\Model_Datasource_Session::message('Formato del logo debe ser PNG', 'error');
                 return;
             }
             $config = \sowerphp\core\Configure::read('dte.logos');
             // redimensionar imagen
             \sowerphp\general\Utility_Image::resizeOnFile($_FILES['logo']['tmp_name'], $config['width'], $config['height']);
             // copiar imagen a directorio final
             move_uploaded_file($_FILES['logo']['tmp_name'], $config['dir'] . '/' . $Contribuyente->rut . '.png');
         }
         // guardar contribuyente
         try {
             $Contribuyente->save();
             \sowerphp\core\Model_Datasource_Session::message('Empresa ' . $Contribuyente->razon_social . ' ha sido modificada', 'ok');
             $this->redirect('/dte/contribuyentes/seleccionar');
         } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
             \sowerphp\core\Model_Datasource_Session::message('No fue posible modificar la empresa:<br/>' . $e->getMessage(), 'error');
         }
     }
 }
 /**
  * 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]);
     }
 }
 /**
  * Acción que entrega los XML del resultado de la revisión del intercambio
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-28
  */
 public function resultados_xml($codigo)
 {
     $Emisor = $this->getContribuyente();
     // 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');
     }
     // si no hay XML error
     if (!$DteIntercambio->recepcion_xml and !$DteIntercambio->recibos_xml and !$DteIntercambio->resultado_xml) {
         \sowerphp\core\Model_Datasource_Session::message('No existen archivos de resultado generados, no se ha procesado aun el intercambio', 'error');
         $this->redirect(str_replace('resultados_xml', 'ver', $this->request->request));
     }
     // agregar a archivo comprimido y entregar
     $dir = TMP . '/resultado_intercambio_' . $Emisor->rut . '-' . $Emisor->dv . '_' . $DteIntercambio->codigo;
     if (is_dir($dir)) {
         \sowerphp\general\Utility_File::rmdir($dir);
     }
     if (!mkdir($dir)) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible crear el directorio temporal para los XML', 'error');
         $this->redirect(str_replace('resultados_xml', 'ver', $this->request->request));
     }
     if ($DteIntercambio->recepcion_xml) {
         file_put_contents($dir . '/RecepcionDTE.xml', base64_decode($DteIntercambio->recepcion_xml));
     }
     if ($DteIntercambio->recibos_xml) {
         file_put_contents($dir . '/EnvioRecibos.xml', base64_decode($DteIntercambio->recibos_xml));
     }
     if ($DteIntercambio->resultado_xml) {
         file_put_contents($dir . '/ResultadoDTE.xml', base64_decode($DteIntercambio->resultado_xml));
     }
     \sowerphp\general\Utility_File::compress($dir, ['format' => 'zip', 'delete' => true]);
     exit;
 }