/**
  * Acción que permite mostrar los documentos recibidos por el contribuyente
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2016-01-04
  */
 public function listar($pagina = 1)
 {
     if (!is_numeric($pagina)) {
         $this->redirect('/dte/' . $this->request->params['controller'] . '/listar');
     }
     $Emisor = $this->getContribuyente();
     $filtros = [];
     if (isset($_GET['search'])) {
         foreach (explode(',', $_GET['search']) as $filtro) {
             list($var, $val) = explode(':', $filtro);
             $filtros[$var] = $val;
         }
     }
     $searchUrl = isset($_GET['search']) ? '?search=' . $_GET['search'] : '';
     try {
         $documentos_total = $Emisor->countDocumentosRecibidos($filtros);
         $documentos = $Emisor->getDocumentosRecibidos($filtros);
     } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
         \sowerphp\core\Model_Datasource_Session::message('Error al recuperar los documentos:<br/>' . $e->getMessage(), 'error');
         $documentos_total = 0;
         $documentos = [];
     }
     if (!empty($pagina)) {
         $filtros['limit'] = \sowerphp\core\Configure::read('app.registers_per_page');
         $filtros['offset'] = ($pagina - 1) * $filtros['limit'];
         $paginas = ceil($documentos_total / $filtros['limit']);
         if ($pagina != 1 && $pagina > $paginas) {
             $this->redirect('/dte/' . $this->request->params['controller'] . '/listar' . $searchUrl);
         }
     } else {
         $paginas = 1;
     }
     $this->set(['Emisor' => $Emisor, 'documentos' => $documentos, 'documentos_total' => $documentos_total, 'paginas' => $paginas, 'pagina' => $pagina, 'search' => $filtros, 'tipos_dte' => (new \website\Dte\Admin\Model_DteTipos())->getList(true), 'usuarios' => $Emisor->getListUsuarios(), 'searchUrl' => $searchUrl]);
 }
 /**
  * Constructor para la clase: crea configuración y carga certificado digital
  *
  * Si se desea pasar una configuración específica para la firma electrónica
  * se debe hacer a través de un arreglo con los índices file y pass, donde
  * file es la ruta hacia el archivo .p12 que contiene tanto la clave privada
  * como la pública y pass es la contraseña para abrir dicho archivo.
  * Ejemplo:
  *
  * \code{.php}
  *   $firma_config = ['file'=>'/ruta/al/certificado.p12', 'pass'=>'contraseña'];
  *   $firma = new \sasco\LibreDTE\FirmaElectronica($firma_config);
  * \endcode
  *
  * También se permite que en vez de pasar la ruta al certificado p12 se pase
  * el contenido del certificado, esto servirá por ejemplo si los datos del
  * archivo están almacenados en una base de datos. Ejemplo:
  *
  * \code{.php}
  *   $firma_config = ['data'=>file_get_contents('/ruta/al/certificado.p12'), 'pass'=>'contraseña'];
  *   $firma = new \sasco\LibreDTE\FirmaElectronica($firma_config);
  * \endcode
  *
  * @param config Configuración para la clase, si no se especifica se tratará de determinar
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-15
  */
 public function __construct(array $config = [])
 {
     // crear configuración
     if (!$config) {
         if (class_exists('\\sowerphp\\core\\Configure')) {
             $config = (array) \sowerphp\core\Configure::read('firma_electronica.default');
         } else {
             $config = [];
         }
     }
     $this->config = array_merge(['file' => null, 'pass' => null, 'data' => null, 'wordwrap' => 64], $config);
     // cargar firma electrónica desde el contenido del archivo .p12 si no
     // se pasaron como datos del arreglo de configuración
     if (!$this->config['data'] and $this->config['file']) {
         if (is_readable($this->config['file'])) {
             $this->config['data'] = file_get_contents($this->config['file']);
         } else {
             return $this->error('Archivo de la firma electrónica ' . basename($this->config['file']) . ' no puede ser leído');
         }
     }
     // leer datos de la firma electrónica
     if ($this->config['data'] and openssl_pkcs12_read($this->config['data'], $this->certs, $this->config['pass']) === false) {
         return $this->error('No fue posible leer los datos de la firma electrónica (verificar la contraseña)');
     }
     $this->data = openssl_x509_parse($this->certs['cert']);
     // quitar datos del contenido del archivo de la firma
     unset($this->config['data']);
 }
