thegreenter / demo

Ejemplos utilizando Greenter (UBL 2.1, SOAP, Firma digital, PDF, QR)
https://greenter-sample.herokuapp.com
MIT License
60 stars 51 forks source link

como usar getStatusCdr - billConsultService #27

Closed sysarp closed 6 years ago

sysarp commented 6 years ago

Hola Ginacarlos, Estoy tratando de implementar la funcion getStatusCdr y aun no logro que funcione con tus clases.

$USER = 'XXXXXXX';//RUC Y USUARIO SUNAT $PASS='XXXXXXXX'//CONTRASENIA $wsClient = new SoapClient('https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService?wsdl'); //$wsClient->setService('https://e-factura.sunat.gob.pe/ol-ti-itcpfegem/billService'); $wsClient->setCredentials(USER,PASS);

$ExtService = new ExtService(); $ExtService->setClient($wsClient); $cdr = $ExtService->getCdrStatus('20537897491','01','F001','1');

print_r($cdr->statusCdr);

y esto me devuelve error Function ("setCredentials") is not a valid method for this service

ahora esto me funciona cuando envio el xml de ejemplo que indica sunat via la aplicacion SOAPUI

XXXXXXXXXXXUSUARIO_SUNAT XXXXXXXX 1028308796 01 f213 12345
thefantas commented 6 years ago

Yo pude hacerlo hace un mes creando una función en util.php

    //thefantas
    public function getConsulta($endpoint)
    {       
        $client = new SoapClient($endpoint . '?wsdl'); 
    $client->setCredentials(strtoupper('20000000000ABCDEFGH'), 'password');
        $client->setService($endpoint);
        $sunat = new ExtService();
        $sunat->setClient($client);
        return $sunat;
    }

