Пример #1
0
 /**
  * Método que realiza el envío del documento al SII
  * @return Track ID del envío o =false si hubo algún problema al enviar el documento
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-12-14
  */
 public function enviar()
 {
     // generar XML que se enviará
     if (!$this->xml_data) {
         $this->xml_data = $this->generar();
     }
     if (!$this->xml_data) {
         \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::DOCUMENTO_ERROR_GENERAR_XML, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::DOCUMENTO_ERROR_GENERAR_XML, substr(get_class($this), strrpos(get_class($this), '\\') + 1)));
         return false;
     }
     // validar schema del documento antes de enviar
     if (!$this->schemaValidate()) {
         return false;
     }
     // solicitar token
     $token = \sasco\LibreDTE\Sii\Autenticacion::getToken($this->Firma);
     if (!$token) {
         return false;
     }
     // enviar DTE
     $envia = $this->caratula['RutEnvia'];
     $emisor = !empty($this->caratula['RutEmisor']) ? $this->caratula['RutEmisor'] : $this->caratula['RutEmisorLibro'];
     $result = \sasco\LibreDTE\Sii::enviar($envia, $emisor, $this->xml_data, $token);
     if ($result === false) {
         return false;
     }
     if (!is_numeric((string) $result->TRACKID)) {
         return false;
     }
     return (int) (string) $result->TRACKID;
 }
 *
 * Debería haber recibido una copia de la Licencia Pública General GNU
 * junto a este programa.
 * En caso contrario, consulte <http://www.gnu.org/licenses/gpl.html>.
 */
/**
 * @file 005-estado_envio_dte.php
 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
 * @version 2015-09-16
 */
