<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use PhpCfdi\SatWsDescargaMasiva\RequestBuilder\FielRequestBuilder\Fiel;
use PhpCfdi\SatWsDescargaMasiva\RequestBuilder\FielRequestBuilder\FielRequestBuilder;
use PhpCfdi\SatWsDescargaMasiva\Service;
use PhpCfdi\SatWsDescargaMasiva\WebClient\GuzzleWebClient;
use PhpCfdi\SatWsDescargaMasiva\RequestBuilder\RequestBuilderInterface;
use PhpCfdi\SatWsDescargaMasiva\Shared\ServiceEndpoints;
use PhpCfdi\SatWsDescargaMasiva\Services\Query\QueryParameters;
use PhpCfdi\SatWsDescargaMasiva\Shared\DateTimePeriod;
use PhpCfdi\SatWsDescargaMasiva\Shared\DownloadType;
use PhpCfdi\SatWsDescargaMasiva\Shared\RequestType;
use PhpCfdi\SatWsDescargaMasiva\PackageReader\Exceptions\OpenZipFileException;
use PhpCfdi\SatWsDescargaMasiva\PackageReader\MetadataPackageReader;
use PhpCfdi\SatWsDescargaMasiva\PackageReader\CfdiPackageReader;
use App\Factura;
use App\Cliente;
use App\Empresa;
use DB;


class AlmacenDigitalController extends Controller
{	
	private $fiel;
	private $webClient;
	private $requestBuilder;
	private $service;

