<?php

/*
 Ejemplo de uso de libfacturista desde PHP en Windows
 Una DLL o Componente para generar XML, sellar y timbrar el CFDI o factura electronica
 Ariel Medina - facturista.com

 libfacturista_com.dll es un ensamblado .net expuesto a COM y
 debe registrarse con regasm.exe /tlb /codebase libfacturista_com.dll

 Crear una carpeta y colocar los archivos de libfacturista ahi
 Podria ser C:\Inetpub\wwwroot\libfacturista\

 Configurar el Apache o IIS para ejecutar archivos .php
 y asignar los permisos necesarios al usuario del servidor web
 de modo que tenga acceso a los archivos de la DLL
 
 Agregar la extension php_com_dotnet a php.ini:
 extension=php_com_dotnet.dll

 Debe contar con el framework 3.5+ de .net
 http://www.microsoft.com/es-es/download/details.aspx?id=21
*/

// Con esta funcion guardamos, sellamos y timbramos el CFDI
// Recibe el objeto libfacturista, el manejador al nodo comprobante del CFDI
// y las rutas para guardar, entre otros parametros
function guarda_sella_timbra($olf, $h, $rutaArchivoSinSello, $rutaLlavePrivada, $contrasena, $rutaCertificado, $rutaArchivoSellado, $rutaArchivoTimbrado)
{
if($olf->cfdi_xml_guardar($h,$rutaArchivoSinSello,1)!=0)
    {
    $s=file_get_contents($rutaArchivoSinSello);
    $s=str_replace("<","<",$s);
    $s=str_replace(">",">",$s);
    echo "<hr/>CFDI generado:<br/><pre>$s</pre><br/>";
    }
else
    {
    echo "<p/>Error al guardar: ".$olf->cfdi_error($h);
    }

// Aunque nuestro CFDI esta en UTF8, el intercambio de cadenas predeterminado esta en ANSI
// Por lo que si nuestra pagina la mostramos en UTF8, esta cadena se podria ver con caracteres
// raros. Al reves, si nuestra pagina esta en ANSI o ISO88591, algunos caracteres UTF8 se veran raros.
printf("<hr/>Cadena original:<br/>\n%s\n",$olf->cfdi_cadena_original($h));

if($olf->cfdi_sellar_pkcs8($h, $rutaLlavePrivada, $contrasena, $rutaCertificado, $rutaArchivoSellado,1)!=0)
	{
	$s=file_get_contents($rutaArchivoSellado);
	$s=str_replace("<","<",$s);
	$s=str_replace(">",">",$s);
	echo "<hr/>CFDI sellado:<br/><pre>$s</pre><br/>";
		
	if($olf->cfdi_timbrar($h, $rutaArchivoSellado, $rutaArchivoTimbrado, 1, "RFC=AAA010101AAA;TransaccionID=456;Servidor=pruebas.ecodex.com.mx;Puerto=2044;Sellar=1")==0)
		echo $olf->cfdi_error($h);
	else
		{
		if(($h=$olf->cfdi_xml_cargar($h,$rutaArchivoTimbrado)))
			echo "$rutaArchivoSellado ha sido timbrado, folio fiscal ".$olf->cfdi_xml_atributo($h,"cfdi:Comprobante/cfdi:Complemento/tfd:TimbreFiscalDigital","UUID");
		else
			echo "$rutaArchivoSellado ha sido timbrado pero no se pudo cargar el archivo destino $rutaArchivoTimbrado. ".$olf->cfdi_error($h);

			$s=file_get_contents($rutaArchivoTimbrado);
			$s=str_replace("<","<",$s);
			$s=str_replace(">",">",$s);
			echo "<hr/>CFDI timbrado:<br/>$s<br/>";

		}

	}
else
	{
	echo "<p/>Error al sellar: ".$olf->cfdi_error($h);
	}


}

