<?php 
if (!defined('BASEPATH')) exit('No direct script access allowed');


class GeneraFactura
{
	
	function facturar($infoFactura,$conceptos)
	{
		//obtenemos la fecha de la factura
		$fch = "$infoFactura->facturaFecha";
		$fecha = explode(" ",$fch);
		//variable para detectar error
		$error = false;
		//variable para detectar si solo se maneja impuesto tasa 0.160000 o tambien tasa 0.000000
		$tasa0 = false;
		$tasa16 = false;

		//iniciamos la variable de cadena_original
		$cadena_original = '';

		//creamos la cadena original
		//atributos del comprobante --->
		$cadena_original .= '||3.3|';// ||-> version *
		$cadena_original .= $infoFactura->facturaSerie.'|';// ||-> serie folio fiscal original
		$cadena_original .= $infoFactura->facturaFolio.'|';// ||-> folio fiscal original		
		$cadena_original .= $fecha[0].'T'.$fecha[1].'|';// ||-> fecha *
		$cadena_original .= $infoFactura->facturaMetodoPagoClave.'|';// ||-> forma de pago *
		/*
		formas de pago
		01 = EFECTIVO
		02 = CHEQUE NOMINATIVO
		03 = TRANSFERENCIA ELECTRONICA DE FONDOS
		04 = TARJETA DE CREDITO
		05 = MONEDERO ELECTRONICO
		06 = DINERO ELECTRONICO
		08 = VALES DE DESPENSA
		28 = TARJETA DE DEBITO
		29 = TARJETA DE SERVICIOS
		99 = POR DEFINIR
		*/
		$cadena_original .= $infoFactura->empresaCertificadoNumero.'|';// ||-> numero de certificado del emisor
		$cadena_original .= number_format($infoFactura->facturaSubtotal,2,'.','').'|';// ||-> subtotal *
		$cadena_original .= 'MXN|';// ||-> moneda
		$cadena_original .= '1|';// ||-> tipo de cambio		
		$cadena_original .= number_format($infoFactura->facturaTotal,2,'.','').'|';// ||-> total *
		$cadena_original .= 'I|';// ||-> tipo de comprobante *
		/*
		tipo de comprobante
		I = INGRESO
		E = EGRESO
		T = TRASLADO
		N = NOMINA
		P = PAGO
		*/
		$cadena_original .= $infoFactura->facturaFormaPagoClave.'|';// ||-> metodo de pago *
		/*
		metodo de pago
		PUE = PAGO EN UNA SOLA EXHIBICION
		PPD = PAGO EN PARCIALIDADES O DIFERIDO
		*/
		$cadena_original .= $infoFactura->sucursalCp.'|';// ||-> lugar de expedicion * ---> SOLO CODIGO POSTAL
				
		//$cadena_original .= '|';// ||-> condiciones de pago
		//$cadena_original .= number_format(0,2,'.','').'|';// ||-> descuento								
		//$cadena_original .= '|';// ||-> numero de cuenta
		//$cadena_original .= '|';// ||-> monto folio fiscal original
		
		
		//atributos del emisor --->
		
		$cadena_original .= $infoFactura->empresaRFC.'|';// ||-> rfc  *
		$cadena_original .= $infoFactura->empresaRazon.'|';// ||-> nombre
		//$cadena_original .= $infoFactura->empresaDireccion.'|';// ||-> calle  *
		//$cadena_original .= $infoFactura->empresaNumExt.'|';// ||-> numero exterior
		//$cadena_original .= '|';// ||-> numero interior
		//$cadena_original .= $infoFactura->empresaColonia.'|';// ||-> colonia
		//$cadena_original .= $infoFactura->empresaCiudad.'|';// ||-> localidad
		//$cadena_original .= '|';// ||-> referencia
		//$cadena_original .= $infoFactura->empresaCiudad.'|';// ||-> municipio  *
		//$cadena_original .= $infoFactura->empresaEstado.'|';// ||-> estado  *
		//$cadena_original .= 'MEXICO|';// ||-> pais  *
		//$cadena_original .= $infoFactura->empresaCp.'|';// ||-> codigo postal  *
		
		//atributos expedidoEn --->
		
		//$cadena_original .= $infoFactura->sucursalDireccion.'|';// ||-> calle  *
		//$cadena_original .= $infoFactura->sucursalNumExt.'|';// ||-> numero exterior
		//$cadena_original .= '|';// ||-> numero interior
		//$cadena_original .= $infoFactura->sucursalColonia.'|';// ||-> colonia
		//$cadena_original .= $infoFactura->sucursalCiudad.'|';// ||-> localidad
		//$cadena_original .= '|';// ||-> referencia
		//$cadena_original .= $infoFactura->sucursalCiudad.'|';// ||-> municipio  *
		//$cadena_original .= $infoFactura->sucursalEstado.'|';// ||-> estado  *
		//$cadena_original .= 'MEXICO|';// ||-> pais  *
		//$cadena_original .= $infoFactura->sucursalCp.'|';// ||-> codigo postal  *
		
		$cadena_original .= $infoFactura->empresaRegimenClave.'|';// ||-> regimen fiscal  *
		/*
		regimen fiscal
		601 = GENERAL DE LEY PERSONAS MORALES
		612 = PERSONAS FISICAS CON ACTIVIDADES EMPRESARIALES Y PROFESIONALES
		621 = INCORPORACION FISCAL
		*/		
		
		
		//atributos del receptor --->
		
		$cadena_original .= $infoFactura->clienteRFC.'|';// ||-> rfc  *
		$cadena_original .= $infoFactura->clienteRazon.'|';// ||-> nombre
		//$cadena_original .= $infoFactura->clienteDireccion.'|';// ||-> calle  *
		
		//$infoFactura->clienteNumExt != NULL ? $cadena_original .= $infoFactura->clienteNumExt.'|' : '';// ||-> numero exterior
		
		//$infoFactura->clienteNumInt != NULL ? $cadena_original .= $infoFactura->clienteNumInt.'|' : '';// ||-> numero interior
		
		//$infoFactura->clienteColonia != NULL ? $cadena_original .= $infoFactura->clienteColonia.'|' : '';// ||-> colonia
		
		//$cadena_original .= $infoFactura->clienteCiudad.'|';// ||-> localidad
		//$cadena_original .= '|';// ||-> referencia
		//$cadena_original .= $infoFactura->clienteCiudad.'|';// ||-> municipio  *
		//$cadena_original .= $infoFactura->clienteEstado.'|';// ||-> estado  *
		//$cadena_original .= 'MEXICO|';// ||-> pais  *
		
		//$infoFactura->clienteCp != NULL ? $cadena_original .= $infoFactura->clienteCp.'|' : '';// ||-> codigo postal  *	
		$cadena_original .= $infoFactura->facturaUsoCFDI.'|'; // |-> uso CFDI
		/*
		USO CFDI
		G01 = ADQUISICION DE MERCANCIAS
		G02 = DEVOLUCIONES, DESCUENTOS O BONIFICACIONES
		G03 = GASTOS EN GENERAL
		IO1 = CONSTRUCCIONES
		I02 = MOBILIARIO Y EQUIPO DE OFICINA POR INVERSIONES
		I03 = EQUIPO DE TRANSPORTE
		I04 = EQUIPO DE COMPUTO Y ACCESORIOS
		I05 = DADOS, TROQUELES, MOLDES, MATRICES Y HERRAMENTAL
		... N USOS --
		PO1 = POR DEFINIR
		*/

		//iteramos los conceptos
		foreach ($conceptos as $key => $concepto) {

			//calculamos precio unitario e importe antes de iva
			//validamos si se mostraras las partidas originales o solo la partida de facturacion
			if ($infoFactura->ventaPartidaFactura == 0) {

				//$preciou = $concepto->precio - calcularDescuento($concepto->precio,$concepto->descuento);
				$preciou = $concepto->precioUnitarioXML;
				//$importe = $preciou * $concepto->cantidad;
				$importe = $concepto->importe;
				$tasaCuota = ($concepto->partidaIVA / 100);
				//$importeImpuesto = $importe * $tasaCuota;
				$importeImpuesto = $concepto->iva;

			}else{

				$preciou = $infoFactura->facturaSubtotal;
				$importe = $preciou;
				$tasaCuota = ($concepto->partidaIVA / 100);
				$importeImpuesto = $infoFactura->facturaIVA;

			}

			$cadena_original .= $concepto->claveProductoServicio.'|'; // |->clave de producto o servicio *
			$cadena_original .= $concepto->codigob.'|';// ||-> numero de identificacion			
			$cadena_original .= number_format($concepto->cantidad,3,'.','').'|';// ||-> cantidad*
			$cadena_original .= $concepto->claveUnidad.'|'; // |->clave de unidad			
			$cadena_original .= $concepto->descripcion.'|';// ||-> descripcion*			
			$cadena_original .= number_format($preciou,2,'.','').'|';// ||-> valor unitario*
			$cadena_original .= number_format($importe,2,'.','').'|';// ||-> importe*

			// ---- informacion de traslado de conceptos Impuestos
			$cadena_original .= number_format($importe,2,'.','').'|'; // |->base*  es el importe del concepto
			$cadena_original .= '002|'; // |->Impuesto
			/*
			impuesto
			001 = ISR
			002 = IVA
			003 = IEPS
			*/
			$cadena_original .= 'Tasa|';// |->tipo factor
			/*
			TIPO FACTOR
			->TASA
			->CUOTA
			->EXCENTO
			*/
			if ($tasaCuota == 0) {
				
				$tasa0 = true;

			}else{

				$tasa16 = true;

			}

			$cadena_original .= number_format($tasaCuota,6,'.','').'|';// |->tasa cuota
			$cadena_original .= number_format($importeImpuesto,2,'.','').'|';// |->importe del impuesto

		}


		if ($tasa16 === true) {

			// informacion total de impuestos
			$cadena_original .= '002|';// ||-> nombre del impuesto*
			/*
			impuesto
			001 = ISR
			002 = IVA
			003 = IEPS
			*/
			$cadena_original .= 'Tasa|';// |->tipo factor
			/*
			TIPO FACTOR
			->TASA
			->CUOTA
			->EXCENTO
			*/
			
			$cadena_original .= '0.160000|';// |->tasa cuota
			$cadena_original .= number_format($infoFactura->facturaIVA, 2,'.','').'|';// ||-> importe*

		}

		if ($tasa0 === true) {

			// informacion total de impuestos
			$cadena_original .= '002|';// ||-> nombre del impuesto*
			/*
			impuesto
			001 = ISR
			002 = IVA
			003 = IEPS
			*/
			$cadena_original .= 'Tasa|';// |->tipo factor
			/*
			TIPO FACTOR
			->TASA
			->CUOTA
			->EXCENTO
			*/
			
			$cadena_original .= '0.000000|';// |->tasa cuota
			$cadena_original .= '0.00|';// ||-> importe*

		}

		
		$cadena_original .= number_format($infoFactura->facturaIVA, 2,'.','').'||'; // ||-> total de impuestos trasladados

		//limpiamos la cadena original de espacios y codificamos a utf8
		$cadena_original = str_replace("  "," ",$cadena_original);
		$cadena_original = utf8_decode($cadena_original);
		$cadena_original = utf8_encode($cadena_original); 


		//CERTIFICADO DIGITAL DEL CONTRIBUYENTE
		$num_certificado = $infoFactura->empresaCertificadoNumero;
				
		$archivo_cer = 'files/sellos/'.$infoFactura->empresaCertificadoNumero.'.cer';
		$certificado_texto = str_replace(array('\n', '\r'), '', base64_encode(file_get_contents($archivo_cer)));
		
		$llave = 'files/sellos/llave.key.pem';
		
		
		// == GENERACION DE SELLO DIGITAL == //
		
		$fp = fopen($llave,"r");
		$priv_key = fread($fp,8192);
		fclose($fp);
		$pkeyid = openssl_get_privatekey($priv_key);
		openssl_sign($cadena_original,$cadena_firmada,$pkeyid,OPENSSL_ALGO_SHA256);
		$sello = base64_encode($cadena_firmada);
		
		// ================================= //

		
		//creo el xml en memoria
		$cadena_xml = '';
		
		$cadena_xml .= '<?xml version="1.0" encoding="UTF-8"?>';
		$cadena_xml .= '<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd"
                                  Version="3.3"
		';
		$cadena_xml .= 'Sello="'.$sello.'"';
		$cadena_xml .= '
			 	 	  Serie="'.$infoFactura->facturaSerie.'"
					  Folio="'.$infoFactura->facturaFolio.'"
					  Fecha="'.$fecha[0].'T'.$fecha[1].'"
					  FormaPago="'.$infoFactura->facturaMetodoPagoClave.'"
					  NoCertificado="'.$num_certificado.'"
		';
		$cadena_xml .= 'Certificado="'.$certificado_texto.'"';
		$cadena_xml .= '
					  SubTotal="'.number_format($infoFactura->facturaSubtotal,2,'.','').'"					  
					  Total="'.number_format($infoFactura->facturaTotal,2,'.','').'"';


		$cadena_xml .= '
					  MetodoPago="'.$infoFactura->facturaFormaPagoClave.'"
					  TipoDeComprobante="I"
					  TipoCambio="1"
					  Moneda="MXN"
					  LugarExpedicion="'.$infoFactura->sucursalCp.'"
					  >
		';
		$cadena_xml .= '
			<cfdi:Emisor
                         Rfc="'.$infoFactura->empresaRFC.'"
                         Nombre="'.$infoFactura->empresaRazon.'"
                         RegimenFiscal="'.$infoFactura->empresaRegimenClave.'" />                         
		';
		$cadena_xml .= '
			<cfdi:Receptor
                        Rfc="'.$infoFactura->clienteRFC.'"
                        Nombre="'.$this->limpiarCaracteres($infoFactura->clienteRazon).'"
                        UsoCFDI="'.$infoFactura->facturaUsoCFDI.'" />
		';
		$cadena_xml .= '
			<cfdi:Conceptos>
		';


		foreach ($conceptos as $key => $concepto) {
			
			//calculamos precio unitario e importe antes de iva
			//validamos si se mostraras las partidas originales o solo la partida de facturacion
			if ($infoFactura->ventaPartidaFactura == 0) {

				//$preciou = $concepto->precio - calcularDescuento($concepto->precio,$concepto->descuento);
				$preciou = $concepto->precioUnitarioXML;
				//$importe = $preciou * $concepto->cantidad;
				$importe = $concepto->importe;
				$tasaCuota = ($concepto->partidaIVA / 100);
				//$importeImpuesto = $importe * $tasaCuota;
				$importeImpuesto = $concepto->iva;

			}else{

				$preciou = $infoFactura->facturaSubtotal;
				$importe = $preciou;
				$tasaCuota = ($concepto->partidaIVA / 100);
				$importeImpuesto = $infoFactura->facturaIVA;

			}

			$cadena_xml .= '
				<cfdi:Concepto 
					ClaveProdServ="'.$concepto->claveProductoServicio.'"
					ClaveUnidad="'.$concepto->claveUnidad.'"
					Cantidad="'.number_format($concepto->cantidad,3,'.','').'" 					
					NoIdentificacion="'.$concepto->codigob.'" 
					Descripcion="'.$this->limpiarCaracteres($concepto->descripcion).'" 
					ValorUnitario="'.number_format($preciou,2,'.','').'"
					Importe="'.number_format($importe,2,'.','').'">
					<cfdi:Impuestos>
						<cfdi:Traslados>
							<cfdi:Traslado Base="'.number_format($importe,2,'.','').'" Impuesto="002" TipoFactor="Tasa" TasaOCuota="'.number_format($tasaCuota,6,'.','').'" Importe="'.number_format($importeImpuesto,2,'.','').'" />
						</cfdi:Traslados>
					</cfdi:Impuestos>
				</cfdi:Concepto>
			';

		}

		$cadena_xml .= '   
                  </cfdi:Conceptos>
		';
		$cadena_xml .= '
			<cfdi:Impuestos TotalImpuestosTrasladados="'.number_format($infoFactura->facturaIVA,2,'.','').'">
                    <cfdi:Traslados>
        ';

        if ($tasa16 === true) {
        	
        	$cadena_xml .= '<cfdi:Traslado Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="'.number_format($infoFactura->facturaIVA,2,'.','').'" />';
        }

        if ($tasa0 === true) {
        	
        	$cadena_xml .= '<cfdi:Traslado Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.000000" Importe="0.00" />';

        }
        

        $cadena_xml .= '
                </cfdi:Traslados>
              </cfdi:Impuestos>
            </cfdi:Comprobante>
		';


		$cadena_xml=str_replace("  "," ",$cadena_xml);
		
		//Dado que un String convencional no esta adecuado para recibir acentos, se deben interpretar esos caracteres, de la siguiente manera.
		$cadena_xml = utf8_decode($cadena_xml);					
		
						
		//Una ves que ya tengo la cadena con los acentos debidamente codificados, aplico la codificion UTF-8 al XML.
		$cadena_xml = utf8_encode($cadena_xml); 
		
		
		// ===== creamos ruta para almacenar el XML/PDF ===== --->
		
		
		//descomponemos la fecha, para almacenar los archivos en el directorio correcto, ..\AÑO\MES\ aqui los archivos
		$fc = explode("-",$fecha[0]);//$fc[0]=año, $fc[1]=mes


		//creamos el nombre de la carpeta de la empresa con el rfc
		$folder_factura = $infoFactura->empresaRFC;

		//validamos si existe la carpeta con el rfc de la empresa, sino la cremos
		if(!file_exists('files/facturas/'.$folder_factura.'/')){
			mkdir('files/facturas/'.$folder_factura.'/',0777);
		}
		
		//crear folder de clientes en caso de no existir
		if(!file_exists('files/facturas/'.$folder_factura.'/clientes/')){
			mkdir('files/facturas/'.$folder_factura.'/clientes/',0777);
		}
		
		//crear folder del año en caso de no existir
		if(!file_exists('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/')){
			mkdir('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/',0777);
		}
		
		
		//crear folder del mes en caso de no existir
		if(!file_exists('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/'.$fc[1].'/')){
			mkdir('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/'.$fc[1].'/',0777);
		}
		
		$ruta_xml = 'files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/'.$fc[1].'/'.$infoFactura->facturaSerie.$infoFactura->facturaFolio;
		// ==================================================
		
		
		//Se guarda el XML con el siguiente nombre.
		$new_xml = fopen ($ruta_xml.".xml", "w");
		fwrite($new_xml,$cadena_xml);
		fclose($new_xml);

		//covertimos a zip
		$zip = new ZipArchive();
		$zip_file = $ruta_xml.".zip";
		$zip->open($zip_file, ZipArchive::CREATE);
		$zip->addFile($ruta_xml.".xml",$infoFactura->facturaSerie.$infoFactura->facturaFolio.".xml");
		$zip->close();

		// == TIMBRADO == //
		$wsdl="https://sat.sifei.com.mx:8443/SIFEI/SIFEI?wsdl";

        $file = base64_encode(file_get_contents($ruta_xml.".zip"));

        $parametros=array("Usuario"=>"$infoFactura->sifeiUsuario","Password"=>"$infoFactura->sifeiPassword","archivoXMLZip"=>$file,"Serie"=>" ","IdEquipo"=>"$infoFactura->sifeiIdEquipo");

		
        $client= new nusoap_client($wsdl,true);

        $rst=$client->call('getCFDI',$parametros);

	
		//borramos el archivo ZIP
		unlink($ruta_xml.".zip");
		
		
		 //verificar que no causo algun error
        if(isset($rst['detail']['SifeiException']['message'])){
			
			//unlink($ruta_xml.".xml");//borramos el archivo XML creado

			$error["codigoError"] = $rst['detail']['SifeiException']['codigo'];
			$error["error"] = true;
			  
        }elseif($rst==""){
			
			unlink($ruta_xml.".xml");//borramos el archivo XML creado

            $error["codigoError"] = 999;
            $error["error"] = true;
				
        }else{	// |-> si no causo error genera la factura


        	unlink($ruta_xml.".xml");//borramos el archivo XML creado
			
			$timbre = base64_decode($rst["return"]);//decodificamos respuesta
			
			//creamos un ZIP con el XML dentro del ZIP
			$new_xml = fopen ($ruta_xml.".zip", "w");
			fwrite($new_xml,$timbre);
			fclose($new_xml);
			
			$zip = new ZipArchive;
			if ($zip->open($ruta_xml.".zip") === TRUE) {

				$name = $zip->getNameIndex(0);
				$zip->extractTo('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/'.$fc[1].'/');
				$zip->close();
				
				unlink($ruta_xml.".zip");
				
				rename('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/'.$fc[1].'/'.$name,$ruta_xml.".xml");

				//leemos XML para extraer informacion generada por el PAC
				$load_xml = simplexml_load_file($ruta_xml.'.xml');
				$ns = $load_xml->getNamespaces(true);
				
				$load_xml->registerXPathNamespace('t', $ns['tfd']);
				 
				foreach ($load_xml->xpath('//t:TimbreFiscalDigital') as $tfd) {

					$uuid = "{$tfd['UUID']}";
					$selloSAT = "{$tfd['SelloSAT']}";
					$certificadoSAT = "{$tfd['NoCertificadoSAT']}";
					$sellocfd = "{$tfd['SelloCFD']}";
					$fechaTimbradoS = "{$tfd['FechaTimbrado']}";
					$fechaTimbrado = "{$tfd['FechaTimbrado']}";
					$fechaTimbrado = str_replace("T"," ",$fechaTimbrado);

				}	
				
				
				//generamos la cadena original del complemento de certificacion del sat
				$cadena_original_sat = '||1.0|';
				$cadena_original_sat .= $uuid.'|';
				$cadena_original_sat .= $fechaTimbradoS.'|';
				$cadena_original_sat .= $sellocfd.'|';
				$cadena_original_sat .= $certificadoSAT.'||';

				//generamos el codigo qr2 y lo guardamos en el servidor al terminar lo borramos
				$texto_qr2 = '?re='.$infoFactura->empresaRFC.'&rr='.$infoFactura->clienteRFC.'&tt='.$infoFactura->facturaTotal.'&id='.$uuid;
				QRcode::png($texto_qr2, 'temp/qr2.png');

			}

        	// ============== GENERAMOS PDF ==================
			$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

			// remove default header/footer
			$pdf->setPrintHeader(false);
			$pdf->setPrintFooter(false);
			
			// set default monospaced font
			$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
			
			// set margins
			$pdf->SetMargins("10", "10", "10");
			
			// set auto page breaks
			$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
			
			// set image scale factor
			$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
			
			// set some language-dependent strings (optional)
			if (@file_exists(dirname(__FILE__).'/lang/eng.php')) {
				require_once(dirname(__FILE__).'/lang/eng.php');
				$pdf->setLanguageArray($l);
			}
			
			// set font
			$pdf->SetFont('', '', 7);
			
			// add a page
			$pdf->AddPage();
			
			$html = '<table width="670" border="0" cellspacing="0" cellpadding="0">
			  <tr>
				<td><table width="100%" border="0" cellspacing="10" cellpadding="0">
				  <tr>
					<td width="'.$infoFactura->medidas[0].'%" valign="top"><img src="'.base_url("assets/images/logo_cotiza.jpg").'" width="'.$infoFactura->medidas[3].'" /></td>
					<td width="'.$infoFactura->medidas[1].'%" valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
					  <tr align="center">
						<td><strong>'.$infoFactura->empresaRazon.'</strong></td>
					  </tr>
					  <tr align="center">
						<td>'.$infoFactura->empresaDireccion.' No. Ext. '.$infoFactura->empresaNumExt;

						if ($infoFactura->empresaNumInt != '' && $infoFactura->empresaNumInt != NULL) {
							
							$html .= ', No. Int '.$infoFactura->empresaNumInt;

						}

						$html .= '
						, '.$infoFactura->empresaColonia.'</td>
					  </tr>
					  <tr align="center">
						<td>C.P. '.$infoFactura->empresaCp.', '.$infoFactura->empresaCiudad.', '.$infoFactura->empresaEstado.'</td>
					  </tr>
					  <tr align="center">
						<td>RFC: '.$infoFactura->empresaRFC.'</td>
					  </tr>
					  <tr align="center">
					  	<td>'.$infoFactura->empresaRegimenClave.' - '.$infoFactura->empresaRegimenNombre.'</td>
					  </tr>
					</table></td>
					<td width="'.$infoFactura->medidas[2].'%" valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
					  <tr>
						<td align="center"><span style="color:red;">FACTURA '.$infoFactura->facturaSerie.$infoFactura->facturaFolio.'</span></td>
					  </tr>
					  <tr>
						<td align="center"><span style="color:blue;">Fecha/Hora</span></td>
					  </tr>
					  <tr>
						<td align="center"><span style="color:blue;">Certificación</span></td>
					  </tr>
					  <tr>
						<td align="center">'.$fechaTimbrado.'</td>
					  </tr>
					  <tr>
						<td align="center"><span style="color:blue;">Fecha de Emisión</span></td>
					  </tr>
					  <tr>
						<td align="center">'.$fecha[0].' '.$fecha[1].'</td>
					  </tr>
					  <tr>
						<td align="center"><span style="color:blue;">Tipo de Comprobante</span></td>
					  </tr>
					  <tr>
						<td align="center">I - Ingreso</td>
					  </tr>
					  <tr>
						<td align="center"><span style="color:blue;">Lugar de Expedicion</span></td>
					  </tr>
					  <tr>
						<td align="center">'.$infoFactura->sucursalCp.'</td>
					  </tr>
					</table></td>
				  </tr>
				</table></td>
			  </tr>
			  <tr>	
				<td>&nbsp;</td>
			  </tr>
			  <tr>
				<td><table width="100%" border="0" cellspacing="10" cellpadding="0">
				  <tr>
					<td width="36%" valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
					  <tr>
						<td><span style="color:blue;">Receptor del comprobante fiscal</span></td>
					  </tr>
					  <tr>
						<td>&nbsp;</td>
					  </tr>
					  <tr>
						<td><strong>'.$infoFactura->clienteRazon.'</strong></td>
					  </tr>
					  <tr>
						<td>'.$infoFactura->clienteDireccion;

						if($infoFactura->clienteNumExt != '' && $infoFactura->clienteNumExt != NULL && $infoFactura->clienteNumExt != 0){
							
							$html .= ', No. Ext. '.$infoFactura->clienteNumExt;

						}
						
						if($infoFactura->clienteNumInt != '' && $infoFactura->clienteNumInt != NULL){

							$html .= ', No. Int. '.$infoFactura->clienteNumInt;

						}
						
						$html .= '
						, '.$infoFactura->clienteColonia.',</td>
					  </tr>
					  <tr>
						<td>C.P. '.$infoFactura->clienteCp.', '.$infoFactura->clienteCiudad.', '.$infoFactura->clienteEstado.', México</td>
					  </tr>
					  <tr>
						<td>RFC: '.$infoFactura->clienteRFC.'</td>
					  </tr>
					  <tr>
					  	<td><strong>Uso CFDI: </strong>'.$infoFactura->facturaUsoCFDI.' - '.$infoFactura->facturaUsoCFDInombre.'</td>
					  </tr>
					</table></td>
					<td width="32%" valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
					  <tr>
						<td>&nbsp;</td>
					  </tr>
					  <tr>
						<td>&nbsp;</td>
					  </tr>					  
					</table></td>
					<td width="32%" valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
					  <tr>
						<td align="center"><span style="color:blue;">Folio Fiscal</span></td>
					  </tr>
					  <tr>
						<td align="center">'.$uuid.'</td>
					  </tr>
					  <tr>
						<td align="center">&nbsp;</td>
					  </tr>
					  <tr>
						<td align="center"><span style="color:blue;">Numero de Serie del Certificado</span></td>
					  </tr>
					  <tr>
						<td align="center">'.$num_certificado.'</td>
					  </tr>
					  <tr>
						<td align="center">&nbsp;</td>
					  </tr>
					  <tr>
						<td align="center"><span style="color:blue;">Numero de Serie del Certificado del SAT</span></td>
					  </tr>
					  <tr>
						<td align="center">'.$certificadoSAT.'</td>
					  </tr>
					</table></td>
				  </tr>
				</table></td>
			  </tr>
			   ';


				  
			   		// Aqui se incluyen los comentarios de la venta
			  $html .= '
					<tr>
						<td>'.$infoFactura->ventaComentarios.'</td>
					</tr>
				';
					

			  
			  $html .= '
			  <tr>
				<td>&nbsp;</td>
			  </tr>
			  <tr>
				<td><table width="100%" border="0" cellspacing="2" cellpadding="3" style="border:#CCC solid 1px; border-radius:5px;">
				  <tr style="background-color:#EBEBEB;">				  	
					<td width="8%" align="center"><strong style="color:#00F;">Cantidad</strong></td>					
					<td width="14%" align="center">
						<strong style="color:#00F;">ClaveProdServ</strong><br>
						<strong style="color:#00F;">Clave unidad</strong><br>
						<strong style="color:#00F;">No. Identificacion</strong>
					</td>
					<td width="'.$infoFactura->porcentajeDescripcion.'%" align="center"><strong style="color:#00F;">Descripción</strong></td>
					<td width="13%" align="center"><strong style="color:#00F;">Valor Unitario</strong></td>
				';


				// == campos dinamicos == 
				if ($infoFactura->camposDinamicos !== false){

					foreach ($infoFactura->camposDinamicos as $key => $campo){

						if (in_array($campo->venta_campos_cot_id, $infoFactura->camposVenta)){

							$html .= '<td width="8%" align="center"><strong style="color:#00F;">'.$campo->venta_campos_cot_nombre.'</strong></td>';

						}

					}

				}


				$html .= '
					<td width="13%" align="center"><strong style="color:#00F;">Impuesto</strong></td>
					<td width="12%" align="center"><strong style="color:#00F;">Importe</strong></td>
				  </tr>';
				  
				  
				  //==== productos
				  
				  
				foreach ($conceptos as $key => $concepto) {

					//calculamos precio unitario e importe antes de iva
					//validamos si se mostraras las partidas originales o solo la partida de facturacion
					if ($infoFactura->ventaPartidaFactura == 0) {
						//$preciou = $concepto->precio - calcularDescuento($concepto->precio,$concepto->descuento);
						$preciou = $concepto->precioUnitario;
						//$importe = $preciou * $concepto->cantidad;
						$importe = $concepto->importe;

					}else{

						$preciou = $infoFactura->facturaSubtotal;
						$importe = $preciou;

					}
					
					$html .= '
						<tr>						
						<td align="center">'.$concepto->cantidad.'</td>												
						<td align="center">'.$concepto->claveProductoServicio.'<br>'.$concepto->claveUnidad.'<br>'.$concepto->codigob.'</td>
						<td align="center">'.$concepto->descripcion.'</td>
						<td align="center">$ '.number_format($preciou,2).'</td>
					';

					// == campos dinamicos ==
					if ($infoFactura->camposDinamicos !== false){

						foreach ($infoFactura->camposDinamicos as $key => $campo){

							if (in_array($campo->venta_campos_cot_id, $infoFactura->camposVenta)){

								$html .= '<td align="center">';

								//aqui traemos la informacion de los campos adicionales
                                $primerNivel = explode("||", $concepto->camposCotizacion);

                                foreach ($primerNivel as $key => $Pnivel) {
                                    
                                    $segundoNivel = explode("@", $Pnivel);

                                    if ($segundoNivel[0] == $campo->venta_campos_cot_id) {
                                        
                                        $html .= $segundoNivel[1]; 

                                    }

                                }

                                $html .= '</td>';

							}

						}

					}                


					if ($infoFactura->ventaPartidaFactura == 0) {

						$html .= '<td align="center">002-IVA | $ '.number_format($concepto->iva,2).'</td>';
						
					}else{

						$html .= '<td align="center">002-IVA | $ '.number_format($infoFactura->facturaIVA,2).'</td>';

					}

					$html .= '
						<td align="center">$ '.number_format($importe,2).'</td>
					  	</tr>
					';
					
					
					if($concepto->comentario !='' && $concepto->comentario != NULL){
			
						$comentario = nl2br($concepto->comentario);
						
						$html .= '
							<tr>								
								<td colspan="2" align="right"><strong>Comentarios:</strong></td>
								<td align="justify" colspan="3">'.$comentario.'</td>
								<td></td>								
							</tr>
						';
						
					}

				}

				  
				$html .= '</table></td>
			  </tr>
			  <tr>
				<td><table width="100%" border="0" cellspacing="10" cellpadding="0">
				  <tr>
					<td width="65%" valign="top"><table width="100%" border="0" cellspacing="10" cellpadding="0">
					  <tr>
						<td><strong>Moneda: </strong>MXN - Peso Mexicano</td>
					  </tr>
					  <tr>
						<td><strong>Forma de pago: </strong>'.$infoFactura->facturaMetodoPago.'</td>
					  </tr>
					  <tr>
						<td><strong>Metodo de Pago: </strong>'.$infoFactura->facturaFormaPagoClave.' - '.$infoFactura->facturaFormaPago.'</td>
					  </tr>
					  <tr>
						<td><strong>Importe Total con letra: </strong>( '.$infoFactura->facturaTotalLetras.' )</td>
					  </tr>
					</table></td>
					<td width="35%" valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
					  <tr>
						<td colspan="2" align="center"><strong style="color:#00F;">&nbsp;</strong></td>
						</tr>
					  <tr>
						<td width="70%">Subtotal</td>
						<td width="30%" align="right">$ '.number_format($infoFactura->facturaSubtotal,2).'</td>
					  </tr>
					  <tr>
						<td>Total Impuestos Trasladados</td>
						<td align="right">$ '.number_format($infoFactura->facturaIVA,2).'</td>
					  </tr>
					  <tr>
						<td>&nbsp;</td>
						<td>&nbsp;</td>
					  </tr>
					  <tr>
						<td>&nbsp;</td>
						<td>&nbsp;</td>
					  </tr>
					  <tr>
						<td colspan="2"><hr></td>
						</tr>
					  <tr>
						<td>Total Comprobante</td>
						<td align="right">$ '.number_format($infoFactura->facturaTotal,2).'</td>
					  </tr>
					</table></td>
				  </tr>
				</table></td>
			  </tr>
			  <tr>
				<td><table width="100%" border="0" cellspacing="10" cellpadding="0">
				  <tr>
					<td><strong style="color:blue;">Cadena original del complemento de certificación digital del SAT</strong></td>
				  </tr>
				  <tr>
					<td>'.$cadena_original_sat.'</td>
				  </tr>
				</table></td>
			  </tr>
			  <tr>
				<td>&nbsp;</td>
			  </tr>
			  <tr>
				<td><table width="100%" border="0" cellspacing="10" cellpadding="0">
				  <tr>
					<td width="20%" rowspan="4" valign="top"><img src="temp/qr2.png" width="120" /></td>
					<td width="80%" valign="top"><strong style="color:blue;">Sello Digital del CFDI</strong></td>
				  </tr>
				  <tr>
					<td valign="top">'.$sellocfd.'</td>
				  </tr>
				  <tr>
					<td valign="top"><strong style="color:blue;">Sello digital del SAT</strong></td>
				  </tr>
				  <tr>
					<td valign="top">'.$selloSAT.'</td>
				  </tr>
				</table></td>
			  </tr>
			  <tr>
				<td>&nbsp;</td>
			  </tr>
			  <tr>
				<td>&nbsp;</td>
			  </tr>
			  <tr>
				<td>&nbsp;</td>
			  </tr>    
			  <tr>
				<td align="center">Este documento es una representación impresa de un CFDI</td>
			  </tr>
			</table>';
			
			// output the HTML content
			$pdf->writeHTML($html, true, false, true, false, '');
			
			//Close and output PDF document
			$pdf->Output($ruta_xml.'.pdf', 'F');
			
			//  ======== fin PDF ========

			//informacion para retornar y actualizar la factura como TImbrada
			$facturaTimbrada = array(
				"uuid"				=>	$uuid,
				"selloSAT"			=>	$selloSAT,
				"certificadoSAT"	=>	$certificadoSAT,
				"sellocfd"			=>	$sellocfd,
				"fechaTimbrado"		=>	$fechaTimbrado,
				"rutaXML"			=>	$ruta_xml.".xml",
				"rutaPDF"			=>	$ruta_xml.".pdf",
				"error"				=>	false
			);

        }
        //si existio algun error en el proceso se retorna el objeto error con el codigo de error
        //de lo contrario se retorna la informacion de la factura timbrada
        if ($error === false) {
        	
        	return $facturaTimbrada;

        }else{

        	return $error;

        }


	}