Example #3
0
 /**
  * Constructor de la clase
  * @param config Configuración del correo electrónico que se usará
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
  * @version 2016-04-20
  */
 public function __construct($config = 'default')
 {
     // Si es un arreglo, se asume es la configuración directamente
     if (is_array($config)) {
         $this->_config = $config;
     } else {
         $this->_config = \SowerPHP\core\Configure::read('email.' . $config);
     }
     // se ponen valores por defecto
     $this->_config = array_merge(['type' => 'smtp', 'host' => 'localhost', 'port' => 25], $this->_config);
     // extraer puerto si se pasó en el host
     $url = parse_url($this->_config['host']);
     if (isset($url['port'])) {
         $this->_config['host'] = str_replace(':' . $url['port'], '', $this->_config['host']);
         $this->_config['port'] = $url['port'];
     }
     // si no están los campos mínimos necesarios error
     if (empty($this->_config['type']) || empty($this->_config['host']) || empty($this->_config['port']) || empty($this->_config['user']) || empty($this->_config['pass'])) {
         throw new Exception('Configuración del correo electrónico incompleta');
     }
     // determinar from
     if (isset($this->_config['from'])) {
         if (is_array($this->_config['from'])) {
             $this->_config['from'] = $this->_config['from']['name'] . ' <' . $this->_config['from']['email'] . '>';
         } else {
             $this->_config['from'] = $this->_config['from'];
         }
     } else {
         $this->_config['from'] = $this->_config['user'];
     }
 }
Example #4
0
 /**
  * Método que desencripta un texto encriptado
  * @param $ciphertext_base64 Texto encriptado en base64 a desencriptar
  * @param key Índice en la configuración para obtener la clave a usar
  * @return Texto plano
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2016-01-02
  */
 public static function decrypt($ciphertext_base64, $key = 'dte.pkey')
 {
     if (empty($ciphertext_base64)) {
         return $ciphertext_base64;
     }
     $ciphertext_dec = base64_decode($ciphertext_base64);
     $key = \sowerphp\core\Configure::read($key);
     if (!$key) {
         return $ciphertext_dec;
     }
     $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
     $iv_dec = substr($ciphertext_dec, 0, $iv_size);
     $ciphertext_dec = substr($ciphertext_dec, $iv_size);
     $plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);
     return $plaintext_dec;
 }
Example #5
0
 /**
  * Constructor para la clase: crea configuración y carga certificado digital
  *
  * Si se desea pasar una configuración específica para la firma electrónica
  * se debe hacer a través de un arreglo con los índices file y pass, donde
  * file es la ruta hacia el archivo .p12 que contiene tanto la clave privada
  * como la pública y pass es la contraseña para abrir dicho archivo.
  * Ejemplo:
  *
  * \code{.php}
  *   $firma_config = ['file'=>'/ruta/al/certificado.p12', 'pass'=>'contraseña'];
  *   $firma = new \sasco\LibreDTE\FirmaElectronica($firma_config);
  * \endcode
  *
  * @param config Configuración para la cllase, si no se especifica se trarará de determinar
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2014-12-08
  */
 public function __construct($config = [])
 {
     // crear configuración
     if (!$config and class_exists('\\sowerphp\\core\\Configure')) {
         $config = (array) \sowerphp\core\Configure::read('firma_electronica.default');
     }
     $this->config = array_merge(['file' => (defined('DIR_PROJECT') ? DIR_PROJECT . '/data/firma_electronica/' : '') . 'default.p12', 'pass' => '', 'wordwrap' => 64], $config);
     // cargar certificado digital
     if (file_exists($this->config['file'])) {
         $pkcs12 = file_get_contents($this->config['file']);
         if (openssl_pkcs12_read($pkcs12, $this->certs, $this->config['pass']) === false) {
             $this->error('Contraseña incorrecta para la firma electrónica ' . basename($this->config['file']));
         }
     } else {
         $this->error('Archivo de la firma electrónica ' . basename($this->config['file']) . ' no existe');
     }
 }