//***** Programa principal
// Crea 2 objetos COM libfacturista para simular el acceso concurrente de 2 usuarios
// y confirmar que cada manejador a CFDI es independiente.
// Los CFDIs generados se guardan a disco, se sellan y se timbran.

$h=0;

$rutaLlavePrivada="aaa010101aaa__csd_01.key";
$contrasena="12345678a";
$rutaCertificado="aaa010101aaa__csd_01.cer";

$rutaArchivoSellado="cfdi_sellado_php.xml";
$rutaArchivoSinSello="cfdi_sinsello_php.xml";
$rutaArchivoTimbrado="cfdi_timbrado_php.xml";

$rutaArchivoSinSello2="cfdi_sinsello_php2.xml";
$rutaArchivoSellado2="cfdi_sellado_php2.xml";
$rutaArchivoTimbrado2="cfdi_timbrado_php2.xml";

// objeto libfacturista
$olf = new COM("libfacturista_com.utf16Api");
if ( !$olf )
	die("No se pudo crear el objeto");

// objeto libfacturista 2
// Aunque no es necesario crear este objeto, pues uno solo puede crear distintos manejadores
// lo creamos para simular una segunda página que está usando las funciones
// con esto confirmamos que se pueden crear cfdis de manera independiente en las páginas
// servidas por IIS o Apache
$olf2 = new COM("libfacturista_com.utf16Api");
if ( !$olf2 )
	die("No se pudo crear el objeto");

// creamos un manejador a cfdi y le agregamos el nodo comprobante
$hraiz2=$olf2->cfdi_crear();
$h2=$olf2->cfdi_comprobante_ex($hraiz2,"3.2", "B", "4321", "2013-01-12T18:43:11", "Pago en una sola exhibición", "6172.50", "12.34", "USD", "7124.75", "Efectivo", "ingreso", "Palenque, Chiapas", "3849", "Venta a credito", "10.50", "descuento por buen fin", "");

// creamos otro manejador a cfdi y le agregamos el nodo comprobante
$hraiz1=$olf->cfdi_crear();
$h=$olf->cfdi_comprobante_ex($hraiz1,"3.2", "A", "1234", "2013-01-12T18:43:11", "Pago en una sola exhibición", "6172.50", "12.34", "USD", "7124.75", "Efectivo", "ingreso", "Campeche, Campeche", "3849", "Venta a credito", "10.50", "descuento por buen fin", "");

$he=$olf->cfdi_emisor($h,"AAA010101AAA","facturista.com");
if($he==0) { printf("<p/>%s<p/>",$olf->cfdi_error($h)); return -1;}

$olf->cfdi_emisor_domicilio($he, "31", "7", "Piso 3A", "Col. Mexico", "Campeche", "Municipio de Campeche", "Campeche", "Mexico", "24000", "Por la CFE");
             
//En caso de ser una sucursal, agregamos su direccion
$olf->cfdi_emisor_expedido_en($he, "39", "8", "Depto. 25", "Col. Jalisco", "San Nicolas de los Garza", "Monterrey", "Nuevo Leon", "Mexico", "74000", "Cerca de Telmex");

$olf->cfdi_emisor_regimen($he,"Regimen General de Ley");
$olf->cfdi_emisor_regimen($he,"Otro regimen (opcional)");

// aqui creamos nodos del otro cfdi, lo hacemos aqui para
// confirmar que como son distintos manejadores, no se afectan entre sí
$he=$olf2->cfdi_emisor($h2,"AAA010101AAA","facturista.com");
$olf2->cfdi_emisor_domicilio($he, "31", "7", "Piso 3C", "Col. San José", "", "Delegacion Benito Juárez", "Distrito Federal", "Mexico", "54000", "Por Luz y Fuerza");
$olf2->cfdi_emisor_regimen($he,"Regimen intermedio de las personas físicas con actividades empresariales");
$hr=$olf2->cfdi_receptor($h2,"AAA010101AAA","Ariel Alonzo Medina Vazquez");
$olf2->cfdi_receptor_domicilio($hr,"Fundidora", "1234", "456", "Col. Escandinava", "Ciudad de los Niños", "Municipio San Nicolás", "Nuevo León", "México", "38294", "Por el cañón");