$see_cdr = $util->getConsulta(SunatEndpoints::FE_CONSULTA_CDR); $result = $see_cdr->getCdrStatus('20000000001', '01', 'F001', '2'); if ($result->isSuccess() && !empty($result->getCdrResponse())) { // procesa... }

Y por último, ya que sunat da muchos errores y dolores de cabeza, modifiqué en ExtService.php

  ```
  $result->setCode($statusCdr->statusCode)
            ->setMessage($statusCdr->statusMessage)
    ->setCdrZip(@$statusCdr->content)
            ->setSuccess(true);
        if (@$statusCdr->content)
            $result->setCdrResponse($this->extractResponse($statusCdr->content));
sysarp commented 6 years ago

Te agradesco por la informacion.

public function getConsulta($endpoint){
    $client = new SoapClient($endpoint . '?wsdl');
    $client->setCredentials('xxxxxxxxxxxxxxx','xxxxxxxxx');
    $client->setService($endpoint);
    $sunat = new ExtService();
    $sunat->setClient($client);
    return $sunat;
}
    $see_cdr = $util->getConsulta(SunatEndpoints::FE_CONSULTA_CDR);
    $rs = $see_cdr->getCdrStatus('xxxxxxxxxxxxx', '01', 'F001', '2');
    if($cdr->isSuccess() && !empty($rs->getCdrResponse())){
        print_r($rs);
    }

Me devuelve este error Function ("setCredentials") is not a valid method for this service

Pero me funciona de esta forma sin embargo me gusataria utilizar con las propias clases de la app:

    class CustomHeaders extends SoapHeader { 
        private $wss_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'; 
        function __construct($user, $pass, $ns = null){
            if ($ns) { 
            $this->wss_ns = $ns; 
            } 
            $auth = new stdClass(); 
            $auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns); 
            $auth->Password = new SoapVar($pass, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns); 
            $username_token = new stdClass(); 
            $username_token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns); 
            $security_sv = new SoapVar( new SoapVar($username_token, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns), SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'Security', $this->wss_ns); 
            parent::__construct($this->wss_ns, 'Security', $security_sv, true);   
        } 
    }

    $service='https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService?wsdl';
    $user='xxxxxxxxxxxxxxxxxxx';
    $pass='xxxxxxxxxxx';
    $headers = new CustomHeaders($user, $pass); 
    $parametros=array('cache_wsdl' => WSDL_CACHE_NONE, 'trace' => TRUE , 'soap_version' => SOAP_1_1);

    $client = new SoapClient($service, $parametros ); 
    $client->__setSoapHeaders($headers); 
    $estado = $client->getStatusCdr(
        array(
            'rucComprobante' => 'xxxxxxxxxxxx',
            'tipoComprobante' => '01',
            'serieComprobante' => 'F001',
            'numeroComprobante' => '1'
            )
        );
    $cdr = $estado->statusCdr;
    echo $cdr->statusCode;
thefantas commented 6 years ago

Recuerda agregar en Util.php

use Greenter\Ws\Services\ExtService;
use Greenter\Ws\Services\SoapClient;

Me olvidé de decir que también agregues a See.php

    // thefantas
    public function getCdrStatus($ruc, $tipo, $serie, $numero)
    {
        $sender = new ExtService();
        $sender->setClient($this->wsClient);

        return $sender->getCdrStatus($ruc, $tipo, $serie, $numero);
    }
giansalex commented 6 years ago

El problema debe ser porque esta tomando el SoapClient nativo (php_soap.dll). puedes importar el namespace o colocarlo explicitamente

$wsClient = new Greenter\Ws\Services\SoapClient('https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService?wsdl');
sysarp commented 6 years ago

use Greenter\Ws\Services\ExtService; use Greenter\Ws\Services\SoapClient;

EN UTIL

public function getConsulta($ruc,$tipo,$serie,$numero){
    $endpoint = 'https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService';
    $wsClient = new SoapClient($endpoint . '?wsdl');
    $wsClient->setCredentials('xxxxxxxxxxxx','xxxxxxxxxx');
    $wsClient->setService($endpoint);

    $sunat = new ExtService();
    $sunat->setClient($wsClient);

    $rs = $sunat->getCdrStatus($ruc, $tipo, $serie, $numero);

    return $rs;
}

DESDE ARCHIVO DONDE LLAMO LA FUNCION

    $cdr = new StatusCdrResult();
    $cdr = $util->getConsulta('XXXXXXXXXX','01','F001','1');
    if($cdr->isSuccess() && !empty($cdr->getCdrResponse())){
        print_r($cdr);
    }

RESPUESTA


Warning: gzinflate(): data error in AppServer/vendor/greenter/ws/src/Zip/ZipHelper.php on line 203

Warning: DOMDocument::loadXML(): Empty string supplied as input in AppServer/vendor/greenter/ws/src/Ws/Reader/DomCdrReader.php on line 50

Notice: Trying to get property of non-object in AppServer/vendor/greenter/ws/src/Ws/Reader/DomCdrReader.php on line 52

Warning: DOMXPath::query(): Undefined namespace prefix in AppServer/vendor/greenter/ws/src/Ws/Reader/DomCdrReader.php on line 64

Warning: DOMXPath::query(): Invalid expression in AppServer/vendor/greenter/ws/src/Ws/Reader/DomCdrReader.php on line 64

Notice: Trying to get property of non-object in AppServer/vendor/greenter/ws/src/Ws/Reader/DomCdrReader.php on line 66
{"Estado":"Error","Descripcion":"Not found cdr response in xml","FechaHora":"2018-09-10 10:09:06","data":[],"Registros":"0","Total":"0"}

NO FOUND CDR RESPONSE IN XML pero en la otra funcion si me devuelve el archivo, alguna sugerencia.

giansalex commented 6 years ago

Llegaste a probar status-cdr.php?

sysarp commented 6 years ago

NOOOOOOOOOOOOOOOOOOOOOO, NO SABIA QUE YA LO TENIAN :(, queria ayudar con eso.

sysarp commented 6 years ago

Giancarlo status-cdr.php en el git.??

giansalex commented 6 years ago

Esta aqui https://github.com/giansalex/greenter-sample/blob/master/examples/pages/status-cdr.php

thefantas commented 6 years ago

Haz la modificación en ExtService.php y el error desaparecerá.

sysarp commented 6 years ago

El que esta en esta ruta /vendor/greenter/ws/src/Ws/Services/ExtService.php

En la linea 77

        /*  $result
            ->setCode($code)
            ->setSuccess(true);
        */
          $result->setCode($statusCdr->statusCode)
                ->setMessage($statusCdr->statusMessage)
                ->setCdrZip(@$statusCdr->content)
                ->setSuccess(true);
        if(@$statusCdr->content)
            $result->setCdrResponse($this->extractResponse($statusCdr->content));
thefantas commented 6 years ago

DESDE ARCHIVO DONDE LLAMO LA FUNCION

$cdr = new StatusCdrResult(); $cdr = $util->getConsulta('XXXXXXXXXX','01','F001','1'); if($cdr->isSuccess() && !empty($cdr->getCdrResponse())){ print_r($cdr); }

Me parece que cometes un error, es así.

$see_cdr = $util->getConsulta(SunatEndpoints::FE_CONSULTA_CDR);
    $rs = $see_cdr->getCdrStatus('xxxxxxxxxxxxx', '01', 'F001', '2');
    if($cdr->isSuccess() && !empty($rs->getCdrResponse())){
        print_r($rs);
    }

Es un getConsulta con el endpoint no con los parámetros de consulta, saludos.

sysarp commented 6 years ago

Ya habia modificado la funcion pero igual me devuelve lo mismo:

public function getConsulta($ruc,$tipo,$serie,$numero){ $endpoint = 'https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService'; $wsClient = new SoapClient($endpoint . '?wsdl'); $wsClient->setCredentials('xxxxxxxxxxxx','xxxxxxxxxx'); $wsClient->setService($endpoint);

$sunat = new ExtService();
$sunat->setClient($wsClient);

$rs = $sunat->getCdrStatus($ruc, $tipo, $serie, $numero);

return $rs;

}

$cdr = new StatusCdrResult(); $cdr = $util->getConsulta('XXXXXXXXXX','01','F001','1'); if($cdr->isSuccess() && !empty($cdr->getCdrResponse())){ print_r($cdr); }

########################################################################

AHORA LO ESTOY PROBANDO DE ESTA FORMA Y LA RESPUESTA ES IGUAL / EL SETEO ES MANUAL.

<#?#php

use Greenter\Ws\Services\ExtService; use Greenter\Ws\Services\SoapClient; use Greenter\Ws\Services\SunatEndpoints;

require DIR . '/../../../../vendor/autoload.php';

$errorMsg = null;

function validateFields(array $items){ global $errorMsg; foreach ($items as $key => $value) { if (empty($value)) { $errorMsg = 'El campo '.$key.', es requerido'; return false; } } return true; }

function getCdrStatusService($user, $password){ $ws = new SoapClient(SunatEndpoints::FE_CONSULTA_CDR.'?wsdl'); $ws->setCredentials($user, $password);

$service = new ExtService();
$service->setClient($ws);

return $service;

}

function process($fields){ /* if (!isset($fields['rucSol'])) { return null; }

if (!validateFields($fields)) {
    return null;
}

*/ $service = getCdrStatusService('XXXXXXXXXX','XXXXXXXX'); return $service->getCdrStatus('XXXXXXXXXX','01','F001','1'); }

function DocGetStatusCdr($args){ try{

    $DOC = $args;
    $rsSunat = process([]);

    if($rsSunat->isSuccess()){

        $json = array();
        $json["Estado"] = "Cargado";
        $json['data']['rsCodigo'] = $rsSunat->getCode();
        $json['data']['rsDescripcion'] = '';
        return $json;
    }else{
        $error = $rsSunat->getError();
        throw new Exception("Error " . $error->getCode() . " | " .$error->getMessage());
    }
}catch(Exception $e){
    $json = array();
    $json["Estado"] = "Error " . $e->getMessage();
    $json['data']['rsCodigo'] = '';
    $json['data']['rsDescripcion'] = '';
    return $json;
}

} ? #>

EL ERROR ES


Warning: gzinflate(): data error in /vendor/greenter/ws/src/Zip/ZipHelper.php on line 203

Warning: DOMDocument::loadXML(): Empty string supplied as input in /vendor/greenter/ws/src/Ws/Reader/DomCdrReader.php on line 50

Notice: Trying to get property of non-object in /vendor/greenter/ws/src/Ws/Reader/DomCdrReader.php on line 52

Warning: DOMXPath::query(): Undefined namespace prefix in /vendor/greenter/ws/src/Ws/Reader/DomCdrReader.php on line 64

Warning: DOMXPath::query(): Invalid expression in /AppServer/vendor/greenter/ws/src/Ws/Reader/DomCdrReader.php on line 64

Notice: Trying to get property of non-object in /vendor/greenter/ws/src/Ws/Reader/DomCdrReader.php on line 66
stdClass Object ( [rsCodigo] => [rsDescripcion] => )

GRACIAS POR SUS RESPUESTAS

giansalex commented 6 years ago

image Deberías intentar hacerlo desde la pagina de ejemplo desde tu local, y ver que resulta.

sysarp commented 6 years ago

Sale este error con GREENTER-SAMPLE:

Fatal error: Uncaught Error: Class 'Greenter\Ws\Services\ConsultCdrService' not found in /greenter-sample/examples/pages/status-cdr.php:37 Stack trace: #0 /greenter-sample/examples/pages/status-cdr.php(61): getCdrStatusService('xxxxxxxxxxxx...', 'xxxxxxxxxxx') #1/greenter-sample/examples/pages/status-cdr.php(82): process(Array) #2 {main} thrown in /greenter-sample/examples/pages/status-cdr.php on line 37

thefantas commented 6 years ago

Creo que tienes que cargarlos con autoload (editar), y actualiza tus librerias (revisa los commits). Saludos

sysarp commented 6 years ago

falto actualizar composer voy a revisarlo. gracias

giansalex commented 6 years ago

si, git pull, composer update

sysarp commented 6 years ago

GRACIAS!!!

use Greenter\Ws\Services\ConsultCdrService;
use Greenter\Ws\Services\SoapClient;
use Greenter\Ws\Services\SunatEndpoints;

$filename = null;

function savedFile($filename, $content)
{
    $pathZip = __DIR__.'/cache/'.$filename;
    file_put_contents($pathZip, $content);
}

function process($fields){
    global $filename;

    $ws = new SoapClient(SunatEndpoints::FE_CONSULTA_CDR.'?wsdl');
    $ws->setCredentials('XXXXXXXXXXXXXXXX','XXXXXXXXXXXXXXX');

    $service = new ConsultCdrService();
    $service->setClient($ws);

    $arguments = [
        $fields['rucComprobante'],
        $fields['tipoComprobante'],
        $fields['serieComprobante'],
        intval($fields['numeroComprobante'])
    ];

    if (isset($fields['cdr'])) {
        $result = $service->getStatusCdr(...$arguments);
        if ($result->getCdrZip()) {
            $filename = 'R-'.implode('-', $arguments).'.zip';
            savedFile($filename, $result->getCdrZip());
        }
        return $result;
    }
    return $service->getStatus(...$arguments);
}

function DocGetStatusCdr($args){
    try{
        $DOC = $args;
        $params = array(
            'cdr' => false,
            'rucComprobante' => 'xxxxxxxxxxxxxxxX',
            'rucComprobante' => $DOC['DocEmisorDocNumero'],
            'tipoComprobante' => $DOC['DocTipo'],
            'serieComprobante' => $DOC['DocSerie'],
            'numeroComprobante' => $DOC['DocNumero']
        );
        $rsSunat = process($params);

        if($rsSunat->isSuccess()){
            $json = array();
            $json["Estado"] = "Cargado";
            $json['data']['rsCodigo'] = $rsSunat->getCode();
            $json['data']['rsDescripcion'] = $rsSunat->getMessage();
            return $json;
        }else{
            $error = $rsSunat->getError();
            throw new Exception("Error " . $error->getCode() . " | " .$error->getMessage());
        }
    }catch(Exception $e){
        $json = array();
        $json["Estado"] = "Error";
        $json['data']['rsCodigo'] = $e->getCode();
        $json['data']['rsDescripcion'] = $e->getMessage();
        return $json;
    }
}

:)

thefantas commented 6 years ago

Deben corregir su código...

if (isset($fields['cdr'])) { <-- Solo comprueba que la variable esté definida, en su caso false o true da igual.
por...
if (isset($fields['cdr']) && $fields['cdr']) { <-- con esto además comprueba que sea true como me imagino que necesitan.

Saludos.

giansalex commented 6 years ago

Hola @thefantas , se usa esa comprobación porque son dos botones, uno para consultar el estado y el otro para obtener el CDR, el servicio billConsultService tiene 2 métodos getStatus() y getStatusCdr, validar que exista la variable isset($fields['cdr'] me indica si fue el botón de Consultar CDR o sino el otro, Consultar Estado

thefantas commented 6 years ago

Entonces que sea true o false es insignificante y poco práctico. ya que basta que esté definido ya procesa la condificional.

giansalex commented 6 years ago

Asi es, solo comprueba que este definido, no importa el valor que tenga