Example #6
0
 /**
  * Método que guarda en memoria un valor a ser cacheado
  * @param host Hostname del servidor que corre Memcached
  * @param port Puerto donde Memcached está escuchando
  * @param prefix Prefijo que se utilizará en las claves de los elementos del caché
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
  * @version 2016-04-13
  */
 public function __construct($host = null, $port = null, $prefix = false)
 {
     if (class_exists('\\Memcached')) {
         // definir host y puerto
         if (!$host or !$port) {
             $cache = \sowerphp\core\Configure::read('cache.default');
             if (!$host) {
                 $host = isset($cache['host']) ? $cache['host'] : '127.0.0.1';
             }
             if (!$port) {
                 $port = isset($cache['port']) ? $cache['port'] : 11211;
             }
         }
         // conectar a Memcached
         $this->_cache = new \Memcached();
         $this->_cache->addServer($host, $port);
         $this->_prefix = $prefix ? $prefix : defined('DIR_PROJECT') ? DIR_PROJECT . ':' : '';
     }
 }
 /**
  * Método que genera la previsualización del PDF del DTE
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
  * @version 2015-09-24
  */
 public function pdf($receptor, $dte, $codigo)
 {
     $Emisor = $this->getContribuyente();
     // obtener datos JSON del DTE
     $DteTmp = new Model_DteTmp($Emisor->rut, $receptor, $dte, $codigo);
     if (!$DteTmp->exists()) {
         \sowerphp\core\Model_Datasource_Session::message('No existe el DTE temporal solicitado', 'error');
         $this->redirect('/dte/dte_tmps');
     }
     // armar xml a partir de datos del dte temporal
     $xml = $DteTmp->getEnvioDte()->generar();
     if (!$xml) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible crear el PDF para previsualización:<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
         $this->redirect('/dte/dte_tmps');
     }
     // armar datos con archivo XML y flag para indicar si es cedible o no
     $data = ['xml' => base64_encode($xml), 'cedible' => false, 'compress' => false];
     // si hay un logo para la empresa se usa
     $logo = \sowerphp\core\Configure::read('dte.logos.dir') . '/' . $Emisor->rut . '.png';
     if (is_readable($logo)) {
         $data['logo'] = base64_encode(file_get_contents($logo));
     }
     // realizar consulta a la API
     $rest = new \sowerphp\core\Network_Http_Rest();
     $rest->setAuth($this->Auth->User ? $this->Auth->User->hash : $this->token);
     $response = $rest->post($this->request->url . '/api/dte/documentos/generar_pdf', $data);
     if ($response['status']['code'] != 200) {
         \sowerphp\core\Model_Datasource_Session::message($response['body'], 'error');
         return;
     }
     // si dió código 200 se entrega la respuesta del servicio web
     foreach (['Content-Disposition', 'Content-Length', 'Content-Type'] as $header) {
         if (isset($response['header'][$header])) {
             header($header . ': ' . $response['header'][$header]);
         }
     }
     echo $response['body'];
     exit;
 }
