Esempio n. 1
0
 /**
  * Método que entrega el objeto del contribuyente que ha sido seleccionado
  * @return \website\Dte\Model_Contribuyente
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2016-01-02
  */
 protected function getContribuyente()
 {
     if (!isset($this->Contribuyente)) {
         $this->Contribuyente = \sowerphp\core\Model_Datasource_Session::read('dte.Contribuyente');
     }
     return $this->Contribuyente;
 }
 /**
  * Acción que descarga el XML de la recepción
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-12-23
  */
 public function xml($responde, $codigo)
 {
     $Emisor = $this->getContribuyente();
     // obtener Recepción
     $DteIntercambioRecepcion = new Model_DteIntercambioRecepcion($responde, $Emisor->rut, $codigo);
     if (!$DteIntercambioRecepcion->exists()) {
         \sowerphp\core\Model_Datasource_Session::message('No existe la recepción solicitada', 'error');
         $this->redirect('/dte/dte_intercambios');
     }
     // entregar XML
     $xml = base64_decode($DteIntercambioRecepcion->xml);
     header('Content-Type: application/xml; charset=ISO-8859-1');
     header('Content-Length: ' . strlen($xml));
     header('Content-Disposition: attachement; filename="' . $DteIntercambioRecepcion->responde . '_' . $DteIntercambioRecepcion->codigo . '.xml"');
     print $xml;
     exit;
 }