	function cancelar($infoFactura)
	{
		//ruta del archivo PFX
		$archivo_pfx = "files/sellos/CER_KEY.pfx";

		//timbrar cancelacion de factura		
		$wsdl="https://sat.sifei.com.mx:8443/SIFEI/SIFEI?wsdl";

		$file=base64_encode(file_get_contents($archivo_pfx));
	
		$parametros=array("usuarioSIFEI"=>"$infoFactura->sifeiUsuario", "passUser"=>"$infoFactura->sifeiPassword","rfc"=>"$infoFactura->empresaRFC","pfx"=>"$file","passPFX"=>"$infoFactura->sifeiPassPFX","UUIDS"=>"$infoFactura->facturaFolioFiscal");
	
		$client= new nusoap_client($wsdl,true);		
	
		$rst=$client->call('cancelaCFDI',$parametros);
	
		//verificar que no causo algun error	
		if(isset($rst['detail']['SifeiException']['message'])){
	
			return false;
	
		}elseif($rst==""){
	
			return false;
	
		}else{

			return true;
			
		}
	}

	function complementoDePago($infoPago,$documentosRelacionados)
	{
		$error = false;
		// === CONTRUCCION DE CADENA ORIGINAL === //
		$cadena_original = '';
				
		//atributos del comprobante --->
		$cadena_original .= '||3.3|';// ||-> version *
		$cadena_original .= $infoPago->pagoSerie.'|';// ||-> serie
		$cadena_original .= $infoPago->pagoFolio.'|';// ||-> folio interno
		$cadena_original .= $infoPago->fechaActualCFDI.'|';// ||-> fecha *

		$cadena_original .= $infoPago->empresaCertificadoNumero.'|';// ||-> numero de certificado del emisor
		$cadena_original .= '0|';// ||-> subtotal *
		$cadena_original .= 'XXX|';// ||-> moneda
		$cadena_original .= '0|';// ||-> total *
		$cadena_original .= 'P|';// ||-> tipo de comprobante *
		/*
		tipo de comprobante
		I = INGRESO
		E = EGRESO
		T = TRASLADO
		N = NOMINA
		P = PAGO
		*/
		$cadena_original .= $infoPago->sucursalCP.'|';// ||-> lugar de expedicion * ---> SOLO CODIGO POSTAL
				

		//atributos del emisor --->
		
		$cadena_original .= $infoPago->empresaRFC.'|';// ||-> rfc  *
		$cadena_original .= $infoPago->empresaRazon.'|';// ||-> nombre


		$cadena_original .= $infoPago->empresaRegimenFiscalClave.'|';// ||-> regimen fiscal*
		/*
		regimen fiscal
		601 = GENERAL DE LEY PERSONAS MORALES
		612 = PERSONAS FISICAS CON ACTIVIDADES EMPRESARIALES Y PROFESIONALES
		621 = INCORPORACION FISCAL
		*/				
		
		
		//atributos del receptor --->
		
		$cadena_original .= $infoPago->clienteRFC.'|';// ||-> rfc*
		$cadena_original .= $infoPago->clienteRazon.'|';// ||-> nombre

		$cadena_original .= 'P01|'; // |-> uso CFDI
		/*
		USO CFDI
		G01 = ADQUISICION DE MERCANCIAS
		G02 = DEVOLUCIONES, DESCUENTOS O BONIFICACIONES
		G03 = GASTOS EN GENERAL
		IO1 = CONSTRUCCIONES
		I02 = MOBILIARIO Y EQUIPO DE OFICINA POR INVERSIONES
		I03 = EQUIPO DE TRANSPORTE
		I04 = EQUIPO DE COMPUTO Y ACCESORIOS
		I05 = DADOS, TROQUELES, MOLDES, MATRICES Y HERRAMENTAL
		... N USOS --
		PO1 = POR DEFINIR
		*/

		$cadena_original .= '84111506|'; // |->clave de producto o servicio *
		$cadena_original .= '1|';// ||-> cantidad  *		
		$cadena_original .= 'ACT|'; // |->clave de unidad					
		$cadena_original .= 'Pago|';// ||-> descripcion  *
		$cadena_original .= '0|';// ||-> valor unitario  *
		$cadena_original .= '0|';// ||-> importe  *

		//complemento de pago
		$cadena_original .= '1.0|';//	||->version
		$cadena_original .= $infoPago->pagoFechaPagoCFDI.'|';// 	||->fecha de pago
		$cadena_original .= $infoPago->metodoPagoClave.'|';// 	||->forma de pago
		$cadena_original .= 'MXN|';// 	||->moneda
		$cadena_original .= number_format($infoPago->pagoTotal,2,".","").'|';// 	||->monto
		$cadena_original .= $infoPago->pagoNumeroOperacion.'|';// 	||->referencia

		//documentos relacionados
		foreach ($documentosRelacionados as $key => $documento) {
			
			$cadena_original .= $documento->facturaUUID.'|';
			$cadena_original .= 'MXN|';
			$cadena_original .= 'PPD|';
			$cadena_original .= '1|';
			$cadena_original .= number_format($documento->cxcTotal,2,'.','').'|';
			$cadena_original .= number_format($documento->cxcTotal,2,'.','').'|';
			$cadena_original .= '0.00|';

		}

		$cadena_original .= '|';

		
		$cadena_original = str_replace("  "," ",$cadena_original);
		$cadena_original = utf8_decode($cadena_original);									
		$cadena_original = utf8_encode($cadena_original);  
		
		// ====================================== // ||-> resultado  ->  CADENA ORIGINAL DEL DOCUMENTO


		//CERTIFICADO DIGITAL DEL CONTRIBUYENTE
		$num_certificado = $infoPago->empresaCertificadoNumero;
				
		$archivo_cer = 'files/sellos/'.$infoPago->empresaCertificadoNumero.'.cer';
		$certificado_texto = str_replace(array('\n', '\r'), '', base64_encode(file_get_contents($archivo_cer)));
		
		$llave = 'files/sellos/llave.key.pem';

		
		// == GENERACION DE SELLO DIGITAL == //
		
		$fp = fopen($llave,"r");
		$priv_key = fread($fp,8192);
		fclose($fp);
		$pkeyid = openssl_get_privatekey($priv_key);
		openssl_sign($cadena_original,$cadena_firmada,$pkeyid,OPENSSL_ALGO_SHA256);
		$sello = base64_encode($cadena_firmada);
		
		// ================================= //
		
		
		//creo el xml en memoria
		$cadena_xml = '';
		
		$cadena_xml .= '<?xml version="1.0" encoding="UTF-8"?>';
		$cadena_xml .= '<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd"
                                  Version="3.3"
		';
		$cadena_xml .= 'Sello="'.$sello.'"';
		$cadena_xml .= '
			 	 	  Serie="'.$infoPago->pagoSerie.'"
					  Folio="'.$infoPago->pagoFolio.'"
					  Fecha="'.$infoPago->fechaActualCFDI.'"					  
					  NoCertificado="'.$num_certificado.'"
		';
		$cadena_xml .= 'Certificado="'.$certificado_texto.'"';
		$cadena_xml .= '
					  SubTotal="0"					  
					  Total="0"';


		$cadena_xml .= '					  
					  TipoDeComprobante="P"					  
					  Moneda="XXX"
					  LugarExpedicion="'.$infoPago->sucursalCP.'"
					  >
		';

		$cadena_xml .= '
			<cfdi:Emisor
                         Rfc="'.$infoPago->empresaRFC.'"
                         Nombre="'.$infoPago->empresaRazon.'"
                         RegimenFiscal="'.$infoPago->empresaRegimenFiscalClave.'" />                         
		';
		$cadena_xml .= '
			<cfdi:Receptor
                        Rfc="'.$infoPago->clienteRFC.'"
                        Nombre="'.$this->limpiarCaracteres($infoPago->clienteRazon).'"
                        UsoCFDI="P01" />
		';
		$cadena_xml .= '
			<cfdi:Conceptos>
		';


		$cadena_xml .= '
			<cfdi:Concepto 
				ClaveProdServ="84111506"
				ClaveUnidad="ACT"
				Cantidad="1" 					
				Descripcion="Pago" 
				ValorUnitario="0"
				Importe="0" />
		';
				

                         
		$cadena_xml .= '   
           </cfdi:Conceptos>
		';

		$cadena_xml .= '<cfdi:Complemento>';

		$cadena_xml .= '
			<pago10:Pagos xmlns:pago10="http://www.sat.gob.mx/Pagos" Version="1.0" xsi:schemaLocation="http://www.sat.gob.mx/Pagos http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos10.xsd">
		';

		$cadena_xml .= '
				<pago10:Pago FechaPago="'.$infoPago->pagoFechaPagoCFDI.'" FormaDePagoP="'.$infoPago->metodoPagoClave.'" MonedaP="MXN" Monto="'.number_format($infoPago->pagoTotal,2,'.','').'" NumOperacion="'.$infoPago->pagoNumeroOperacion.'">
		';

		//documentos relacionados
		foreach ($documentosRelacionados as $key => $documento) {

			$cadena_xml .= '
					<pago10:DoctoRelacionado IdDocumento="'.$documento->facturaUUID.'" MonedaDR="MXN" MetodoDePagoDR="PPD" NumParcialidad="1" ImpSaldoAnt="'.$documento->cxcTotal.'" ImpPagado="'.$documento->cxcTotal.'" ImpSaldoInsoluto="0.00" />
			';

		}

		$cadena_xml .= '
				</pago10:Pago>
		';

		$cadena_xml .= '
			</pago10:Pagos>
		';

		$cadena_xml .= '</cfdi:Complemento>';

		$cadena_xml .= '</cfdi:Comprobante>';
		
		
		
				
		$cadena_xml=str_replace("  "," ",$cadena_xml);
		
		//Dado que un String convencional no esta adecuado para recibir acentos, se deben interpretar esos caracteres, de la siguiente manera.
		$cadena_xml = utf8_decode($cadena_xml);					
		
						
		//Una ves que ya tengo la cadena con los acentos debidamente codificados, aplico la codificion UTF-8 al XML.
		$cadena_xml = utf8_encode($cadena_xml); 		
		
		// ==================================================

		// ===== creamos ruta para almacenar el XML/PDF ===== --->
		
		
		//descomponemos la fecha, para almacenar los archivos en el directorio correcto, ..\AÑO\MES\ aqui los archivos
		$fc = explode("-",$infoPago->fechaActual);//$fc[0]=año, $fc[1]=mes


		//creamos el nombre de la carpeta de la empresa con el rfc
		$folder_factura = $infoPago->empresaRFC;

		//validamos si existe la carpeta con el rfc de la empresa, sino la cremos
		if(!file_exists('files/facturas/'.$folder_factura.'/')){
			mkdir('files/facturas/'.$folder_factura.'/',0777);
		}
		
		//crear folder de clientes en caso de no existir
		if(!file_exists('files/facturas/'.$folder_factura.'/clientes/')){
			mkdir('files/facturas/'.$folder_factura.'/clientes/',0777);
		}
		
		//crear folder del año en caso de no existir
		if(!file_exists('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/')){
			mkdir('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/',0777);
		}
		
		
		//crear folder del mes en caso de no existir
		if(!file_exists('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/'.$fc[1].'/')){
			mkdir('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/'.$fc[1].'/',0777);
		}
		
		$ruta_xml = 'files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/'.$fc[1].'/'.$infoPago->pagoSerie.$infoPago->pagoFolio;
		// ==================================================
		
		
		//Se guarda el XML con el siguiente nombre.
		$new_xml = fopen ($ruta_xml.".xml", "w");
		fwrite($new_xml,$cadena_xml);
		fclose($new_xml);

		//covertimos a zip
		$zip = new ZipArchive();
		$zip_file = $ruta_xml.".zip";
		$zip->open($zip_file, ZipArchive::CREATE);
		$zip->addFile($ruta_xml.".xml",$infoPago->pagoSerie.$infoPago->pagoFolio.".xml");
		$zip->close();


		// == TIMBRADO == //
		$wsdl="https://sat.sifei.com.mx:8443/SIFEI/SIFEI?wsdl";

        $file = base64_encode(file_get_contents($ruta_xml.".zip"));

        $parametros=array("Usuario"=>"$infoPago->sifeiUsuario","Password"=>"$infoPago->sifeiPassword","archivoXMLZip"=>$file,"Serie"=>" ","IdEquipo"=>"$infoPago->sifeiIdEquipo");

		
        $client= new nusoap_client($wsdl,true);

        $rst=$client->call('getCFDI',$parametros);
	
		//borramos el archivo ZIP
		unlink($ruta_xml.".zip");		
		
		 //verificar que no causo algun error
        if(isset($rst['detail']['SifeiException']['message'])){
			
			unlink($ruta_xml.".xml");//borramos el archivo XML creado

			$error["codigoError"] = $rst['detail']['SifeiException']['codigo'];
			$error["error"] = true;
			  
        }elseif($rst==""){
			
			unlink($ruta_xml.".xml");//borramos el archivo XML creado

            $error["codigoError"] = 999;
            $error["error"] = true;
				
        }else{	// |-> si no causo error genera la factura


        	unlink($ruta_xml.".xml");//borramos el archivo XML creado
			
			$timbre = base64_decode($rst["return"]);//decodificamos respuesta
			
			//creamos un ZIP con el XML dentro del ZIP
			$new_xml = fopen ($ruta_xml.".zip", "w");
			fwrite($new_xml,$timbre);
			fclose($new_xml);
			
			$zip = new ZipArchive;
			if ($zip->open($ruta_xml.".zip") === TRUE) {

				$name = $zip->getNameIndex(0);
				$zip->extractTo('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/'.$fc[1].'/');
				$zip->close();
				
				unlink($ruta_xml.".zip");
				
				rename('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/'.$fc[1].'/'.$name,$ruta_xml.".xml");

				//leemos XML para extraer informacion generada por el PAC
				$load_xml = simplexml_load_file($ruta_xml.'.xml');
				$ns = $load_xml->getNamespaces(true);
				
				$load_xml->registerXPathNamespace('t', $ns['tfd']);
				 
				foreach ($load_xml->xpath('//t:TimbreFiscalDigital') as $tfd) {

					$uuid = "{$tfd['UUID']}";
					$selloSAT = "{$tfd['SelloSAT']}";
					$certificadoSAT = "{$tfd['NoCertificadoSAT']}";
					$sellocfd = "{$tfd['SelloCFD']}";
					$fechaTimbradoS = "{$tfd['FechaTimbrado']}";
					$fechaTimbrado = "{$tfd['FechaTimbrado']}";
					$fechaTimbrado = str_replace("T"," ",$fechaTimbrado);

				}	
				
				
				//generamos la cadena original del complemento de certificacion del sat
				$cadena_original_sat = '||1.0|';
				$cadena_original_sat .= $uuid.'|';
				$cadena_original_sat .= $fechaTimbradoS.'|';
				$cadena_original_sat .= $sellocfd.'|';
				$cadena_original_sat .= $certificadoSAT.'||';


			}

		}

		if ($error === false) {
			
			//informacion para retornar y actualizar la factura como TImbrada
			$pagoTimbrado = array(
				"uuid"				=>	$uuid,
				"selloSAT"			=>	$selloSAT,
				"certificadoSAT"	=>	$certificadoSAT,
				"sellocfd"			=>	$sellocfd,
				"fechaTimbrado"		=>	$fechaTimbrado,
				"rutaXML"			=>	$ruta_xml.".xml",				
				"error"				=>	false
			);

			return $pagoTimbrado;


		}else{

			return $error;

		}


	}