Example #8
0
define('DIR_WEBSITE', DIR_PROJECT . '/website');
// Iniciar buffer
ob_start();
// Incluir archivo de funciones básicas y clase para autoload
include DIR_FRAMEWORK . '/lib/sowerphp/core/basics.php';
include DIR_FRAMEWORK . '/lib/sowerphp/core/App.php';
// Asociar el método que cargará las clases
spl_autoload_register('\\sowerphp\\core\\App::loadClass');
// Crear capas de la aplicación (se registrarán extensiones)
\sowerphp\core\App::createLayers($_EXTENSIONS);
unset($_EXTENSIONS);
// Definir si la aplicación se ejecuta en ambiente de desarrollo
// Si estamos en Apache se debe definir en /etc/httpd/conf/httpd.conf:
//   SetEnv APPLICATION_ENV "dev".
// Si estamos en una terminal se debe pasar el flas: --dev
global $argv;
if (isset($_SERVER['APPLICATION_ENV']) and $_SERVER['APPLICATION_ENV'] == 'dev') {
    define('ENVIRONMENT_DEV', true);
} else {
    if (is_array($argv) and in_array('--dev', $argv)) {
        define('ENVIRONMENT_DEV', true);
        // se quita flasg --dev de los argumentos
        unset($argv[array_search('--dev', $argv)]);
    }
}
// Iniciar sesión y configurar el sitio
\sowerphp\core\Configure::bootstrap();
\sowerphp\core\Model_Datasource_Session::start(\sowerphp\core\Configure::read('session.expires'));
\sowerphp\core\Model_Datasource_Session::configure();
// autocarga de composer
require 'Vendor/autoload.php';
 /**
  * Acción que permite la generación del PDF con los DTEs contenidos en un
  * XML de EnvioDTE
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-12-12
  */
 public function generar_pdf()
 {
     if (isset($_POST['submit'])) {
         // si hubo problemas al subir el archivo error
         if (!isset($_FILES['xml']) or $_FILES['xml']['error']) {
             \sowerphp\core\Model_Datasource_Session::message('Hubo algún problema al recibir el archivo XML con el EnvioDTE', 'error');
             return;
         }
         // armar datos con archivo XML y flag para indicar si es cedible o no
         $data = ['xml' => base64_encode(file_get_contents($_FILES['xml']['tmp_name'])), 'cedible' => isset($_POST['cedible']), 'papelContinuo' => $_POST['papelContinuo'], 'webVerificacion' => $_POST['webVerificacion']];
         // si se pasó un logo se agrega el archivo a los datos que se enviarán
         if (isset($_FILES['logo']) and !$_FILES['logo']['error']) {
             $data['logo'] = base64_encode(file_get_contents($_FILES['logo']['tmp_name']));
         }
         // realizar consulta a la API
         $rest = new \sowerphp\core\Network_Http_Rest();
         $rest->setAuth($this->Auth->User ? $this->Auth->User->hash : \sowerphp\core\Configure::read('api.default.token'));
         $response = $rest->post($this->request->url . '/api/dte/documentos/generar_pdf', $data);
         if ($response['status']['code'] != 200) {
             \sowerphp\core\Model_Datasource_Session::message($response['body'], 'error');
             return;
         }
         // si dió código 200 se entrega la respuesta del servicio web
         foreach (['Content-Disposition', 'Content-Length', 'Content-Type'] as $header) {
             if (isset($response['header'][$header])) {
                 header($header . ': ' . $response['header'][$header]);
             }
         }
         echo $response['body'];
         exit;
     }
 }
 /**
  * Acción que envía por email el PDF y el XML del DTE
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-12-12
  */
 public function enviar_email($dte, $folio)
 {
     $Emisor = $this->getContribuyente();
     // obtener DTE emitido
     $DteEmitido = new Model_DteEmitido($Emisor->rut, $dte, $folio, (int) $Emisor->certificacion);
     if (!$DteEmitido->exists()) {
         \sowerphp\core\Model_Datasource_Session::message('No existe el DTE solicitado', 'error');
         $this->redirect('/dte/dte_emitidos/listar');
     }
     // se verifican datos mínimos
     foreach (['emails', 'asunto', 'mensaje'] as $attr) {
         if (empty($_POST[$attr])) {
             \sowerphp\core\Model_Datasource_Session::message('Debe especificar el campo: ' . $attr, 'error');
             $this->redirect(str_replace('enviar_email', 'ver', $this->request->request) . '#email');
         }
     }
     // crear email
     $email = $Emisor->getEmailSmtp();
     $email->to($_POST['emails']);
     $email->subject($_POST['asunto']);
     // adjuntar PDF
     $data = ['xml' => $DteEmitido->xml, 'cedible' => isset($_POST['cedible']), 'compress' => false];
     $logo = \sowerphp\core\Configure::read('dte.logos.dir') . '/' . $Emisor->rut . '.png';
     if (is_readable($logo)) {
         $data['logo'] = base64_encode(file_get_contents($logo));
     }
     $rest = new \sowerphp\core\Network_Http_Rest();
     $rest->setAuth($this->Auth->User->hash);
     $response = $rest->post($this->request->url . '/api/dte/documentos/generar_pdf', $data);
     if ($response['status']['code'] != 200) {
         \sowerphp\core\Model_Datasource_Session::message($response['body'], 'error');
         $this->redirect(str_replace('enviar_email', 'ver', $this->request->request) . '#email');
     }
     $email->attach(['data' => $response['body'], 'name' => 'dte_' . $Emisor->rut . '-' . $Emisor->dv . '_T' . $DteEmitido->dte . 'F' . $DteEmitido->folio . '.pdf', 'type' => 'application/pdf']);
     // adjuntar XML
     $email->attach(['data' => base64_decode($DteEmitido->xml), 'name' => 'dte_' . $Emisor->rut . '-' . $Emisor->dv . '_T' . $DteEmitido->dte . 'F' . $DteEmitido->folio . '.xml', 'type' => 'application/xml']);
     // enviar email
     $status = $email->send($_POST['mensaje']);
     if ($status === true) {
         \sowerphp\core\Model_Datasource_Session::message('Se envió el DTE a: ' . implode(', ', $_POST['emails']), 'ok');
         $this->redirect(str_replace('enviar_email', 'ver', $this->request->request));
     } else {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible enviar el email, por favor intente nuevamente.<br /><em>' . $status['message'] . '</em>', 'error');
         $this->redirect(str_replace('enviar_email', 'ver', $this->request->request) . '#email');
     }
 }
 /**
  * Acción que entrega el logo del contribuyente
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-29
  */
 public function logo($rut)
 {
     $Contribuyente = new Model_Contribuyente(substr($rut, 0, -4));
     if (!$Contribuyente->exists()) {
         \sowerphp\core\Model_Datasource_Session::message('Contribuyente solicitado no existe');
         $this->redirect('/');
     }
     $dir = \sowerphp\core\Configure::read('dte.logos.dir');
     $logo = $dir . '/' . $Contribuyente->rut . '.png';
     if (!is_readable($logo)) {
         $logo = $dir . '/default.png';
     }
     header('Content-Type: image/png');
     header('Content-Length: ' . filesize($logo));
     header('Content-Disposition: inline; filename="' . $Contribuyente->rut . '.png"');
     print file_get_contents($logo);
     exit;
 }