// continuamos con nuestro cfdi anterior
$hr=$olf->cfdi_receptor($h,"X&XX010101AAA","José Ángel & 'Niño' & \"Niña\"");
$olf->cfdi_receptor_domicilio($hr,"Paseo de Montejo", "1234", "456", "Col. Europea", "Ciudad de los Niños", "Municipio de Mérida", "Yucatán", "México", "38294", "Por la cascada");

$hc=$olf->cfdi_concepto($h,"10", "PZA", "1", "Memoria USB", "123.45", "1234.50");
$olf->cfdi_concepto_informacionaduanera($hc,"12345", "2011-01-01","Aduana nogales");

$hc=$olf->cfdi_concepto($h,"10", "PZA", "2", "Memoria USB", "123.45", "1234.50");
$olf->cfdi_concepto_cuentapredial($hc,"3836463729385495");

$hc=$olf->cfdi_concepto($h,"10", "PZA", "3", "Memoria USB", "123.45", "1234.50");
$olf->cfdi_concepto_parte($h,"10", "PZA", "3", "Parte 1", "123.45", "1234.50");
$olf->cfdi_concepto_parte($h,"10", "PZA", "3", "Parte 2", "123.45", "1234.50");

$hc=$olf->cfdi_concepto($h,"10", "PZA", "4", "Memoria USB", "123.45", "1234.50");
$olf->cfdi_concepto_ComplementoConcepto($hc);

$hc=$olf->cfdi_concepto($h,"10", "PZA", "5", "Memoria USB", "123.45", "1234.50");

$hi=$olf->cfdi_impuestos($h,"35.35","987.60");

$olf->cfdi_impuestos_retencion($hi,"ISR","12.12");
$olf->cfdi_impuestos_retencion($hi,"IVA","23.23");

$olf->cfdi_impuestos_traslado($hi,"IVA", "987.60", "16.00");
$olf->cfdi_impuestos_traslado($hi,"IEPS", "0.00", "0.00");

echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';

guarda_sella_timbra($olf,$h, $rutaArchivoSinSello, $rutaLlavePrivada, $contrasena, $rutaCertificado, $rutaArchivoSellado, $rutaArchivoTimbrado);

// Pasamos al otro cfdi
$hc=$olf2->cfdi_concepto($h2,"10", "PZA", "1", "Memoria USB", "123.45", "1234.50");
$olf->cfdi_concepto_informacionaduanera($hc,"12345", "2011-01-01","Aduana nogales");

$hc=$olf2->cfdi_concepto($h2,"10", "PZA", "2", "Memoria USB", "123.45", "1234.50");
$olf->cfdi_concepto_cuentapredial($hc,"3836463729385495");

$hi=$olf->cfdi_impuestos($h2,"0.00","987.60");

$olf->cfdi_impuestos_traslado($hi,"IVA", "987.60", "16.00");

guarda_sella_timbra($olf2,$h2, $rutaArchivoSinSello2, $rutaLlavePrivada, $contrasena, $rutaCertificado, $rutaArchivoSellado2, $rutaArchivoTimbrado2);

	echo "<br/><br/>Estado de cuenta de AAA010101AAA:<br/>";
	echo str_replace("\n","<br/>",$olf->cfdi_estado_cuenta($h,1,"RFC=AAA010101AAA;TransaccionID=456;Servidor=pruebas.ecodex.com.mx;Puerto=2044"))."<br/>";

echo "<br/><br/><hr/>facturista.com<br/><br/>";

echo "\n\n" . $olf->cfdis_activos() . "\n\n";
//echo $olf2->xml_serialize($h2,1);

$olf->cfdi_destruir($hraiz1);
$olf2->cfdi_destruir($hraiz2);
$olf = null;
unset($olf);
$olf2 = null;
unset($olf2);


?>