	function regenerarCFDI($infoFactura,$conceptos)
	{
		//obtenemos la fecha de la factura
		$fch = "$infoFactura->facturaFecha";
		$fecha = explode(" ",$fch);
		//variable para detectar error
		$error = false;
		//variable para detectar si solo se maneja impuesto tasa 0.160000 o tambien tasa 0.000000
		$tasa0 = false;
		$tasa16 = false;

		//iniciamos la variable de cadena_original
		$cadena_original = '';

		//creamos la cadena original
		//atributos del comprobante --->
		$cadena_original .= '||3.3|';// ||-> version *
		$cadena_original .= $infoFactura->facturaSerie.'|';// ||-> serie folio fiscal original
		$cadena_original .= $infoFactura->facturaFolio.'|';// ||-> folio fiscal original		
		$cadena_original .= $fecha[0].'T'.$fecha[1].'|';// ||-> fecha *
		$cadena_original .= $infoFactura->facturaMetodoPagoClave.'|';// ||-> forma de pago *
		/*
		formas de pago
		01 = EFECTIVO
		02 = CHEQUE NOMINATIVO
		03 = TRANSFERENCIA ELECTRONICA DE FONDOS
		04 = TARJETA DE CREDITO
		05 = MONEDERO ELECTRONICO
		06 = DINERO ELECTRONICO
		08 = VALES DE DESPENSA
		28 = TARJETA DE DEBITO
		29 = TARJETA DE SERVICIOS
		99 = POR DEFINIR
		*/
		$cadena_original .= $infoFactura->empresaCertificadoNumero.'|';// ||-> numero de certificado del emisor
		$cadena_original .= number_format($infoFactura->facturaSubtotal,2,'.','').'|';// ||-> subtotal *
		$cadena_original .= 'MXN|';// ||-> moneda
		$cadena_original .= '1|';// ||-> tipo de cambio		
		$cadena_original .= number_format($infoFactura->facturaTotal,2,'.','').'|';// ||-> total *
		$cadena_original .= 'I|';// ||-> tipo de comprobante *
		/*
		tipo de comprobante
		I = INGRESO
		E = EGRESO
		T = TRASLADO
		N = NOMINA
		P = PAGO
		*/
		$cadena_original .= $infoFactura->facturaFormaPagoClave.'|';// ||-> metodo de pago *
		/*
		metodo de pago
		PUE = PAGO EN UNA SOLA EXHIBICION
		PPD = PAGO EN PARCIALIDADES O DIFERIDO
		*/
		$cadena_original .= $infoFactura->sucursalCp.'|';// ||-> lugar de expedicion * ---> SOLO CODIGO POSTAL
				
		//$cadena_original .= '|';// ||-> condiciones de pago
		//$cadena_original .= number_format(0,2,'.','').'|';// ||-> descuento								
		//$cadena_original .= '|';// ||-> numero de cuenta
		//$cadena_original .= '|';// ||-> monto folio fiscal original
		
		
		//atributos del emisor --->
		
		$cadena_original .= $infoFactura->empresaRFC.'|';// ||-> rfc  *
		$cadena_original .= $infoFactura->empresaRazon.'|';// ||-> nombre
		//$cadena_original .= $infoFactura->empresaDireccion.'|';// ||-> calle  *
		//$cadena_original .= $infoFactura->empresaNumExt.'|';// ||-> numero exterior
		//$cadena_original .= '|';// ||-> numero interior
		//$cadena_original .= $infoFactura->empresaColonia.'|';// ||-> colonia
		//$cadena_original .= $infoFactura->empresaCiudad.'|';// ||-> localidad
		//$cadena_original .= '|';// ||-> referencia
		//$cadena_original .= $infoFactura->empresaCiudad.'|';// ||-> municipio  *
		//$cadena_original .= $infoFactura->empresaEstado.'|';// ||-> estado  *
		//$cadena_original .= 'MEXICO|';// ||-> pais  *
		//$cadena_original .= $infoFactura->empresaCp.'|';// ||-> codigo postal  *
		
		//atributos expedidoEn --->
		
		//$cadena_original .= $infoFactura->sucursalDireccion.'|';// ||-> calle  *
		//$cadena_original .= $infoFactura->sucursalNumExt.'|';// ||-> numero exterior
		//$cadena_original .= '|';// ||-> numero interior
		//$cadena_original .= $infoFactura->sucursalColonia.'|';// ||-> colonia
		//$cadena_original .= $infoFactura->sucursalCiudad.'|';// ||-> localidad
		//$cadena_original .= '|';// ||-> referencia
		//$cadena_original .= $infoFactura->sucursalCiudad.'|';// ||-> municipio  *
		//$cadena_original .= $infoFactura->sucursalEstado.'|';// ||-> estado  *
		//$cadena_original .= 'MEXICO|';// ||-> pais  *
		//$cadena_original .= $infoFactura->sucursalCp.'|';// ||-> codigo postal  *
		
		$cadena_original .= $infoFactura->empresaRegimenClave.'|';// ||-> regimen fiscal  *
		/*
		regimen fiscal
		601 = GENERAL DE LEY PERSONAS MORALES
		612 = PERSONAS FISICAS CON ACTIVIDADES EMPRESARIALES Y PROFESIONALES
		621 = INCORPORACION FISCAL
		*/		
		
		
		//atributos del receptor --->
		
		$cadena_original .= $infoFactura->clienteRFC.'|';// ||-> rfc  *
		$cadena_original .= $infoFactura->clienteRazon.'|';// ||-> nombre
		//$cadena_original .= $infoFactura->clienteDireccion.'|';// ||-> calle  *
		
		//$infoFactura->clienteNumExt != NULL ? $cadena_original .= $infoFactura->clienteNumExt.'|' : '';// ||-> numero exterior
		
		//$infoFactura->clienteNumInt != NULL ? $cadena_original .= $infoFactura->clienteNumInt.'|' : '';// ||-> numero interior
		
		//$infoFactura->clienteColonia != NULL ? $cadena_original .= $infoFactura->clienteColonia.'|' : '';// ||-> colonia
		
		//$cadena_original .= $infoFactura->clienteCiudad.'|';// ||-> localidad
		//$cadena_original .= '|';// ||-> referencia
		//$cadena_original .= $infoFactura->clienteCiudad.'|';// ||-> municipio  *
		//$cadena_original .= $infoFactura->clienteEstado.'|';// ||-> estado  *
		//$cadena_original .= 'MEXICO|';// ||-> pais  *
		
		//$infoFactura->clienteCp != NULL ? $cadena_original .= $infoFactura->clienteCp.'|' : '';// ||-> codigo postal  *	
		$cadena_original .= $infoFactura->facturaUsoCFDI.'|'; // |-> uso CFDI
		/*
		USO CFDI
		G01 = ADQUISICION DE MERCANCIAS
		G02 = DEVOLUCIONES, DESCUENTOS O BONIFICACIONES
		G03 = GASTOS EN GENERAL
		IO1 = CONSTRUCCIONES
		I02 = MOBILIARIO Y EQUIPO DE OFICINA POR INVERSIONES
		I03 = EQUIPO DE TRANSPORTE
		I04 = EQUIPO DE COMPUTO Y ACCESORIOS
		I05 = DADOS, TROQUELES, MOLDES, MATRICES Y HERRAMENTAL
		... N USOS --
		PO1 = POR DEFINIR
		*/

		//iteramos los conceptos
		foreach ($conceptos as $key => $concepto) {

			//calculamos precio unitario e importe antes de iva
			//validamos si se mostraras las partidas originales o solo la partida de facturacion
			if ($infoFactura->ventaPartidaFactura == 0) {

				//$preciou = $concepto->precio - calcularDescuento($concepto->precio,$concepto->descuento);
				$preciou = $concepto->precioUnitarioXML;
				//$importe = $preciou * $concepto->cantidad;
				$importe = $concepto->importe;
				$tasaCuota = ($concepto->partidaIVA / 100);
				//$importeImpuesto = $importe * $tasaCuota;
				$importeImpuesto = $concepto->iva;

			}else{

				$preciou = $infoFactura->facturaSubtotal;
				$importe = $preciou;
				$tasaCuota = ($concepto->partidaIVA / 100);
				$importeImpuesto = $infoFactura->facturaIVA;

			}

			$cadena_original .= $concepto->claveProductoServicio.'|'; // |->clave de producto o servicio *
			$cadena_original .= $concepto->codigob.'|';// ||-> numero de identificacion			
			$cadena_original .= number_format($concepto->cantidad,3,'.','').'|';// ||-> cantidad*
			$cadena_original .= $concepto->claveUnidad.'|'; // |->clave de unidad			
			$cadena_original .= $concepto->descripcion.'|';// ||-> descripcion*			
			$cadena_original .= number_format($preciou,2,'.','').'|';// ||-> valor unitario*
			$cadena_original .= number_format($importe,2,'.','').'|';// ||-> importe*

			// ---- informacion de traslado de conceptos Impuestos
			$cadena_original .= number_format($importe,2,'.','').'|'; // |->base*  es el importe del concepto
			$cadena_original .= '002|'; // |->Impuesto
			/*
			impuesto
			001 = ISR
			002 = IVA
			003 = IEPS
			*/
			$cadena_original .= 'Tasa|';// |->tipo factor
			/*
			TIPO FACTOR
			->TASA
			->CUOTA
			->EXCENTO
			*/
			if ($tasaCuota == 0) {
				
				$tasa0 = true;

			}else{

				$tasa16 = true;

			}

			$cadena_original .= number_format($tasaCuota,6,'.','').'|';// |->tasa cuota
			$cadena_original .= number_format($importeImpuesto,2,'.','').'|';// |->importe del impuesto

		}

		// informacion total de impuestos

		$cadena_original .= '002|';// ||-> nombre del impuesto*
		/*
		impuesto
		001 = ISR
		002 = IVA
		003 = IEPS
		*/
		$cadena_original .= 'Tasa|';// |->tipo factor
		/*
		TIPO FACTOR
		->TASA
		->CUOTA
		->EXCENTO
		*/

		if ($tasa16 === true) {
			
			$cadena_original .= '0.160000|';// |->tasa cuota
			$cadena_original .= number_format($infoFactura->facturaIVA, 2,'.','').'|';// ||-> importe*

		}

		if ($tasa0 === true) {
			
			$cadena_original .= '0.000000|';// |->tasa cuota
			$cadena_original .= '0.00|';// ||-> importe*

		}

		
		$cadena_original .= number_format($infoFactura->facturaIVA, 2,'.','').'||'; // ||-> total de impuestos trasladados

		//limpiamos la cadena original de espacios y codificamos a utf8
		$cadena_original = str_replace("  "," ",$cadena_original);
		$cadena_original = utf8_decode($cadena_original);
		$cadena_original = utf8_encode($cadena_original); 
		
		
		
		// ===== creamos ruta para almacenar el XML/PDF ===== --->
		
		
		//descomponemos la fecha, para almacenar los archivos en el directorio correcto, ..\AÑO\MES\ aqui los archivos
		$fc = explode("-",$fecha[0]);//$fc[0]=año, $fc[1]=mes


		//creamos el nombre de la carpeta de la empresa con el rfc
		$folder_factura = $infoFactura->empresaRFC;

		//validamos si existe la carpeta con el rfc de la empresa, sino la cremos
		if(!file_exists('files/facturas/'.$folder_factura.'/')){
			mkdir('files/facturas/'.$folder_factura.'/',0777);
		}
		
		//crear folder de clientes en caso de no existir
		if(!file_exists('files/facturas/'.$folder_factura.'/clientes/')){
			mkdir('files/facturas/'.$folder_factura.'/clientes/',0777);
		}
		
		//crear folder del año en caso de no existir
		if(!file_exists('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/')){
			mkdir('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/',0777);
		}
		
		
		//crear folder del mes en caso de no existir
		if(!file_exists('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/'.$fc[1].'/')){
			mkdir('files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/'.$fc[1].'/',0777);
		}
		
		$ruta_xml = 'files/facturas/'.$folder_factura.'/clientes/'.$fc[0].'/'.$fc[1].'/'.$infoFactura->facturaSerie.$infoFactura->facturaFolio;
		// ==================================================

		//generamos la cadena original del complemento de certificacion del sat
		$fechaTimbradoS = str_replace("T"," ",$infoFactura->facturaFechaTimbrado);
		$cadena_original_sat = '||1.0|';
		$cadena_original_sat .= $infoFactura->facturaUUID.'|';
		$cadena_original_sat .= $fechaTimbradoS.'|';
		$cadena_original_sat .= $infoFactura->facturaSelloCFD.'|';
		$cadena_original_sat .= $infoFactura->facturaCertificadoSAT.'||';
		
		
		// ============== GENERAMOS PDF ==================
		$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

		// remove default header/footer
		$pdf->setPrintHeader(false);
		$pdf->setPrintFooter(false);
		
		// set default monospaced font
		$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
		
		// set margins
		$pdf->SetMargins("10", "10", "10");
		
		// set auto page breaks
		$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
		
		// set image scale factor
		$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
		
		// set some language-dependent strings (optional)
		if (@file_exists(dirname(__FILE__).'/lang/eng.php')) {
			require_once(dirname(__FILE__).'/lang/eng.php');
			$pdf->setLanguageArray($l);
		}
		
		// set font
		$pdf->SetFont('', '', 7);
		
		// add a page
		$pdf->AddPage();
		
		$html = '<table width="670" border="0" cellspacing="0" cellpadding="0">
		  <tr>
			<td><table width="100%" border="0" cellspacing="10" cellpadding="0">
			  <tr>
				<td width="'.$infoFactura->medidas[0].'%" valign="top"><img src="'.base_url("assets/images/logo_cotiza.jpg").'" width="'.$infoFactura->medidas[3].'" /></td>
				<td width="'.$infoFactura->medidas[1].'%" valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
				  <tr align="center">
					<td><strong>'.$infoFactura->empresaRazon.'</strong></td>
				  </tr>
				  <tr align="center">
					<td>'.$infoFactura->empresaDireccion.' No. Ext. '.$infoFactura->empresaNumExt;

					if ($infoFactura->empresaNumInt != '' && $infoFactura->empresaNumInt != NULL) {
						
						$html .= ', No. Int '.$infoFactura->empresaNumInt;

					}

					$html .= '
					, '.$infoFactura->empresaColonia.'</td>
				  </tr>
				  <tr align="center">
					<td>C.P. '.$infoFactura->empresaCp.', '.$infoFactura->empresaCiudad.', '.$infoFactura->empresaEstado.'</td>
				  </tr>
				  <tr align="center">
					<td>RFC: '.$infoFactura->empresaRFC.'</td>
				  </tr>
				  <tr align="center">
				  	<td>'.$infoFactura->empresaRegimenClave.' - '.$infoFactura->empresaRegimenNombre.'</td>
				  </tr>
				</table></td>
				<td width="'.$infoFactura->medidas[2].'%" valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
				  <tr>
					<td align="center"><span style="color:red;">FACTURA '.$infoFactura->facturaSerie.$infoFactura->facturaFolio.'</span></td>
				  </tr>
				  <tr>
					<td align="center"><span style="color:blue;">Fecha/Hora</span></td>
				  </tr>
				  <tr>
					<td align="center"><span style="color:blue;">Certificación</span></td>
				  </tr>
				  <tr>
					<td align="center">'.$infoFactura->facturaFechaTimbrado.'</td>
				  </tr>
				  <tr>
					<td align="center"><span style="color:blue;">Fecha de Emisión</span></td>
				  </tr>
				  <tr>
					<td align="center">'.$fecha[0].' '.$fecha[1].'</td>
				  </tr>
				  <tr>
					<td align="center"><span style="color:blue;">Tipo de Comprobante</span></td>
				  </tr>
				  <tr>
					<td align="center">I - Ingreso</td>
				  </tr>
				  <tr>
					<td align="center"><span style="color:blue;">Lugar de Expedicion</span></td>
				  </tr>
				  <tr>
					<td align="center">'.$infoFactura->sucursalCp.'</td>
				  </tr>
				</table></td>
			  </tr>
			</table></td>
		  </tr>
		  <tr>	
			<td>&nbsp;</td>
		  </tr>
		  <tr>
			<td><table width="100%" border="0" cellspacing="10" cellpadding="0">
			  <tr>
				<td width="36%" valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
				  <tr>
					<td><span style="color:blue;">Receptor del comprobante fiscal</span></td>
				  </tr>
				  <tr>
					<td>&nbsp;</td>
				  </tr>
				  <tr>
					<td><strong>'.$infoFactura->clienteRazon.'</strong></td>
				  </tr>
				  <tr>
					<td>'.$infoFactura->clienteDireccion;

					if($infoFactura->clienteNumExt != '' && $infoFactura->clienteNumExt != NULL && $infoFactura->clienteNumExt != 0){
						
						$html .= ', No. Ext. '.$infoFactura->clienteNumExt;

					}
					
					if($infoFactura->clienteNumInt != '' && $infoFactura->clienteNumInt != NULL){

						$html .= ', No. Int. '.$infoFactura->clienteNumInt;

					}
					
					$html .= '
					, '.$infoFactura->clienteColonia.',</td>
				  </tr>
				  <tr>
					<td>C.P. '.$infoFactura->clienteCp.', '.$infoFactura->clienteCiudad.', '.$infoFactura->clienteEstado.', México</td>
				  </tr>
				  <tr>
					<td>RFC: '.$infoFactura->clienteRFC.'</td>
				  </tr>
				  <tr>
				  	<td><strong>Uso CFDI: </strong>'.$infoFactura->facturaUsoCFDI.' - '.$infoFactura->facturaUsoCFDInombre.'</td>
				  </tr>
				</table></td>
				<td width="32%" valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
				  <tr>
					<td>&nbsp;</td>
				  </tr>
				  <tr>
					<td>&nbsp;</td>
				  </tr>					  
				</table></td>
				<td width="32%" valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
				  <tr>
					<td align="center"><span style="color:blue;">Folio Fiscal</span></td>
				  </tr>
				  <tr>
					<td align="center">'.$infoFactura->facturaUUID.'</td>
				  </tr>
				  <tr>
					<td align="center">&nbsp;</td>
				  </tr>
				  <tr>
					<td align="center"><span style="color:blue;">Numero de Serie del Certificado</span></td>
				  </tr>
				  <tr>
					<td align="center">'.$infoFactura->empresaCertificadoNumero.'</td>
				  </tr>
				  <tr>
					<td align="center">&nbsp;</td>
				  </tr>
				  <tr>
					<td align="center"><span style="color:blue;">Numero de Serie del Certificado del SAT</span></td>
				  </tr>
				  <tr>
					<td align="center">'.$infoFactura->facturaCertificadoSAT.'</td>
				  </tr>
				</table></td>
			  </tr>
			</table></td>
		  </tr>
		   ';


			  
		   		// Aqui se incluyen los comentarios de la venta
			  $html .= '
					<tr>
						<td>'.$infoFactura->ventaComentarios.'</td>
					</tr>
				';

		  
		  $html .= '
		  <tr>
			<td>&nbsp;</td>
		  </tr>
		  <tr>
			<td><table width="100%" border="0" cellspacing="2" cellpadding="3" style="border:#CCC solid 1px; border-radius:5px;">
			  <tr style="background-color:#EBEBEB;">				  	
				<td width="8%" align="center"><strong style="color:#00F;">Cantidad</strong></td>					
				<td width="14%" align="center">
					<strong style="color:#00F;">ClaveProdServ</strong><br>
					<strong style="color:#00F;">Clave unidad</strong><br>
					<strong style="color:#00F;">No. Identificacion</strong>
				</td>
				<td width="'.$infoFactura->porcentajeDescripcion.'%" align="center"><strong style="color:#00F;">Descripción</strong></td>
				<td width="13%" align="center"><strong style="color:#00F;">Valor Unitario</strong></td>
			';


			// == campos dinamicos == 
			if ($infoFactura->camposDinamicos !== false){

				foreach ($infoFactura->camposDinamicos as $key => $campo){

					if (in_array($campo->venta_campos_cot_id, $infoFactura->camposVenta)){

						$html .= '<td width="8%" align="center"><strong style="color:#00F;">'.$campo->venta_campos_cot_nombre.'</strong></td>';

					}

				}

			}


			$html .= '
				<td width="13%" align="center"><strong style="color:#00F;">Impuesto</strong></td>
				<td width="12%" align="center"><strong style="color:#00F;">Importe</strong></td>
			  </tr>';
			  
			  
			  //==== productos
			  
			  
			foreach ($conceptos as $key => $concepto) {

				//calculamos precio unitario e importe antes de iva
				//validamos si se mostraras las partidas originales o solo la partida de facturacion
				if ($infoFactura->ventaPartidaFactura == 0) {
					//$preciou = $concepto->precio - calcularDescuento($concepto->precio,$concepto->descuento);
					$preciou = $concepto->precioUnitario;
					//$importe = $preciou * $concepto->cantidad;
					$importe = $concepto->importe;

				}else{

					$preciou = $infoFactura->facturaSubtotal;
					$importe = $preciou;

				}
				
				$html .= '
					<tr>						
					<td align="center">'.$concepto->cantidad.'</td>												
					<td align="center">'.$concepto->claveProductoServicio.'<br>'.$concepto->claveUnidad.'<br>'.$concepto->codigob.'</td>
					<td align="center">'.$concepto->descripcion.'</td>
					<td align="center">$ '.number_format($preciou,2).'</td>
				';

				// == campos dinamicos ==
				if ($infoFactura->camposDinamicos !== false){

					foreach ($infoFactura->camposDinamicos as $key => $campo){

						if (in_array($campo->venta_campos_cot_id, $infoFactura->camposVenta)){

							$html .= '<td align="center">';

							//aqui traemos la informacion de los campos adicionales
                            $primerNivel = explode("||", $concepto->camposCotizacion);

                            foreach ($primerNivel as $key => $Pnivel) {
                                
                                $segundoNivel = explode("@", $Pnivel);

                                if ($segundoNivel[0] == $campo->venta_campos_cot_id) {
                                    
                                    $html .= $segundoNivel[1]; 

                                }

                            }

                            $html .= '</td>';

						}

					}

				}                


				if ($infoFactura->ventaPartidaFactura == 0) {

					$html .= '<td align="center">002-IVA | $ '.number_format($concepto->iva,2).'</td>';
					
				}else{

					$html .= '<td align="center">002-IVA | $ '.number_format($infoFactura->facturaIVA,2).'</td>';

				}

				$html .= '
					<td align="center">$ '.number_format($importe,2).'</td>
				  	</tr>
				';
				
				
				if($concepto->comentario !='' && $concepto->comentario != NULL){
		
					$comentario = nl2br($concepto->comentario);
					
					$html .= '
						<tr>								
							<td colspan="2" align="right"><strong>Comentarios:</strong></td>
							<td align="justify" colspan="3">'.$comentario.'</td>
							<td></td>								
						</tr>
					';
					
				}

			}

			  
			$html .= '</table></td>
		  </tr>
		  <tr>
			<td><table width="100%" border="0" cellspacing="10" cellpadding="0">
			  <tr>
				<td width="65%" valign="top"><table width="100%" border="0" cellspacing="10" cellpadding="0">
				  <tr>
					<td><strong>Moneda: </strong>MXN - Peso Mexicano</td>
				  </tr>
				  <tr>
					<td><strong>Forma de pago: </strong>'.$infoFactura->facturaMetodoPago.'</td>
				  </tr>
				  <tr>
					<td><strong>Metodo de Pago: </strong>'.$infoFactura->facturaFormaPagoClave.' - '.$infoFactura->facturaFormaPago.'</td>
				  </tr>
				  <tr>
					<td><strong>Importe Total con letra: </strong>( '.$infoFactura->facturaTotalLetras.' )</td>
				  </tr>
				</table></td>
				<td width="35%" valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
				  <tr>
					<td colspan="2" align="center"><strong style="color:#00F;">&nbsp;</strong></td>
					</tr>
				  <tr>
					<td width="70%">Subtotal</td>
					<td width="30%" align="right">$ '.number_format($infoFactura->facturaSubtotal,2).'</td>
				  </tr>
				  <tr>
					<td>Total Impuestos Trasladados</td>
					<td align="right">$ '.number_format($infoFactura->facturaIVA,2).'</td>
				  </tr>
				  <tr>
					<td>&nbsp;</td>
					<td>&nbsp;</td>
				  </tr>
				  <tr>
					<td>&nbsp;</td>
					<td>&nbsp;</td>
				  </tr>
				  <tr>
					<td colspan="2"><hr></td>
					</tr>
				  <tr>
					<td>Total Comprobante</td>
					<td align="right">$ '.number_format($infoFactura->facturaTotal,2).'</td>
				  </tr>
				</table></td>
			  </tr>
			</table></td>
		  </tr>
		  <tr>
			<td><table width="100%" border="0" cellspacing="10" cellpadding="0">
			  <tr>
				<td><strong style="color:blue;">Cadena original del complemento de certificación digital del SAT</strong></td>
			  </tr>
			  <tr>
				<td>'.$cadena_original_sat.'</td>
			  </tr>
			</table></td>
		  </tr>
		  <tr>
			<td>&nbsp;</td>
		  </tr>
		  <tr>
			<td><table width="100%" border="0" cellspacing="10" cellpadding="0">
			  <tr>
				<td width="20%" rowspan="4" valign="top"><img src="temp/qr2.png" width="120" /></td>
				<td width="80%" valign="top"><strong style="color:blue;">Sello Digital del CFDI</strong></td>
			  </tr>
			  <tr>
				<td valign="top">'.$infoFactura->facturaSelloCFD.'</td>
			  </tr>
			  <tr>
				<td valign="top"><strong style="color:blue;">Sello digital del SAT</strong></td>
			  </tr>
			  <tr>
				<td valign="top">'.$infoFactura->facturaSelloSAT.'</td>
			  </tr>
			</table></td>
		  </tr>
		  <tr>
			<td>&nbsp;</td>
		  </tr>
		  <tr>
			<td>&nbsp;</td>
		  </tr>
		  <tr>
			<td>&nbsp;</td>
		  </tr>    
		  <tr>
			<td align="center">Este documento es una representación impresa de un CFDI</td>
		  </tr>
		</table>';
		
		// output the HTML content
		$pdf->writeHTML($html, true, false, true, false, '');
		
		//Close and output PDF document
		$pdf->Output($ruta_xml.'.pdf', 'F');
		
		//  ======== fin PDF ========

		return true;

	}

	function limpiarCaracteres($cadena)
	{
		$search  = array("<", ">", "&", "'",'"');
	    $replace = array("&lt;", "&gt;", "&amp;", "&apos;","&quot;");
	    $final = str_replace($search, $replace, $cadena);
	    return $final;
	}

}



 ?>