	public function __construct()
    {

    	$fiel = Empresa::find(1);
    	$url = storage_path('app');
		// Creación de la FIEL, puede leer archivos DER (como los envía el SAT) o PEM (convertidos con openssl)
		$fiel = Fiel::create(
		    file_get_contents($url.'/'.$fiel->cer),
		    file_get_contents($url.'/'.$fiel->key),
		    $fiel->contra_csd
		);

		// verificar que la FIEL sea válida (no sea CSD y sea vigente acorde a la fecha del sistema)
		if (! $fiel->isValid()) {

		    return;
		}

		// creación del web client basado en Guzzle que implementa WebClientInterface
		// para usarlo necesitas instalar guzzlehttp/guzzle pues no es una dependencia directa
		$webClient = new GuzzleWebClient();

		// creación del objeto encargado de crear las solicitudes firmadas usando una FIEL
		$requestBuilder = new FielRequestBuilder($fiel);

		// Creación del servicio
		$this->service = new Service($requestBuilder, $webClient);
		//dd($service);
    }
    public function getXMLs(Request $r){
    	//echo $r->rango;03/28/2021 - 03/28/2021
    	$cliente = $r->cliente;
    	$fechas = explode(' - ', $r->rango);
    	$fechaIni = date('Y-m-d', strtotime($fechas[0]));
    	$fechaIni =  $fechaIni.' 00:00:00';
    	$fechaFin = date('Y-m-d', strtotime($fechas[1]));
    	$fechaFinAux = date('Y-m-d', strtotime($fechas[1]));
    	$minutos = rand(10, 59);
    	$segundos = rand(10, 59);
    	$minutos2 = rand(10, 59);
    	$segundos2 = rand(10, 59);
    	$fechaFin =  $fechaFin.' 23:'.$minutos.':'.$segundos;
    	$fechaFin2 =  $fechaFinAux.' 23:'.$minutos2.':'.$segundos2;


    	$respX = $this->peticionDescargaXMLs($cliente,$fechaIni,$fechaFin);
    	$respD = $this->peticionDescargaDatos($cliente,$fechaIni,$fechaFin2);
    	//dd($this->service);
    	if($respX['estatus']==1 && $respD['estatus']==1){
    		$resultado = array('estatus' => 1,'idPeticionXml' => $respX['solicitud'],'idPeticionDatos' => $respD['solicitud']);
    	}else{
    		$resultado = array('estatus' => 0,'mensaje' => $respX['mensaje'].'/'.$respD['mensaje'] );
    	}
    	echo json_encode($resultado);
    	exit();
    	
    }
    public function peticionDescargaXMLs($cliente,$fechaIni,$fechaFin){
    	// crear la consulta:
		// - Del 13/ene/2019 00:00:00 al 13/ene/2019 (inclusive)
		// - Todos los emitidos por el dueño de la FIEL
		// - Solicitando la información de Metadata
		// - Filtrando únicamente por los recibidos del RFC MAG041126GT8	
		if($cliente!=0){
			$request = QueryParameters::create(
			    DateTimePeriod::createFromValues($fechaIni, $fechaFin),
			    DownloadType::issued(),
			    //DownloadType::received(),
			    RequestType::cfdi(),
			    $cliente
			);
		}else{
			$request = QueryParameters::create(
			    DateTimePeriod::createFromValues($fechaIni, $fechaFin),
			    DownloadType::issued(),
			    //DownloadType::received(),
			    RequestType::cfdi(),
			    //'MAG041126GT8'
			);
		}

		// presentar la consulta
		$query = $this->service->query($request);
		//dd($query);

		// verificar que el proceso de consulta fue correcto
		if (! $query->getStatus()->isAccepted()) {
		    //echo "Fallo al presentar la consulta: {$query->getStatus()->getMessage()}";
		    return $arrayName = array('estatus'=> 0,'mensaje' =>  $query->getStatus()->getMessage() );
		}

		// el identificador de la consulta está en $query->getRequestId()
		//echo "<br>Se generó la solicitud {$query->getRequestId()}", PHP_EOL;
		
		// consultar el servicio de verificación
		$requestId =  $query->getRequestId();

		return $arrayName = array('estatus'=> 1,'solicitud' =>  $requestId,'mensaje' => '' );
    }
        public function peticionDescargaDatos($cliente,$fechaIni,$fechaFin){
    	// crear la consulta:
		// - Del 13/ene/2019 00:00:00 al 13/ene/2019 (inclusive)
		// - Todos los emitidos por el dueño de la FIEL
		// - Solicitando la información de Metadata
		// - Filtrando únicamente por los recibidos del RFC MAG041126GT8
        if($cliente!=0){
			$request = QueryParameters::create(
			    DateTimePeriod::createFromValues($fechaIni, $fechaFin),
			    DownloadType::issued(),
			    //DownloadType::received(),
			    RequestType::metadata(),
			    $cliente
			);
        }else{
			$request = QueryParameters::create(
			    DateTimePeriod::createFromValues($fechaIni, $fechaFin),
			    DownloadType::issued(),
			    //DownloadType::received(),
			    RequestType::metadata(),
			    //'MAG041126GT8'
			);       	
        }

		// presentar la consulta
		$query = $this->service->query($request);
		//dd($query);

		// verificar que el proceso de consulta fue correcto
		if (! $query->getStatus()->isAccepted()) {
		    //echo "Fallo al presentar la consulta: {$query->getStatus()->getMessage()}";
		    return $arrayName = array('estatus'=> 0,'mensaje' =>  $query->getStatus()->getMessage() );
		}

		// el identificador de la consulta está en $query->getRequestId()
		//echo "<br>Se generó la solicitud {$query->getRequestId()}", PHP_EOL;
		
		// consultar el servicio de verificación
		$requestId =  $query->getRequestId();


		return $arrayName = array('estatus'=> 1,'solicitud' =>  $requestId,'mensaje' => '' );
    }
    public function verifica_solicitud_datos(Request $r){
    	// Creación del servicio
		//$service = new Service($requestBuilder, $webClient);
		$url = storage_path('app');
		sleep(15);
		$requestId = $r->idSol;
		//echo $requestId;
		//exit();
		$verify = $this->service->verify($requestId);

			//sleep(100);
		// revisar que el proceso de verificación fue correcto
		if (! $verify->getStatus()->isAccepted()) {
		    $err = "Fallo al verificar la consulta {$requestId}: {$verify->getStatus()->getMessage()}";
		    $arrayerror = array('estatus' => 0,'msj' => $err );
		    echo json_encode($arrayerror);
		    exit();
		}

		// revisar que la consulta no haya sido rechazada
		if (! $verify->getCodeRequest()->isAccepted()) {
		    $err = "La solicitud {$requestId} fue rechazada: {$verify->getCodeRequest()->getMessage()}";
		    $arrayerror = array('estatus' => 0,'msj' => $err );
		    echo json_encode($arrayerror);
		    exit();
		    
		}

		// revisar el progreso de la generación de los paquetes
		$statusRequest = $verify->getStatusRequest();
		//dd($verify);
		//exit();
		/*if ($statusRequest->isExpired() || $statusRequest->isFailure() || $statusRequest->isRejected()) {
		    $err = "La solicitud {$requestId} no se puede completar";
		    $arrayerror = array('estatus' => 0,'msj' => $err );
		    echo json_encode($arrayerror);
		    exit();
		}
		if ($statusRequest->isInProgress() || $statusRequest->isAccepted()) {
		    $err = "<br>La solicitud {$requestId} se está procesando";
		    $arrayerror = array('estatus' => 0,'msj' => $err );
		    echo json_encode($arrayerror);
		    exit();
		    
		}*/
	
		/*if ($statusRequest->isFinished()) {
		    echo "<br>La solicitud {$requestId} está lista", PHP_EOL;
		}*/

		/*echo "Se encontraron {$verify->countPackages()} paquetes", PHP_EOL;
		foreach ($verify->getPackagesIds() as $packageId) {
		    echo " > {$packageId}", PHP_EOL;
		}*/

		// consultar el servicio de verificación
		$packagesIds = $verify->getPackagesIds();
		foreach($packagesIds as $packageId) {
		    $download = $this->service->download($packageId);
		    if (! $download->getStatus()->isAccepted()) {
		        $err = "El paquete {$packageId} no se ha podido descargar: {$download->getStatus()->getMessage()}";
		        $arrayerror = array('estatus' => 0,'msj' => $err );
		    	echo json_encode($arrayerror);
		    	
		        continue;
		    }
		    $zipfile = $url."/descargas/$packageId.zip";
		    file_put_contents($zipfile, $download->getPackageContent());
		    //echo "El paquete {$packageId} se ha almacenado", PHP_EOL;
		}
		/**
		 *  string $zipfile contiene la ruta al archivo de paquete de Metadata
		 */
		//echo '<br>';
		// abrir el archivo de Metadata
		try {
		    $metadataReader = MetadataPackageReader::createFromFile($zipfile);
		} catch (OpenZipFileException $exception) {
		    echo $exception->getMessage(), PHP_EOL;
		    return;
		}

		$url = storage_path('app');
		// leer todos los registros de metadata dentro de todos los archivos del archivo ZIP
		foreach ($metadataReader->metadata() as $uuid => $metadata) {
			$existe = Factura::where('uuid',$metadata->uuid)->get();
			$exist = $existe->count();
			if($exist=='0'){	

				if($metadata->estatus==1){
					$resReadXML = $this->guardaXMLData($url."/descargas/xmls/".$metadata->uuid.".xml");
					$res = Cliente::where('rfc', '=', $metadata->rfcReceptor)->first();
			    	if($res==null){
			    		$dataC = [
			    			'rfc' => $metadata->rfcReceptor,
			    			'nombre' => $metadata->nombreReceptor,
			    		];
			    		$clientex = Cliente::create($dataC);
			    		$clienteID = $clientex->id;
			    	}else{
			    		$clienteID = $res->id;
			    	}
					$data = [
			    		'uuid' => $metadata->uuid,
			    		'serie' => $resReadXML['serie'],
			    		'folio' => $resReadXML['folio'],
			    		'rfc_emisor' => $resReadXML['rfcEmisor'],
				    	'razon_social_emisor' => $resReadXML['razonEmisor'],
				    	'id_cliente' => $clienteID,
			    		'rfc_receptor' => $metadata->rfcReceptor,
			    		'razon_social_receptor' => $metadata->nombreReceptor,
			    		'monto' => $resReadXML['total'],
			    		//'iva' => $resReadXML['iva'],
			    		'tipo' => $metadata->efectoComprobante,
			    		'pac' => $metadata->rfcPac,
			    		'fecha_emision' => $metadata->fechaEmision,
			    		'fecha_certificacion' => $metadata->fechaCertificacionSat,
			    		'estatus' => $metadata->estatus,
			    		//'fecha_cancelacion' => $metadata->fechaCancelacion,
					];
				}else{
					$resReadXML = $this->guardaXMLData($url."/descargas/xmls/".$metadata->uuid.".xml");
					$res = Cliente::where('rfc', '=', $metadata->rfcReceptor)->first();
			    	if($res==null){
			    		$dataC = [
			    			'rfc' => $metadata->rfcReceptor,
			    			'nombre' => $metadata->nombreReceptor,
			    		];
			    		$clientex = Cliente::create($dataC);
			    		$clienteID = $clientex->id;
			    	}else{
			    		$clienteID = $res->id;
			    	}
						$data = [
				    		'uuid' => $metadata->uuid,
				    		'serie' => $resReadXML['serie'],
				    		'folio' => $resReadXML['folio'],
				    		'rfc_emisor' => $resReadXML['rfcEmisor'],
				    		'razon_social_emisor' => $resReadXML['razonEmisor'],
				    		'id_cliente' => $clienteID,
				    		'rfc_receptor' => $metadata->rfcReceptor,
				    		'razon_social_receptor' => $metadata->nombreReceptor,
				    		'monto' => $resReadXML['total'],
				    		//'iva' => $resReadXML['iva'],
				    		'tipo' => $metadata->efectoComprobante,
				    		'pac' => $metadata->rfcPac,
				    		'fecha_emision' => $metadata->fechaEmision,	
				    		'fecha_certificacion' => $metadata->fechaCertificacionSat,
				    		'estatus' => $metadata->estatus,
				    		'fecha_cancelacion' => $metadata->fechaCancelacion,
						];
				}
				Factura::insertOrIgnore($data);
			}

			
			
		}
		   $arrayerror = array('estatus' => 1,'msj' => 'Se guardaron con Exito' );
		   echo json_encode($arrayerror);

    }
    public function verifica_solicitud_xml(Request $r){
// Creación del servicio
		//$service = new Service($requestBuilder, $webClient);
		$url = storage_path('app');
		sleep(20);
		$requestId = $r->idSol;
		//echo $requestId;
		//exit();
		$verify = $this->service->verify($requestId);

			//sleep(100);
		// revisar que el proceso de verificación fue correcto
		if (! $verify->getStatus()->isAccepted()) {
		    $err = "Fallo al verificar la consulta {$requestId}: {$verify->getStatus()->getMessage()}";
		    $arrayerror = array('estatus' => 0,'msj' => $err );
		    echo json_encode($arrayerror);
		    exit();
		}

		// revisar que la consulta no haya sido rechazada
		if (! $verify->getCodeRequest()->isAccepted()) {
		    $err = "La solicitud {$requestId} fue rechazada: {$verify->getCodeRequest()->getMessage()}";
		    $arrayerror = array('estatus' => 0,'msj' => $err );
		    echo json_encode($arrayerror);
		    exit();
		    
		}

		// revisar el progreso de la generación de los paquetes
		$statusRequest = $verify->getStatusRequest();
		//dd($verify);
		//exit();
		if ($statusRequest->isExpired() || $statusRequest->isFailure() || $statusRequest->isRejected()) {
		    $err = "La solicitud {$requestId} no se puede completar";
		    $arrayerror = array('estatus' => 0,'msj' => $err );
		    echo json_encode($arrayerror);
		    exit();
		}
		if ($statusRequest->isInProgress() || $statusRequest->isAccepted()) {
		    $err = "<br>La solicitud {$requestId} se está procesando";
		    $arrayerror = array('estatus' => 0,'msj' => $err );
		    echo json_encode($arrayerror);
		    exit();
		    
		}
	
		/*if ($statusRequest->isFinished()) {
		    echo "<br>La solicitud {$requestId} está lista", PHP_EOL;
		}*/

		/*echo "Se encontraron {$verify->countPackages()} paquetes", PHP_EOL;
		foreach ($verify->getPackagesIds() as $packageId) {
		    echo " > {$packageId}", PHP_EOL;
		}*/

		// consultar el servicio de verificación
		$packagesIds = $verify->getPackagesIds();
		foreach($packagesIds as $packageId) {
		    $download = $this->service->download($packageId);
		    if (! $download->getStatus()->isAccepted()) {
		        $err = "El paquete {$packageId} no se ha podido descargar: {$download->getStatus()->getMessage()}";
		        $arrayerror = array('estatus' => 0,'msj' => $err );
		    	echo json_encode($arrayerror);
		    	
		        continue;
		    }
		    $zipfile = $url."/descargas/$packageId.zip";
		    file_put_contents($zipfile, $download->getPackageContent());
		    //echo "El paquete {$packageId} se ha almacenado", PHP_EOL;
		}
			/**
		 *  string $zipfile contiene la ruta al archivo de paquete de archivos ZIP
		 */
		try {
		    $cfdiReader = CfdiPackageReader::createFromFile($zipfile);
		} catch (OpenZipFileException $exception) {
		    echo $exception->getMessage(), PHP_EOL;
		    return;
		}

		// leer todos los CFDI dentro del archivo ZIP con el UUID como llave
		foreach ($cfdiReader->cfdis() as $uuid => $content) {
			$uuid = strtoupper($uuid);
		    file_put_contents($url."/descargas/xmls/$uuid.xml", $content);
		    //$xml = simplexml_load_file($url."/descargas/xmls/$uuid.xml");
		}
		$arrayerror = array('estatus' => 1,'msj' => 'Se descargo con Exito' );
		   echo json_encode($arrayerror);
    }
    public function getFacturasGrid(Request $r){
    	$cliente = $r->cliente;
    	$fechas = explode(' - ', $r->rango);
    	$fechaIni = date('Y-m-d', strtotime($fechas[0]));
    	$fechaIni =  $fechaIni.' 00:00:00';
    	$fechaFin = date('Y-m-d', strtotime($fechas[1]));
    	$fechaFin = $fechaFin.' 23:59:59';
    	$filtro='';
    	if($cliente!=0){
    		$filtro.="and rfc_receptor='".$cliente."' ";
    	}
    	$query = "SELECT * from cont_facturas where fecha_emision >= '".$fechaIni."' and fecha_emision <= '".$fechaFin."' ".$filtro;
        $facturas = DB::select($query);
        $facturas = $this->object_to_array($facturas);
        //dd($facturas);
        //exit();
        foreach ($facturas as $key => $value) {
        	if($value['estatus']==1){
        		$estatus = '<div align="center"><span class="badge badge-success">Activa</span></div>';
        	}else{
        		$estatus = '<div align="center"><span class="badge badge-danger">Cancelada</span></div>';
        	}
        	$facturas[$key]['estatus']= $estatus;
        	$facturas[$key]['monto']= '$'.number_format($value['monto'],2);
        	$facturas[$key]['acciones'] = '<div><button class="btn btn-info" onclick="verXml(\''.$value['uuid'].'\')">XML</button></div>';
        	$facturas[$key]['folio'] =  $value['serie'].''.$value['folio'];

        }
        $res = array('data' => $facturas);
        return response()->json($res);

    }
   public function object_to_array($data) {
        if (is_array($data) || is_object($data)) {
            $result = array();
            foreach ($data as $key => $value) {
                $result[$key] = $this->object_to_array($value);
            }
            return $result;
        }
    return $data;
    }
	public function grid(){
		$clientes = Cliente::all();
		return view('almacen.almacendigital')->with('clientes',$clientes);
	}
    public function indexAlmacen(){
    	$url = storage_path('app');
    		
		// Creación de la FIEL, puede leer archivos DER (como los envía el SAT) o PEM (convertidos con openssl)
		$fiel = Fiel::create(
		    file_get_contents($url.'/00001000000503347164.cer'),
		    file_get_contents($url.'/Claveprivada_FIEL_DIG200217HA4_20200227_120431.key'),
		    'DIG20021'
		);

		// verificar que la FIEL sea válida (no sea CSD y sea vigente acorde a la fecha del sistema)
		if (! $fiel->isValid()) {

		    return;
		}

		// creación del web client basado en Guzzle que implementa WebClientInterface
		// para usarlo necesitas instalar guzzlehttp/guzzle pues no es una dependencia directa
		$webClient = new GuzzleWebClient();

		// creación del objeto encargado de crear las solicitudes firmadas usando una FIEL
		$requestBuilder = new FielRequestBuilder($fiel);

		// Creación del servicio
		$service = new Service($requestBuilder, $webClient);
		// crear la consulta:
		// - Del 13/ene/2019 00:00:00 al 13/ene/2019 (inclusive)
		// - Todos los emitidos por el dueño de la FIEL
		// - Solicitando la información de Metadata
		// - Filtrando únicamente por los recibidos del RFC MAG041126GT8
		$request = QueryParameters::create(
		    DateTimePeriod::createFromValues('2021-01-01 12:10:01', '2021-02-10 23:49:59'),
		    DownloadType::issued(),
		    RequestType::metadata(),
		    //'MAG041126GT8'
		);

		// presentar la consulta
		$query = $service->query($request);
		//dd($query);

		// verificar que el proceso de consulta fue correcto
		if (! $query->getStatus()->isAccepted()) {
		    echo "Fallo al presentar la consulta: {$query->getStatus()->getMessage()}";
		    return;
		}

		// el identificador de la consulta está en $query->getRequestId()
		echo "<br>Se generó la solicitud {$query->getRequestId()}", PHP_EOL;
		sleep(30);
		// consultar el servicio de verificación
		$requestId =  $query->getRequestId();

		$verify = $service->verify($requestId);

		// revisar que el proceso de verificación fue correcto
		if (! $verify->getStatus()->isAccepted()) {
		    echo "Fallo al verificar la consulta {$requestId}: {$verify->getStatus()->getMessage()}";
		    return;
		}

		// revisar que la consulta no haya sido rechazada
		if (! $verify->getCodeRequest()->isAccepted()) {
		    echo "La solicitud {$requestId} fue rechazada: {$verify->getCodeRequest()->getMessage()}", PHP_EOL;
		    return;
		}
		echo '<br>';
		// revisar el progreso de la generación de los paquetes
		$statusRequest = $verify->getStatusRequest();
		//dd($statusRequest);
		//exit();
		if ($statusRequest->isExpired() || $statusRequest->isFailure() || $statusRequest->isRejected()) {
		    echo "La solicitud {$requestId} no se puede completar", PHP_EOL;
		    return;
		}
		if ($statusRequest->isInProgress() || $statusRequest->isAccepted()) {
		    echo "<br>La solicitud {$requestId} se está procesando", PHP_EOL;
		    return;
		}
		sleep(100);
		if ($statusRequest->isFinished()) {
		    echo "<br>La solicitud {$requestId} está lista", PHP_EOL;
		}

		echo "Se encontraron {$verify->countPackages()} paquetes", PHP_EOL;
		foreach ($verify->getPackagesIds() as $packageId) {
		    echo " > {$packageId}", PHP_EOL;
		}

		// consultar el servicio de verificación
		$packagesIds = $verify->getPackagesIds();
		foreach($packagesIds as $packageId) {
		    $download = $service->download($packageId);
		    if (! $download->getStatus()->isAccepted()) {
		        echo "El paquete {$packageId} no se ha podido descargar: {$download->getStatus()->getMessage()}", PHP_EOL;
		        continue;
		    }
		    $zipfile = $url."/descargas/$packageId.zip";
		    file_put_contents($zipfile, $download->getPackageContent());
		    echo "El paquete {$packageId} se ha almacenado", PHP_EOL;
		}
		/**
		 *  string $zipfile contiene la ruta al archivo de paquete de Metadata
		 */
		echo '<br>';
		// abrir el archivo de Metadata
		try {
		    $metadataReader = MetadataPackageReader::createFromFile($zipfile);
		} catch (OpenZipFileException $exception) {
		    echo $exception->getMessage(), PHP_EOL;
		    return;
		}

		// leer todos los registros de metadata dentro de todos los archivos del archivo ZIP
		foreach ($metadataReader->metadata() as $uuid => $metadata) {
			$idInsertado = DB::table('cont_facturas')->insertGetId([
	    		'uuid' => $metadata->uuid,
	    		'rfc_emisor' => $r->RfcEmisor,
	    		'razon_social_emisor' => $r->NombreEmisor,
	    		'rfc_receptor' => $metadata->RfcReceptor,
	    		'razon_social_receptor' => $metadata->NombreReceptor,
	    		'monto' => $metadata->monto,
	    		'tipo' => $metadata->EfectoComprobante,
	    		'pac' => $metadata->RfcPac,
	    		'fecha_emision' => $metadata->fechaEmision,
	    		'fecha_certificacion' => $metadata->FechaCertificacionSat,
	    		'estatus' => $metadata->Estatus,
	    		'fecha_cancelacion' => $metadata->FechaCancelacion,
			]);
		    echo $metadata->uuid, ': ', $metadata->fechaEmision.'='.$metadata->monto.'<br>', PHP_EOL;
		} 

		/**
		 *  string $zipfile contiene la ruta al archivo de paquete de archivos ZIP
		 */
		try {
		    $cfdiReader = CfdiPackageReader::createFromFile($zipfile);
		} catch (OpenZipFileException $exception) {
		    echo $exception->getMessage(), PHP_EOL;
		    return;
		}

		// leer todos los CFDI dentro del archivo ZIP con el UUID como llave
		foreach ($cfdiReader->cfdis() as $uuid => $content) {
		    file_put_contents($url."/descargas/xmls/$uuid.xml", $content);
		}
    }
    public function verificaSolicitud(){
    	$url = storage_path('app');
    		
		// Creación de la FIEL, puede leer archivos DER (como los envía el SAT) o PEM (convertidos con openssl)
		$fiel = Fiel::create(
		    file_get_contents($url.'/00001000000503347164.cer'),
		    file_get_contents($url.'/Claveprivada_FIEL_DIG200217HA4_20200227_120431.key'),
		    'DIG20021'
		);

		// verificar que la FIEL sea válida (no sea CSD y sea vigente acorde a la fecha del sistema)
		if (! $fiel->isValid()) {

		    return;
		}

		// creación del web client basado en Guzzle que implementa WebClientInterface
		// para usarlo necesitas instalar guzzlehttp/guzzle pues no es una dependencia directa
		$webClient = new GuzzleWebClient();

		// creación del objeto encargado de crear las solicitudes firmadas usando una FIEL
		$requestBuilder = new FielRequestBuilder($fiel);

		// Creación del servicio
		$service = new Service($requestBuilder, $webClient);
		$requestId = '1948a832-f30c-46b4-9bf4-3ce5131e8d9b';

		$verify = $service->verify($requestId);

			//sleep(100);
		// revisar que el proceso de verificación fue correcto
		if (! $verify->getStatus()->isAccepted()) {
		    echo "Fallo al verificar la consulta {$requestId}: {$verify->getStatus()->getMessage()}";
		    return;
		}

		// revisar que la consulta no haya sido rechazada
		if (! $verify->getCodeRequest()->isAccepted()) {
		    echo "La solicitud {$requestId} fue rechazada: {$verify->getCodeRequest()->getMessage()}", PHP_EOL;
		    return;
		}

		// revisar el progreso de la generación de los paquetes
		$statusRequest = $verify->getStatusRequest();
		dd($verify);
		/*exit();
		if ($statusRequest->isExpired() || $statusRequest->isFailure() || $statusRequest->isRejected()) {
		    echo "La solicitud {$requestId} no se puede completar", PHP_EOL;
		    return;
		}
		if ($statusRequest->isInProgress() || $statusRequest->isAccepted()) {
		    echo "<br>La solicitud {$requestId} se está procesando", PHP_EOL;
		    return;
		}
	
		if ($statusRequest->isFinished()) {
		    echo "<br>La solicitud {$requestId} está lista", PHP_EOL;
		}*/

		echo "Se encontraron {$verify->countPackages()} paquetes", PHP_EOL;
		foreach ($verify->getPackagesIds() as $packageId) {
		    echo " > {$packageId}", PHP_EOL;
		}

		// consultar el servicio de verificación
		$packagesIds = $verify->getPackagesIds();
		foreach($packagesIds as $packageId) {
		    $download = $service->download($packageId);
		    if (! $download->getStatus()->isAccepted()) {
		        echo "El paquete {$packageId} no se ha podido descargar: {$download->getStatus()->getMessage()}", PHP_EOL;
		        continue;
		    }
		    $zipfile = $url."/descargas/$packageId.zip";
		    file_put_contents($zipfile, $download->getPackageContent());
		    echo "El paquete {$packageId} se ha almacenado", PHP_EOL;
		}
		/**
		 *  string $zipfile contiene la ruta al archivo de paquete de Metadata
		 */
		echo '<br>';
		// abrir el archivo de Metadata
		try {
		    $metadataReader = MetadataPackageReader::createFromFile($zipfile);
		} catch (OpenZipFileException $exception) {
		    echo $exception->getMessage(), PHP_EOL;
		    return;
		}

		// leer todos los registros de metadata dentro de todos los archivos del archivo ZIP
		foreach ($metadataReader->metadata() as $uuid => $metadata) {
			
		    echo $metadata->uuid, ': ', $metadata->fechaEmision.'<br>', PHP_EOL;
		}

		/**
		 *  string $zipfile contiene la ruta al archivo de paquete de archivos ZIP
		 */
		try {
		    $cfdiReader = CfdiPackageReader::createFromFile($zipfile);
		} catch (OpenZipFileException $exception) {
		    echo $exception->getMessage(), PHP_EOL;
		    return;
		}

		// leer todos los CFDI dentro del archivo ZIP con el UUID como llave
		foreach ($cfdiReader->cfdis() as $uuid => $content) {
		    file_put_contents($url."/descargas/xmls/$uuid.xml", $content);
		}
    }
    public function guardaXMLData($urlXML){

    	$feed = file_get_contents($urlXML);
		$xml = simplexml_load_string($feed);
    	//$xml = simplexml_load_file($urlXML); 	
		$ns = $xml->getNamespaces(true);
		$xml->registerXPathNamespace('c', $ns['cfdi']);
		$xml->registerXPathNamespace('t', $ns['tfd']);
		 
		//EMPIEZO A LEER LA INFORMACION DEL CFDI E IMPRIMIRLA 
		foreach ($xml->xpath('//cfdi:Comprobante') as $cfdiComprobante){ 

		      if (isset($cfdiComprobante['Serie'])) {
		      		//echo $cfdiComprobante['Serie'].'--'.$cfdiComprobante['Folio']; 
		      		$serie = $cfdiComprobante['Serie'];
		      		$folio = $cfdiComprobante['Folio'];
		      }else{
		      		$serie = $cfdiComprobante['Serie'];
		      		$folio = $cfdiComprobante['Folio'];
		      }
		      $total = $cfdiComprobante['Total']; 

		}
		foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Emisor') as $Emisor){ 
		   $rfcEmisor =  $Emisor['Rfc']; 
		   $razonEmisor = $Emisor['Nombre']; 
		}
		foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Impuestos//cfdi:Traslados//cfdi:Traslado') as $Traslado){ 

		   $iva = $Traslado['importe']; 
		 
		} 
		$arrayDatos = array(
			'serie' => $serie,
			'folio' => $folio,
			'total' => $total,	
			'rfcEmisor' =>  $rfcEmisor,
			'razonEmisor' => $razonEmisor,
			//'iva' => $iva,
		);
		return $arrayDatos;
    }
    public function buscaCliente(){
    	$res = Cliente::where('rfc', '=', 'GTR160126P13')->first();
    	if($res==null){
    		echo 'no Exxiste';
    	}else{
    		echo 'es el id='.$res->id;
    	}
    	//var_dump($res);
    }
}