// respuesta en texto plano
header('Content-type: text/plain');
// incluir archivos php de la biblioteca y configuraciones
include 'inc.php';
// solicitar token
$token = \sasco\LibreDTE\Sii\Autenticacion::getToken($config['firma']);
if (!$token) {
    foreach (\sasco\LibreDTE\Log::readAll() as $error) {
        echo $error, "\n";
    }
    exit;
}
// consultar estado enviado
$rut = '';
$dv = '';
$trackID = '';
$estado = \sasco\LibreDTE\Sii::request('QueryEstUp', 'getEstUp', [$rut, $dv, $trackID, $token]);
// si el estado se pudo recuperar se muestra estado y glosa
if ($estado !== false) {
    print_r(['codigo' => (string) $estado->xpath('/SII:RESPUESTA/SII:RESP_HDR/ESTADO')[0], 'glosa' => (string) $estado->xpath('/SII:RESPUESTA/SII:RESP_HDR/GLOSA')[0]]);
}
Пример #3
0
$Folios = new \sasco\LibreDTE\Sii\Folios(file_get_contents('xml/folios/33.xml'));
// generar XML del DTE timbrado y firmado
$DTE = new \sasco\LibreDTE\Sii\Dte($factura);
$DTE->timbrar($Folios);
$DTE->firmar($Firma);
// generar sobre con el envío del DTE
// en este ejemplo sólo se obtendrá el XML del EnvioDT y se enviará
// posteriormente por el método "paso a paso", existe un método
// EnvioDTE::enviar() que envía el XML que se genera, ver ejemplo 010-set_pruebas.php
$EnvioDTE = new \sasco\LibreDTE\Sii\EnvioDTE();
$EnvioDTE->agregar($DTE);
$EnvioDTE->setCaratula($caratula);
$EnvioDTE->setFirma($Firma);
$xml = $EnvioDTE->generar();
// solicitar token
$token = \sasco\LibreDTE\Sii\Autenticacion::getToken($Firma);
if (!$token) {
    foreach (\sasco\LibreDTE\Log::readAll() as $log) {
        echo $log, "\n";
    }
    exit;
}
// enviar DTE
$result = \sasco\LibreDTE\Sii::enviar($caratula['RutEnvia'], $factura['Encabezado']['Emisor']['RUTEmisor'], $xml, $token);
// si hubo algún error al enviar al servidor mostrar
if ($result === false) {
    foreach (\sasco\LibreDTE\Log::readAll() as $log) {
        echo $log, "\n";
    }
    exit;
}
Пример #4
0
 /**
  * Método que entrega un arreglo con todos los datos de los contribuyentes
  * que operan con factura electrónica descargados desde el SII
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-30
  */
 public static function getContribuyentes(\sasco\LibreDTE\FirmaElectronica $Firma, $ambiente = null)
 {
     // solicitar token
     $token = \sasco\LibreDTE\Sii\Autenticacion::getToken($Firma);
     if (!$token) {
         return false;
     }
     // definir ambiente y servidor
     $ambiente = self::getAmbiente($ambiente);
     $servidor = self::$config['servidor'][$ambiente];
     // preparar consulta curl
     $curl = curl_init();
     $header = ['User-Agent: Mozilla/4.0 (compatible; PROG 1.0; Windows NT 5.0; YComp 5.0.2.4)', 'Referer: https://' . $servidor . '.sii.cl/cvc/dte/ee_empresas_dte.html', 'Cookie: TOKEN=' . $token, 'Accept-Encoding' => 'gzip, deflate, sdch'];
     $url = 'https://' . $servidor . '.sii.cl/cvc_cgi/dte/ee_consulta_empresas_dwnld?NOMBRE_ARCHIVO=ce_empresas_dwnld_' . date('Ymd') . '.csv';
     curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
     curl_setopt($curl, CURLOPT_URL, $url);
     curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
     // si no se debe verificar el SSL se asigna opción a curl, además si
     // se está en el ambiente de producción y no se verifica SSL se
     // generará un error de nivel E_USER_NOTICE
     if (!self::$verificar_ssl) {
         if ($ambiente == self::PRODUCCION) {
             $msg = Estado::get(Estado::ENVIO_SSL_SIN_VERIFICAR);
             trigger_error($msg, E_USER_NOTICE);
             \sasco\LibreDTE\Log::write(Estado::ENVIO_SSL_SIN_VERIFICAR, $msg, LOG_WARNING);
         }
         curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
     }
     // realizar consulta curl
     $response = curl_exec($curl);
     if (!$response) {
         return false;
     }
     // cerrar sesión curl
     curl_close($curl);
     // entregar datos del archivo CSV
     ini_set('memory_limit', '1024M');
     $lines = explode("\n", $response);
     $n_lines = count($lines);
     $data = [];
     for ($i = 1; $i < $n_lines; $i++) {
         $row = str_getcsv($lines[$i], ';', '');
         unset($lines[$i]);
         if (!isset($row[5])) {
             continue;
         }
         for ($j = 0; $j < 6; $j++) {
             $row[$j] = trim($row[$j]);
         }
         $row[1] = utf8_decode($row[1]);
         $row[4] = strtolower($row[4]);
         $row[5] = strtolower($row[5]);
         $data[] = $row;
     }
     return $data;
 }
 /**
  * Método que consulta al estado al SII del dte recibido
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-28
  */
 public function getEstado(\sasco\LibreDTE\FirmaElectronica $Firma)
 {
     // obtener token
     $token = \sasco\LibreDTE\Sii\Autenticacion::getToken($Firma);
     if (!$token) {
         return false;
     }
     // consultar estado
     list($RutConsultante, $DvConsultante) = explode('-', $Firma->getID());
     list($Y, $m, $d) = explode('-', $this->fecha);
     $xml = \sasco\LibreDTE\Sii::request('QueryEstDte', 'getEstDte', ['RutConsultante' => $RutConsultante, 'DvConsultante' => $DvConsultante, 'RutCompania' => $this->getEmisor()->rut, 'DvCompania' => $this->getEmisor()->dv, 'RutReceptor' => $this->getReceptor()->rut, 'DvReceptor' => $this->getReceptor()->dv, 'TipoDte' => $this->dte, 'FolioDte' => $this->folio, 'FechaEmisionDte' => $d . $m . $Y, 'MontoDte' => $this->total, 'token' => $token]);
     // si hubo error con el estado se muestra que no se pudo obtener
     if ($xml === false) {
         return false;
     }
     $estado = (array) $xml->xpath('/SII:RESPUESTA/SII:RESP_HDR')[0];
     return $estado['ESTADO'] == 'DOK' ? true : $estado['GLOSA_ERR'];
 }
 /**
  * Acción que solicita se envíe una nueva revisión del DTE al email
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-25
  */
 public function solicitar_revision($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');
     }
     // si no tiene track id error
     if (!$DteEmitido->track_id) {
         \sowerphp\core\Model_Datasource_Session::message('DTE no tiene Track ID, primero debe enviarlo al SII', 'error');
         $this->redirect(str_replace('solicitar_revision', 'ver', $this->request->request));
     }
     // 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');
     }
     // obtener token
     $token = \sasco\LibreDTE\Sii\Autenticacion::getToken($Firma);
     if (!$token) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible obtener el token para el SII<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
         $this->redirect(str_replace('solicitar_revision', 'ver', $this->request->request));
     }
     // solicitar envío de nueva revisión
     $estado = \sasco\LibreDTE\Sii::request('wsDTECorreo', 'reenvioCorreo', [$token, $Emisor->rut, $Emisor->dv, $DteEmitido->track_id]);
     if ($estado === false) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible solicitar una nueva revisión del DTE.<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
     } else {
         if ((int) $estado->xpath('/SII:RESPUESTA/SII:RESP_HDR/SII:ESTADO')[0]) {
             \sowerphp\core\Model_Datasource_Session::message('No fue posible solicitar una nueva revisión del DTE: ' . $estado->xpath('/SII:RESPUESTA/SII:RESP_HDR/SII:GLOSA')[0], 'error');
         } else {
             \sowerphp\core\Model_Datasource_Session::message('Se solicitó nueva revisión del DTE, verificar estado en unos segundos', 'ok');
         }
     }
     // redireccionar
     $this->redirect(str_replace('solicitar_revision', 'ver', $this->request->request));
 }
 /**
  * Recurso de la API que permite validar el TED (timbre electrónico)
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-19
  */
 public function _api_verificar_ted_POST()
 {
     // verificar si se pasaron credenciales de un usuario
     $User = $this->Api->getAuthUser();
     if (is_string($User)) {
         $this->Api->send($User, 401);
     }
     // obtener TED
     $TED = base64_decode($this->Api->data);
     if (strpos($TED, '<?xml') !== 0) {
         $TED = '<?xml version="1.0" encoding="ISO-8859-1"?>' . "\n" . $TED;
     }
     // crear xml con el ted y obtener datos en arreglo
     $xml = new \sasco\LibreDTE\XML();
     $xml->loadXML($TED);
     $datos = $xml->toArray();
     // verificar firma del ted
     $DD = $xml->getFlattened('/TED/DD');
     $FRMT = $datos['TED']['FRMT'];
     $pub_key = \sasco\LibreDTE\FirmaElectronica::getFromModulusExponent($datos['TED']['DD']['CAF']['DA']['RSAPK']['M'], $datos['TED']['DD']['CAF']['DA']['RSAPK']['E']);
     if (openssl_verify($DD, base64_decode($FRMT), $pub_key, OPENSSL_ALGO_SHA1) !== 1) {
         $this->Api->send('Firma del timbre incorrecta', 500);
     }
     // verificar que datos del timbre correspondan con datos del CAF
     if ($datos['TED']['DD']['RE'] != $datos['TED']['DD']['CAF']['DA']['RE']) {
         $this->Api->send('RUT del timbre no corresponde con RUT del CAF', 500);
     }
     if ($datos['TED']['DD']['TD'] != $datos['TED']['DD']['CAF']['DA']['TD']) {
         $this->Api->send('Tipo de DTE del timbre no corresponde con tipo de DTE del CAF', 500);
     }
     if ($datos['TED']['DD']['F'] < $datos['TED']['DD']['CAF']['DA']['RNG']['D'] or $datos['TED']['DD']['F'] > $datos['TED']['DD']['CAF']['DA']['RNG']['H']) {
         $this->Api->send('Folio del DTE del timbre fuera del rango del CAF', 500);
     }
     // definir si se consultará en certificación o producción
     define('_LibreDTE_CERTIFICACION_', $datos['TED']['DD']['CAF']['DA']['IDK'] == 100);
     // crear objeto firma
     $Firma = new \sasco\LibreDTE\FirmaElectronica();
     // obtener token
     $token = \sasco\LibreDTE\Sii\Autenticacion::getToken($Firma);
     if (!$token) {
         return $this->Api->send(\sasco\LibreDTE\Log::readAll(), 500);
     }
     // verificar estado del DTE con el SII
     list($RutConsultante, $DvConsultante) = explode('-', $Firma->getID());
     list($RutCompania, $DvCompania) = explode('-', $datos['TED']['DD']['RE']);
     list($RutReceptor, $DvReceptor) = explode('-', $datos['TED']['DD']['RR']);
     list($a, $m, $d) = explode('-', $datos['TED']['DD']['FE']);
     $xml = \sasco\LibreDTE\Sii::request('QueryEstDte', 'getEstDte', ['RutConsultante' => $RutConsultante, 'DvConsultante' => $DvConsultante, 'RutCompania' => $RutCompania, 'DvCompania' => $DvCompania, 'RutReceptor' => $RutReceptor, 'DvReceptor' => $DvReceptor, 'TipoDte' => $datos['TED']['DD']['TD'], 'FolioDte' => $datos['TED']['DD']['F'], 'FechaEmisionDte' => $d . $m . $a, 'MontoDte' => $datos['TED']['DD']['MNT'], 'token' => $token]);
     if ($xml === false) {
         return $this->Api->send(\sasco\LibreDTE\Log::readAll(), 500);
     }
     return (array) $xml->xpath('/SII:RESPUESTA/SII:RESP_HDR')[0];
 }