Example #12
0
 /**
  * Comando que procesa el envío del timbre como fotografía
  * @param photo ID de la fotografía que envió el usuario
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
  * @version 2015-10-13
  */
 protected function _bot_photo($file_id)
 {
     $this->Bot->sendChatAction();
     $n_sizes = count($this->Bot->getMessage()->photo);
     $file_id = $this->Bot->getMessage()->photo[$n_sizes - 1]->file_id;
     $file = $this->Bot->downloadFile($file_id);
     if (!$file) {
         $this->Bot->send('No fue posible recuperar el archivo que envíaste');
         return;
     }
     $rest = new \sowerphp\core\Network_Http_Rest();
     $rest->setAuth(\sowerphp\core\Configure::read('api.default.token'));
     $response = $rest->post($this->request->url . '/api/dte/documentos/get_ted', base64_encode($file['data']));
     if ($response['status']['code'] != 200) {
         $this->Bot->send($response['body']);
         return;
     }
     $this->_bot_timbre(base64_decode($response['body']));
 }
 /**
  * Acción para mostrar el PDF de un EnvioDTE de un intercambio de DTE
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-27
  */
 public function pdf($codigo, $cedible = false)
 {
     $Emisor = $this->getContribuyente();
     // obtener DTE intercambiado
     $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');
     }
     // armar datos con archivo XML y flag para indicar si es cedible o no
     $data = ['xml' => $DteIntercambio->archivo_xml, 'cedible' => $cedible, 'compress' => $DteIntercambio->documentos == 1 ? false : true];
     // si hay un logo para la empresa se usa
     $logo = \sowerphp\core\Configure::read('dte.logos.dir') . '/' . $DteIntercambio->emisor . '.png';
     if (is_readable($logo)) {
         $data['logo'] = base64_encode(file_get_contents($logo));
     }
     // realizar consulta a la API
     $rest = new \sowerphp\core\Network_Http_Rest();
     $rest->setAuth($this->Auth->User ? $this->Auth->User->hash : $this->token);
     $response = $rest->post($this->request->url . '/api/dte/documentos/generar_pdf', $data);
     if ($response['status']['code'] != 200) {
         \sowerphp\core\Model_Datasource_Session::message($response['body'], 'error');
         return;
     }
     // si dió código 200 se entrega la respuesta del servicio web
     foreach (['Content-Disposition', 'Content-Length', 'Content-Type'] as $header) {
         if (isset($response['header'][$header])) {
             header($header . ': ' . $response['header'][$header]);
         }
     }
     echo $response['body'];
     exit;
 }