Esempio n. 3
0
 /**
  * Método que fuerza la selección de un contribuyente
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-12-12
  */
 public function beforeFilter()
 {
     parent::beforeFilter();
     // configuración previa para el módulo Dte y sus submódulos
     if (strpos($this->request->params['module'], 'Dte') === 0 and $this->request->params['controller'] != 'contribuyentes' and !$this->Auth->allowedWithoutLogin()) {
         // obtener emisor
         $Emisor = \sowerphp\core\Model_Datasource_Session::read('dte.Emisor');
         if (!$Emisor) {
             \sowerphp\core\Model_Datasource_Session::message('Antes de utilizar el módulo DTE debe seleccionar un contribuyente con el que operará', 'error');
             \sowerphp\core\Model_Datasource_Session::write('referer', $this->request->request);
             $this->redirect('/dte/contribuyentes/seleccionar');
         }
         // si no existe la definición de ambiente y es de certificación se asigna
         if (!defined('_LibreDTE_CERTIFICACION_') and $Emisor->certificacion) {
             define('_LibreDTE_CERTIFICACION_', true);
         }
     }
 }
 /**
  * Acción que muestra la página principal de estadísticas
  * @param certificacion =true se generan estadísticas para el ambiente de certificación
  * @param desde Desde cuando considerar la actividad de los contribuyentes
  * @param hasta Hasta cuando considerar la actividad de los contribuyentes
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2016-01-07
  */
 public function index($certificacion = false, $desde = 1, $hasta = 0)
 {
     $Contribuyentes = new \website\Dte\Model_Contribuyentes();
     $contribuyentes_sii = $Contribuyentes->count();
     $Contribuyentes->setWhereStatement(['usuario IS NOT NULL', 'certificacion = :certificacion'], [':certificacion' => (int) $certificacion]);
     $empresas_registradas = $Contribuyentes->count();
     $DteEmitidos = new \website\Dte\Model_DteEmitidos();
     $DteEmitidos->setWhereStatement(['certificacion = :certificacion'], [':certificacion' => (int) $certificacion]);
     $Usuarios = new \sowerphp\app\Sistema\Usuarios\Model_Usuarios();
     $Usuarios->setWhereStatement(['activo = true']);
     try {
         $contribuyentes_activos = $Contribuyentes->getConMovimientos($desde, $hasta, $certificacion, false);
     } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
         \sowerphp\core\Model_Datasource_Session::message($e->getMessage(), 'error');
         $contribuyentes_activos = [];
     }
     $this->set(['certificacion' => $certificacion, 'contribuyentes_sii' => $contribuyentes_sii, 'usuarios_registrados' => $Usuarios->count(), 'empresas_registradas' => $empresas_registradas, 'documentos_emitidos' => $DteEmitidos->count(), 'contribuyentes_activos' => $contribuyentes_activos]);
     $this->autoRender = false;
     $this->render('Estadisticas/index');
 }
 /**
  * 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]);
 }
Esempio n. 6
0
 /**
  * Método que permite generar un libro de Compras o Ventas a partir de un
  * archivo CSV con el detalle del mismo
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-10-05
  */
 public function generar_libro()
 {
     // si no se viene por post terminar
     if (!isset($_POST['submit'])) {
         return;
     }
     // verificar campos no estén vacíos
     $campos = ['TipoOperacion', 'RutEmisorLibro', 'PeriodoTributario', 'FchResol', 'NroResol', 'TipoLibro', 'TipoEnvio', 'FolioNotificacion', 'contrasenia'];
     foreach ($campos as $campo) {
         if (empty($_POST[$campo])) {
             \sowerphp\core\Model_Datasource_Session::message($campo . ' no puede estar en blanco', 'error');
             return;
         }
     }
     // si no se pasó el archivo error
     if (!isset($_FILES['archivo']) or $_FILES['archivo']['error']) {
         \sowerphp\core\Model_Datasource_Session::message('Debes enviar el archivo CSV con el detalle de las compras o ventas al que deseas generar su XML', 'error');
         return;
     }
     // si no se pasó la firma error
     if (!isset($_FILES['firma']) or $_FILES['firma']['error']) {
         \sowerphp\core\Model_Datasource_Session::message('Debes enviar el archivo con la firma digital', 'error');
         return;
     }
     // Objeto de la Firma
     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 caratula del libro
     $caratula = ['RutEmisorLibro' => str_replace('.', '', $_POST['RutEmisorLibro']), 'RutEnvia' => $Firma->getID(), 'PeriodoTributario' => $_POST['PeriodoTributario'], 'FchResol' => $_POST['FchResol'], 'NroResol' => $_POST['NroResol'], 'TipoOperacion' => $_POST['TipoOperacion'], 'TipoLibro' => $_POST['TipoLibro'], 'TipoEnvio' => $_POST['TipoEnvio'], 'FolioNotificacion' => $_POST['FolioNotificacion']];
     // definir si es certificacion
     $caratula_certificacion = ['COMPRA' => ['PeriodoTributario' => 2000, 'FchResol' => '2006-01-20', 'NroResol' => 102006, 'TipoLibro' => 'ESPECIAL', 'TipoEnvio' => 'TOTAL', 'FolioNotificacion' => 102006], 'VENTA' => ['PeriodoTributario' => 1980, 'FchResol' => '2006-01-20', 'NroResol' => 102006, 'TipoLibro' => 'ESPECIAL', 'TipoEnvio' => 'TOTAL', 'FolioNotificacion' => 102006]];
     $certificacion = true;
     foreach ($caratula_certificacion[$caratula['TipoOperacion']] as $attr => $val) {
         if ($caratula[$attr] != $val or $attr == 'PeriodoTributario' and substr($caratula[$attr], 0, 4) != $val) {
             $certificacion = false;
             break;
         }
     }
     // generar libro de compras o venta
     $LibroCompraVenta = new \sasco\LibreDTE\Sii\LibroCompraVenta();
     if ($caratula['TipoOperacion'] === 'COMPRA') {
         $LibroCompraVenta->agregarComprasCSV($_FILES['archivo']['tmp_name']);
     } else {
         $LibroCompraVenta->agregarVentasCSV($_FILES['archivo']['tmp_name']);
     }
     $LibroCompraVenta->setCaratula($caratula);
     if (!$certificacion) {
         $LibroCompraVenta->setFirma($Firma);
     }
     $xml = $LibroCompraVenta->generar($caratula['TipoOperacion'] == 'COMPRA');
     if (!$certificacion and !$LibroCompraVenta->schemaValidate()) {
         \sowerphp\core\Model_Datasource_Session::message(implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
         return;
     }
     // descargar XML
     $file = TMP . '/' . $LibroCompraVenta->getID() . '.xml';
     file_put_contents($file, $xml);
     \sasco\LibreDTE\File::compress($file, ['format' => 'zip', 'delete' => true]);
     exit;
 }
 /**
  * Acción que permite modificar un mantenedor de folios
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-29
  */
 public function modificar($dte)
 {
     $Emisor = $this->getContribuyente();
     $DteFolio = new Model_DteFolio($Emisor->rut, $dte, (int) $Emisor->certificacion);
     if (!$DteFolio->exists()) {
         \sowerphp\core\Model_Datasource_Session::message('No existe el mantenedor de folios solicitado', 'error');
         $this->redirect('/dte/admin/dte_folios');
     }
     $this->set(['Emisor' => $Emisor, 'DteFolio' => $DteFolio]);
     if (isset($_POST['submit'])) {
         // validar que campos existan y asignar
         foreach (['siguiente', 'alerta'] as $attr) {
             if (empty($_POST[$attr])) {
                 \sowerphp\core\Model_Datasource_Session::message('Debe especificar el campo: ' . $attr, 'error');
                 return;
             }
             $DteFolio->{$attr} = $_POST[$attr];
         }
         // guardar y redireccionar
         try {
             $DteFolio->calcularDisponibles();
             \sowerphp\core\Model_Datasource_Session::message('Mantenedor de folios para tipo ' . $DteFolio->dte . ' actualizado', 'ok');
             $this->redirect('/dte/admin/dte_folios');
         } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
             \sowerphp\core\Model_Datasource_Session::message('No fue posible actualizar el mantenedor de folios: ' . $e->getMessage(), 'error');
             return;
         }
     }
 }
 /**
  * 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');
     }
 }
Esempio n. 9
0
 /**
  * Acción que permite subir un XML con el resultado de la revisión
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-12-26
  */
 public function subir_revision($periodo)
 {
     $Emisor = $this->getContribuyente();
     // obtener libro envíado
     $class = __NAMESPACE__ . '\\Model_Dte' . $this->config['model']['singular'];
     $Libro = new $class($Emisor->rut, (int) $periodo, (int) $Emisor->certificacion);
     if (!$Libro->exists()) {
         \sowerphp\core\Model_Datasource_Session::message('Aun no se ha generado el libro del período ' . $periodo, 'error');
         $this->redirect(str_replace('subir_revision', 'ver', $this->request->request));
     }
     // si no tiene track id error
     if (!$Libro->track_id) {
         \sowerphp\core\Model_Datasource_Session::message('Libro del período ' . $periodo . ' no tiene Track ID, primero debe enviarlo al SII', 'error');
         $this->redirect(str_replace('subir_revision', 'ver', $this->request->request));
     }
     // si no se viene por post o el archivo no se subió o dió error
     if (!isset($_POST['submit']) or !isset($_FILES['xml']) or $_FILES['xml']['error']) {
         \sowerphp\core\Model_Datasource_Session::message('Debe subir archivo XML con la revisión', 'ok');
         $this->redirect(str_replace('subir_revision', 'ver', $this->request->request) . '#revision');
     }
     // guardar revisión
     $status = $Libro->saveRevision(file_get_contents($_FILES['xml']['tmp_name']));
     if ($status === true) {
         \sowerphp\core\Model_Datasource_Session::message('Se actualizó el estado del envío del libro', 'ok');
     } else {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible guardar el estado del libro en la base de datos<br/>' . $status, 'error');
     }
     $this->redirect(str_replace('subir_revision', 'ver', $this->request->request));
 }
 /**
  * Método que agrega o modifica un DTE recibido
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-28
  */
 private function save()
 {
     $Emisor = $this->getContribuyente();
     // revisar datos minimos
     foreach (['emisor', 'dte', 'folio', 'fecha', 'tasa'] as $attr) {
         if (!isset($_POST[$attr][0])) {
             \sowerphp\core\Model_Datasource_Session::message('Debe indicar ' . $attr, 'error');
             return;
         }
     }
     // crear dte recibido
     list($emisor, $dv) = explode('-', str_replace('.', '', $_POST['emisor']));
     $DteRecibido = new Model_DteRecibido($emisor, $_POST['dte'], (int) $_POST['folio'], (int) $Emisor->certificacion);
     $DteRecibido->receptor = $Emisor->rut;
     $DteRecibido->tasa = (int) $_POST['tasa'];
     $DteRecibido->fecha = $_POST['fecha'];
     $DteRecibido->exento = !empty($_POST['exento']) ? $_POST['exento'] : null;
     $DteRecibido->neto = !empty($_POST['neto']) ? $_POST['neto'] : null;
     $DteRecibido->iva = round((int) $DteRecibido->neto * ($DteRecibido->tasa / 100));
     $DteRecibido->total = (int) $DteRecibido->exento + (int) $DteRecibido->neto + $DteRecibido->iva;
     $DteRecibido->usuario = $this->Auth->User->id;
     // iva uso común, no recuperable e impuesto adicional
     $DteRecibido->iva_uso_comun = !empty($_POST['iva_uso_comun']) ? $_POST['iva_uso_comun'] : null;
     $DteRecibido->iva_no_recuperable = !empty($_POST['iva_no_recuperable']) ? $_POST['iva_no_recuperable'] : null;
     if (!empty($_POST['impuesto_adicional']) and !empty($_POST['impuesto_adicional_tasa'])) {
         $DteRecibido->impuesto_adicional = $_POST['impuesto_adicional'];
         $DteRecibido->impuesto_adicional_tasa = $_POST['impuesto_adicional_tasa'];
     } else {
         $DteRecibido->impuesto_adicional = null;
         $DteRecibido->impuesto_adicional_tasa = null;
     }
     $DteRecibido->impuesto_tipo = $_POST['impuesto_tipo'];
     $DteRecibido->anulado = isset($_POST['anulado']) ? 'A' : null;
     $DteRecibido->impuesto_sin_credito = !empty($_POST['impuesto_sin_credito']) ? $_POST['impuesto_sin_credito'] : null;
     $DteRecibido->monto_activo_fijo = !empty($_POST['monto_activo_fijo']) ? $_POST['monto_activo_fijo'] : null;
     $DteRecibido->monto_iva_activo_fijo = !empty($_POST['monto_iva_activo_fijo']) ? $_POST['monto_iva_activo_fijo'] : null;
     $DteRecibido->iva_no_retenido = !empty($_POST['iva_no_retenido']) ? $_POST['iva_no_retenido'] : null;
     // si el DTE es de producción y es electrónico entonces se consultará su
     // estado antes de poder guardar, esto evitará agregar documentos que no
     // han sido recibidos en el SII o sus datos son incorrectos
     if (!$Emisor->certificacion and $DteRecibido->getTipo()->electronico) {
         // 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');
         }
         // consultar estado dte
         $estado = $DteRecibido->getEstado($Firma);
         if ($estado === false) {
             \sowerphp\core\Model_Datasource_Session::message('No se pudo obtener el estado del DTE.<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
             return;
         } else {
             if (is_string($estado)) {
                 \sowerphp\core\Model_Datasource_Session::message('Estado DTE: ' . $estado, 'error');
                 return;
             }
         }
     }
     // todo ok con el dte así que se agrega a los dte recibidos
     try {
         $DteRecibido->save();
         \sowerphp\core\Model_Datasource_Session::message('DTE recibido guardado', 'ok');
         $this->redirect('/dte/dte_recibidos/listar');
     } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible guardar el DTE: ' . $e->getMessage(), 'error');
     }
 }