Пример #8
0
 /**
  * Método que obtiene el estado del DTE
  * @param Firma objeto que representa la Firma Electrónca
  * @return Arreglo con el estado del DTE
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-27
  */
 public function getEstado(\sasco\LibreDTE\FirmaElectronica $Firma)
 {
     // solicitar token
     $token = \sasco\LibreDTE\Sii\Autenticacion::getToken($Firma);
     if (!$token) {
         return false;
     }
     // consultar estado dte
     list($RutConsultante, $DvConsultante) = explode('-', $Firma->getID());
     list($RutCompania, $DvCompania) = explode('-', $this->getEmisor());
     list($RutReceptor, $DvReceptor) = explode('-', $this->getReceptor());
     list($Y, $m, $d) = explode('-', $this->getFechaEmision());
     $xml = \sasco\LibreDTE\Sii::request('QueryEstDte', 'getEstDte', ['RutConsultante' => $RutConsultante, 'DvConsultante' => $DvConsultante, 'RutCompania' => $RutCompania, 'DvCompania' => $DvCompania, 'RutReceptor' => $RutReceptor, 'DvReceptor' => $DvReceptor, 'TipoDte' => $this->getTipo(), 'FolioDte' => $this->getFolio(), 'FechaEmisionDte' => $d . $m . $Y, 'MontoDte' => $this->getMontoTotal(), 'token' => $token]);
     // si el estado se pudo recuperar se muestra
     if ($xml === false) {
         return false;
     }
     // entregar estado
     return (array) $xml->xpath('/SII:RESPUESTA/SII:RESP_HDR')[0];
 }