LibreDTE / libredte-lib-core

LibreDTE: Biblioteca PHP (Núcleo)
https://lib-core.docs.libredte.cl
GNU Affero General Public License v3.0
196 stars 156 forks source link

Añadir funcionalidad `getContribuyente` #64

Closed dissapointmentcl closed 4 years ago

dissapointmentcl commented 4 years ago

Hola, gracias DeLaF por el inmenso aporte con esta biblioteca.

Quería permitirme ver la posiblilidad de implementar esta función en Lib/Sii.php, solo que no logro que el token generado por getToken sea compatible con esta Request.

Yo validé que funcionase, con un token generado directo en la pagina del SII logueado con certificado digital.

    /**
     * Método que entrega un arreglo con todos los datos de un contribuyente especifico
     * que operan con factura electrónica descargados desde el SII
     */
    public static function getContribuyente(\sasco\LibreDTE\FirmaElectronica $Firma, $ambiente = null, $params)
    {
        // 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];

        [$rut, $dv] = explode('-', $Firma->getID());
        // preparar consulta curl
        $curl = curl_init();

        $cookies = [
            'cert_Origin=hercules.sii.cl',
            'EMG='.$rut,
            'NETSCAPE_LIVEWIRE.rcmp='.$params['RUT_EMP'],
            'NETSCAPE_LIVEWIRE.dcmp='.$params['DV_EMP'],
            'NETSCAPE_LIVEWIRE.rut='.$rut,
            'NETSCAPE_LIVEWIRE.rutm='.$rut,
            'NETSCAPE_LIVEWIRE.dv='.$dv,
            'NETSCAPE_LIVEWIRE.dvm='.$dv,
            'NETSCAPE_LIVEWIRE.lms=120',
            'RUT_NS='.$rut,
            'DV_NS='.$dv,
            'TOKEN='.$token
        ];

        $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_cgi/dte/ce_consulta_rut',
            'Cookie: '.implode('; ', $cookies),
            'Accept-Encoding' => 'gzip, deflate, sdch',
            'Content-Type' => 'application/x-www-form-urlencoded',
        ];
        $url = 'https://'.$servidor.'.sii.cl/cvc_cgi/dte/ce_consulta_e';
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        curl_setopt($curl, CURLOPT_URL, $url);

        // 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);
        }
        // Añadir submit del boton
        $params['ACEPTAR'] = 'Consultar';

        // carga de parámetros POST
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($params));
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        // realizar consulta curl
        $response = curl_exec($curl);

        if (!$response)
            return false;

        $clientData = [];

        try{
            $dom = new \DOMDocument();
            $dom->loadHTML($response);
            $xpath = new \DOMXPath($dom);
            $tags = $xpath->query('//td[@align="left"]/font[@class="texto"]');

            $lastKey = '';
            foreach ($tags as $i => $tag) {
                $values = explode('  ',$tag->textContent);
                $text = '';
                foreach($values as $val){
                    $val = strip_tags($val);
                    if(strlen(str_replace(' ', '', $val)) >= strlen($text)){
                        $text = $val;
                    }
                }
                if($i%2 === 0) $lastKey = trim(strip_tags($text));
                $clientData[$lastKey] = trim(strip_tags($text));
            }

            [
                'Rut' => $rut,
                'Razón Social/Nombres' => $razonsoc,
                'N° Resolución' => $nroresol,
                'Fecha Resolución' => $fecharesol,
                'Mail de contacto' => $mailcontacto
            ] = $clientData;

            // cerrar sesión curl
            curl_close($curl);

            return [
                'Rut' => $rut,
                'Razón Social' => $razonsoc,
                'N° Resolución' => $nroresol,
                'Fecha Resolución' => $fecharesol,
                'Mail de contacto' => $mailcontacto
            ];
        } catch (\Exception $e) {
            $msg = $e->getMessage();
            if (isset($e->getTrace()[0]['args'][1]) and is_string($e->getTrace()[0]['args'][1])) {
                $msg .= ': '.$e->getTrace()[0]['args'][1];
            }
            \sasco\LibreDTE\Log::write(Estado::REQUEST_ERROR_SOAP, Estado::get(Estado::REQUEST_ERROR_SOAP, $msg));
            return null;
        }
    }
estebandelaf commented 4 years ago

La biblioteca de LibreDTE sólo trabaja con servicios web oficiales del SII. No tiene, ni tendrá, soporte para consultas como la que se menciona aquí.

Si necesitas obtener los datos de los contribuyentes, es mejor hacerlo consultando la API de LibreDTE. Específicamente el servicio web que te puede servir es este:

https://documenter.getpostman.com/view/5911929/SWLiYkK9?version=latest#8b6c8774-9ed0-48d6-9b9d-4fa4ab909d4e

Eso te entregará un listado con todos los contribuyentes autorizados a trabajar con DTE. Junto a su correo de intercambio. Si actualizas eso al menos una vez a la semana, tendrás bien actualizados los datos. Y claro, puedes actualizar todos los días incluso.

Aun así, si necesitas obtener los datos sólo de un contribuyente (incluyendo correo), puedes usar este servicio web:

https://documenter.getpostman.com/view/5911929/SWLiYkK9?version=latest#6ec81a87-96dd-403c-adaa-8aa0bd3d0d9a

Yo no recomiendo mucho este último, porque sólo te trae un contribuyente, en cambio la anterior te los trae todos.

Esos servicios son parte de los que encuentras en https://api.libredte.cl