Esempio n. 11
0
 /**
  * Método que elimina un DTE temporal
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
  * @version 2015-09-23
  */
 public function eliminar($receptor, $dte, $codigo)
 {
     $Emisor = $this->getContribuyente();
     // obtener DTE temporal
     $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');
     }
     // eliminar
     try {
         $DteTmp->delete();
         \sowerphp\core\Model_Datasource_Session::message('DTE temporal eliminado', 'ok');
         $this->redirect('/dte/dte_tmps');
     } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible eliminar el DTE temporal: ' . $e->getMessage());
         $this->redirect('/dte/dte_tmps');
     }
 }
 /**
  * Método que genera la el XML del DTE temporal con Folio y Firma y lo envía
  * al SII
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
  * @version 2016-01-02
  */
 public function generar($receptor, $dte, $codigo)
 {
     $Emisor = $this->getContribuyente();
     // obtener DTE temporal
     $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/documentos/emitir');
     }
     // obtener firma electrónica
     $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');
     }
     // solicitar folio
     $FolioInfo = $Emisor->getFolio($DteTmp->dte);
     if (!$FolioInfo) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible obtener un folio para el DTE de tipo ' . $DteTmp->dte, 'error');
         $this->redirect('/dte/dte_tmps');
     }
     // si quedan pocos folios y se debe alertar al usuario admnistrador de la empresa se hace
     if ($FolioInfo->DteFolio->disponibles <= $FolioInfo->DteFolio->alerta and !$FolioInfo->DteFolio->alertado) {
         $msg = 'Se ha alcanzado el límite de folios del tipo de DTE ' . $FolioInfo->DteFolio->dte . ' para el contribuyente ' . $Emisor->razon_social . ', quedan ' . $FolioInfo->DteFolio->disponibles . '. Por favor, solicite un nuevo archivo CAF y súbalo en: ' . "\n\n" . $this->request->url . '/dte/admin/dte_folios';
         if ($this->Notify->send(null, $Emisor->getUsuario()->id, $msg, 'email')) {
             $FolioInfo->DteFolio->alertado = 1;
             $FolioInfo->DteFolio->save();
         }
     }
     // armar xml a partir de json del DTE temporal
     $EnvioDte = $DteTmp->getEnvioDte($FolioInfo->folio, $FolioInfo->Caf, $Firma);
     $xml = $EnvioDte->generar();
     if (!$xml) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible generar el XML del EnvioDTE. Folio ' . $FolioInfo->folio . ' quedará sin usar.<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
         $this->redirect('/dte/documentos/emitir');
     }
     // guardar DTE
     $r = $EnvioDte->getDocumentos()[0]->getResumen();
     $DteEmitido = new Model_DteEmitido($Emisor->rut, $r['TpoDoc'], $r['NroDoc'], (int) $Emisor->certificacion);
     if ($DteEmitido->exists()) {
         \sowerphp\core\Model_Datasource_Session::message('Ya existe un DTE del tipo ' . $r['TpoDoc'] . ' y folio ' . $r['NroDoc'] . ' emitido', 'error');
         $this->redirect('/dte/dte_emitidos/ver/' . $r['TpoDoc'] . '/' . $r['NroDoc'] . '/' . (int) $Emisor->certificacion);
     }
     $cols = ['tasa' => 'TasaImp', 'fecha' => 'FchDoc', 'sucursal_sii' => 'CdgSIISucur', 'receptor' => 'RUTDoc', 'exento' => 'MntExe', 'neto' => 'MntNeto', 'iva' => 'MntIVA', 'total' => 'MntTotal'];
     foreach ($cols as $attr => $col) {
         if ($r[$col] !== false) {
             $DteEmitido->{$attr} = $r[$col];
         }
     }
     $DteEmitido->receptor = substr($DteEmitido->receptor, 0, -2);
     $DteEmitido->xml = base64_encode($xml);
     $DteEmitido->usuario = $this->Auth->User->id;
     // guardar referencias si existen
     $datos = json_decode($DteTmp->datos, true);
     if (isset($datos['Referencia'])) {
         foreach ($datos['Referencia'] as $referencia) {
             $DteReferencia = new Model_DteReferencia();
             $DteReferencia->emisor = $DteEmitido->emisor;
             $DteReferencia->dte = $DteEmitido->dte;
             $DteReferencia->folio = $DteEmitido->folio;
             $DteReferencia->certificacion = $DteEmitido->certificacion;
             $DteReferencia->referencia_dte = $referencia['TpoDocRef'];
             $DteReferencia->referencia_folio = $referencia['FolioRef'];
             $DteReferencia->codigo = !empty($referencia['CodRef']) ? $referencia['CodRef'] : null;
             $DteReferencia->razon = !empty($referencia['RazonRef']) ? $referencia['RazonRef'] : null;
             $DteReferencia->save();
         }
     }
     // eliminar DTE temporal
     $DteTmp->delete();
     // enviar DTE al SII y redireccionar a página del DTE
     $track_id = $EnvioDte->enviar();
     if ($track_id) {
         $DteEmitido->track_id = $track_id;
         \sowerphp\core\Model_Datasource_Session::message('Documento emitido y envíado al SII, ahora debe verificar estado del envío. TrackID: ' . $track_id, 'ok');
     } else {
         \sowerphp\core\Model_Datasource_Session::message('Documento emitido, pero no pudo ser envíado al SII, debe reenviar.<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'warning');
     }
     $DteEmitido->save();
     $this->redirect('/dte/dte_emitidos/ver/' . $r['TpoDoc'] . '/' . $r['NroDoc'] . '/' . (int) $Emisor->certificacion);
 }
 /**
  * Acción que descarga la firma electrónica de un usuario
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-10-05
  */
 public function descargar()
 {
     $FirmaElectronica = (new Model_FirmaElectronicas())->getByUser($this->Auth->User->id);
     // si el usuario no tiene firma electrónica no se elimina :-)
     if (!$FirmaElectronica) {
         \sowerphp\core\Model_Datasource_Session::message('Usted no tiene una firma electrónica registrada en el sistema, no hay nada que descargar');
         $this->redirect('/dte/admin/firma_electronicas');
     }
     // descargar la firma
     $file = $FirmaElectronica->run . '.p12';
     $firma = base64_decode($FirmaElectronica->archivo);
     header('Content-Type: application/x-pkcs12');
     header('Content-Length: ' . strlen($firma));
     header('Content-Disposition: attachement; filename="' . $file . '"');
     print $firma;
     exit;
 }
 /**
  * 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;
 }
Esempio n. 15
0
 /**
  * Método que se ejecuta al terminar la ejecución del controlador
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
  * @version 2014-09-19
  */
 public function afterFilter()
 {
     if ($this->redirect !== null) {
         if (!is_array($this->redirect)) {
             $this->redirect($this->redirect);
         } else {
             if (isset($this->redirect['msg'])) {
                 \sowerphp\core\Model_Datasource_Session::message($this->redirect['msg']);
             }
             $this->redirect($this->redirect['page']);
         }
     }
     if ($this->Components) {
         $this->Components->trigger('afterFilter');
     }
 }
 /**
  * Método que permite generar un libro de guías de despacho a partir de un
  * archivo CSV con el detalle del mismo
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-12-24
  */
 public function generar_libro_guia()
 {
     // si no se viene por post terminar
     if (!isset($_POST['submit'])) {
         return;
     }
     // verificar campos no estén vacíos
     $campos = ['RutEmisorLibro', 'PeriodoTributario', 'FchResol', 'NroResol', 'TipoLibro', 'TipoEnvio', 'FolioNotificacion', 'contrasenia'];
     foreach ($campos as $campo) {
         if (!isset($_POST[$campo][0])) {
             \sowerphp\core\Model_Datasource_Session::message($campo . ' no puede estar en blanco', 'error');
             return;
         }
     }
     // si no se pasó el archivo error
     if (!isset($_FILES['archivo']) or $_FILES['archivo']['error']) {
         \sowerphp\core\Model_Datasource_Session::message('Debes enviar el archivo CSV con el detalle de las guías a la que deseas generar su XML', 'error');
         return;
     }
     // si no se pasó la firma error
     if (!isset($_FILES['firma']) or $_FILES['firma']['error']) {
         \sowerphp\core\Model_Datasource_Session::message('Debes enviar el archivo con la firma digital', 'error');
         return;
     }
     // Objeto de la Firma
     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 caratula del libro
     $caratula = ['RutEmisorLibro' => str_replace('.', '', $_POST['RutEmisorLibro']), 'PeriodoTributario' => $_POST['PeriodoTributario'], 'FchResol' => $_POST['FchResol'], 'NroResol' => $_POST['NroResol'], 'TipoLibro' => $_POST['TipoLibro'], 'TipoEnvio' => $_POST['TipoEnvio'], 'FolioNotificacion' => $_POST['FolioNotificacion']];
     // generar libro de guías
     $LibroGuia = new \sasco\LibreDTE\Sii\LibroGuia();
     $LibroGuia->agregarCSV($_FILES['archivo']['tmp_name']);
     $LibroGuia->setFirma($Firma);
     $LibroGuia->setCaratula($caratula);
     $xml = $LibroGuia->generar();
     if (!$LibroGuia->schemaValidate()) {
         \sowerphp\core\Model_Datasource_Session::message(implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
         return;
     }
     // descargar XML
     $file = TMP . '/' . $LibroGuia->getID() . '.xml';
     file_put_contents($file, $xml);
     \sasco\LibreDTE\File::compress($file, ['format' => 'zip', 'delete' => true]);
     exit;
 }
Esempio n. 17
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 envía el archivo XML del libro de ventas al SII
  * Si no hay documentos en el período se enviará sin movimientos
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-12-27
  */
 public function enviar_sii($periodo)
 {
     $Emisor = $this->getContribuyente();
     // si el periodo es mayor o igual al actual no se puede enviar
     if ($periodo >= date('Ym')) {
         \sowerphp\core\Model_Datasource_Session::message('No puede enviar el libro de ventas del período ' . $periodo . ', debe esperar al mes siguiente del período', 'error');
         $this->redirect(str_replace('enviar_sii', 'ver', $this->request->request));
     }
     // obtener ventas
     $ventas = $Emisor->getVentas($periodo);
     // crear libro
     $Libro = new \sasco\LibreDTE\Sii\LibroCompraVenta();
     // 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');
     }
     // agregar detalle
     $documentos = 0;
     foreach ($ventas as $venta) {
         $documentos++;
         // armar detalle para agregar al libro
         $d = [];
         foreach ($venta as $k => $v) {
             if (strpos($k, 'impuesto_') !== 0) {
                 if ($v !== null) {
                     $d[$this->libro_cols[$k]] = $v;
                 }
             }
         }
         // agregar otros impuestos
         if (!empty($venta['impuesto_codigo'])) {
             $d['OtrosImp'] = ['CodImp' => $venta['impuesto_codigo'], 'TasaImp' => $venta['impuesto_tasa'], 'MntImp' => $venta['impuesto_monto']];
         }
         // agregar detalle al libro
         $Libro->agregar($d);
     }
     // agregar carátula al libro
     $Libro->setCaratula(['RutEmisorLibro' => $Emisor->rut . '-' . $Emisor->dv, 'RutEnvia' => $Firma->getID(), 'PeriodoTributario' => substr($periodo, 0, 4) . '-' . substr($periodo, 4), 'FchResol' => $Emisor->certificacion ? $Emisor->certificacion_resolucion : $Emisor->resolucion_fecha, 'NroResol' => $Emisor->certificacion ? 0 : $Emisor->resolucion_numero, 'TipoOperacion' => 'VENTA', 'TipoLibro' => 'MENSUAL', 'TipoEnvio' => 'TOTAL']);
     // obtener XML
     $Libro->setFirma($Firma);
     $xml = $Libro->generar();
     if (!$xml) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible generar el libro de ventas<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
         $this->redirect(str_replace('enviar_sii', 'ver', $this->request->request));
     }
     // enviar al SII
     $track_id = $Libro->enviar();
     if (!$track_id) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible enviar el libro de ventas al SII<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
         $this->redirect(str_replace('enviar_sii', 'ver', $this->request->request));
     }
     // guardar libro de ventas
     $DteVenta = new Model_DteVenta($Emisor->rut, $periodo, (int) $Emisor->certificacion);
     $DteVenta->documentos = $documentos;
     $DteVenta->xml = base64_encode($xml);
     $DteVenta->track_id = $track_id;
     $DteVenta->save();
     \sowerphp\core\Model_Datasource_Session::message('Libro de ventas período ' . $periodo . ' envíado', 'ok');
     $this->redirect(str_replace('enviar_sii', 'ver', $this->request->request));
 }
// menú de módulos si hay sesión iniciada
if ($_Auth->logged() and $_module_breadcrumb) {
    echo '<ol class="breadcrumb">', "\n";
    $url = '/';
    foreach ($_module_breadcrumb as $link => &$name) {
        if (is_string($link)) {
            echo '    <li><a href="', $_base, $url, $link, '">', $name, '</a></li>', "\n";
            $url .= $link . '/';
        } else {
            echo '    <li class="active">', $name, '</li>';
        }
    }
    echo '</ol>', "\n";
}
// mensaje de sesión
$message = \sowerphp\core\Model_Datasource_Session::message();
if ($message) {
    $icons = ['success' => 'ok', 'info' => 'info-sign', 'warning' => 'warning-sign', 'danger' => 'exclamation-sign'];
    echo '<div class="alert alert-', $message['type'], '" role="alert">', "\n";
    echo '    <span class="glyphicon glyphicon-', $icons[$message['type']], '" aria-hidden="true"></span>', "\n";
    echo '    <span class="sr-only">', $message['type'], ': </span>', $message['text'], "\n";
    echo '</div>' . "\n";
}
// contenido de la página
echo $_content;
?>
<!-- END MAIN CONTENT -->
            <div class="center" id="google" style="margin: 2em 0">
                <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
                <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-3829973028217596" data-ad-slot="3431080345" data-ad-format="auto"></ins>
                <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script>
 /**
  * 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;
 }