';
echo 'PROCESO DE TIMBRADO DE CFDI 3.3 CON COMPLEMENTO DE NÓMINA 1.2';
echo '';
echo '';
### 1. CONFIGURACIÓN INICIAL ######################################################
# 1.1 Configuración de zona horaria
date_default_timezone_set('America/Mexico_City');
$Fec1 = date("d/m/Y");
$Fec2 = date("Y/m/d");
$Hora = date("H:i:s");
echo $Fec1." | ".$Hora."
";
# 1.2 Muestra la zona horaria predeterminada del servidor (opcional a mostrar)
echo '
';
echo 'ZONA HORARIA PREDETERMINADA';
echo '
';
echo '
';
echo date_default_timezone_get();
echo '
';
### 2. ASIGNACIÓN DE VALORES A VARIABLES ##########################################
$SendaPEMS = "archs_pem/"; // 2.1 Directorio en donde se encuentran los archivos *.cer.pem y *.key.pem (para efectos de demostración se utilizan los que proporciona el SAT para pruebas).
$SendaCFDI = "archs_cfdi/"; // 2.2 Directorio en donde se almacenarán los archivos *.xml (CFDIs).
$SendaGRAFS = "archs_graf/"; // 2.3 Directorio en donde se almacenan los archivos .jpg (logo de la empresa) y .png (códigos bidimensionales).
// 2.5 Datos de acceso del usuario (proporcionados por www.finkok.com) modo de integración (para pruebas) o producción.
$username = "carlosrodriguez_rodriguez@hotmail.com";
$password = "Rorc760408$";
### MUESTRA LOS DATOS DEL USUARIO QUE ESTÁ TIMBRANDO (OPCIONAL A MOSTRAR) ######
echo '
';
echo 'DATOS DEL USUARIO QUE ESTÁ TIMBRANDO';
echo '
';
### 3. DEFINICIÓN DE VARIABLES INICIALES ##########################################
$noCertificado = "30001000000400002434"; // 3.1 Número de certificado.
$file_cer = "EKU9003173C9.cer.pem"; // 3.2 Nombre del archivo .cer.pem
$file_key = "EKU9003173C9.key.pem"; // 3.3 Nombre del archivo .cer.key
###################################################################################
### DATOS GENERALES DEL RECIBO DE NÓMINA ##########################################
$TipoNomina = "O"; // Clave de TipoNomina: O= Nómina ordinaria o E= Nómina extraordinaria
$RegistroPatronal = "Y3743947107"; // Registro patronal.
$fact_serie = "A"; // Número de serie.
$fact_folio = mt_rand(1000, 9999); // Número de folio.
$NoRecNom = $fact_serie.$fact_folio; // Serie del RECIBO concatenado con el número de folio.
$fact_tipcompr = "egreso"; // Tipo de comprobante.
$fecha_fact = date("Y-m-d")."T".date("H:i:s"); // Fecha y hora de facturación.
$metodoDePago = "NA"; // En nómina la clave del método de pago debe ser NA.
// $formaDePago = "PAGO EN UNA SOLA EXHIBICION"; // Forma de pago.
$TipoCambio = 1; // Tipo de cambio de la moneda.
$moneda = "MXN"; // Moneda
$TipoCambio = 1; // 4.16 Tipo de cambio de la moneda.
$LugarExpedicion = "58000"; // Lugar de expedición.
$fact_exportacion = "01"; // Atributo requerido para expresar si el comprobante ampara una operación de exportación.
$totalPercepciones = "0.00"; // Total de percepciones.
$totalDeducciones = "0.00"; // Total de deducciones.
$totalOtrosPagos = "0.00"; // Suma de otros pagos.
$Percep_TotalSueldos = "0.00"; // Percepciones, total sueldos.
$Percep_TotalGravado = "0.00"; // Percepciones, total gravado.
$Percep_TotalExento = "0.00"; // Percepciones, total exento.
$TotalOtrasDeducciones = "0.00"; // Deducciones, total otras deducciones.
$TotalImpuestosRetenidos = "0.00"; // Deducciones, toal impuestos retenidos.
$subTotal = "0.00"; // SubTotal.
$descuento = "0.00"; // descuento.
$total = "0.00"; // Total.
### No. DE CFDI ASIGNADO (CONTROL INTERNO) ######
echo '
';
echo 'No. DE CFDI';
echo '
';
echo '
';
echo $NoRecNom;
echo '
';
### 9. DATOS GENERALES DEL EMISOR #################################################
$emisor_rs = "ESCUELA KEMPER URGATE"; // 9.1 Nombre o Razón social.
$emisor_rfc = "EKU9003173C9"; // 9.2 RFC (al momento de timbrar el SAT comprueba que el RFC se encuentre registrado y vigente en su base de datos)
$emisor_ClaRegFis = "601"; // 9.3 Clave del Régimen fiscal.
### DATOS DEL EMPLEADO (RECEPTOR) ######################################################
$receptor_rfc = "MASO451221PM4"; // RFC del empleado.
$receptor_nom = "MARIA OLIVIA MARTINEZ SAGAZ"; // Nombre del empleado.
$DomicilioFiscalReceptor = "80290";
$RegimenFiscalReceptor = "605";
$UsoCFDI = "CN01";
$NumEmpleado = "001";
$CURP_Empleado = "GOVA550404MTSMLN15";
$Departamento = "SISTEMAS";
$Puesto = "PROGRAMADOR";
$NumSeguridadSocial = "43715435038";
$PeriodicidadPago = "04";
// Nomina ========================================
$FechaInicioRelLaboral = "2016-06-01"; // <======
$FechaPago = "2016-10-31";
$FechaInicialPago = "2016-10-17";
$FechaFinalPago = "2016-10-31"; // <======
$NumDiasPagados = "15";
$Antigüedad = "P21W";
$SalarioDiarioIntegrado = "304.00";
$TipoContrato = "01";
$TipoJornada = "01";
$TipoRegimen = "02";
$Banco = "012";
$CuentaBancaria = "6787543287";
$ClaveEntFed = "AGU";
$ClaveRiesgoPuesto = "1";
### MUESTRA LA ZONA HORARIA PREDETERMINADA DEL SERVIDOR (OPCIONAL A MOSTRAR) ###
echo '
';
echo 'FECHA Y HORA DE SOLICITUD DE TIMBRADO';
echo '
';
echo '
';
echo $fecha_fact; // 6.1 Se muestra solo para consultar y confirmar que sea la correcta.
echo '
';
### PERCEPCIONES ###############################################################
// ArraysPercepciones.
$ArrayPercep_Clave = ['101', '102', '114', '116', '122', '1CH', '1SC'];
$ArrayPercep_Concepto = ['SUELDO BASE', 'FONDO SOCIAL DE PREV MULT', 'COMPENSACION EXTRAORDINARIA', 'B O N O S I N D I C A L', 'D E S P E N S A', 'COMP HOMOLOG A SIMILARES PODER', 'COMPLEMENTO SALARIAL'];
$ArrayPercep_ImporteExento = ['0', '77.28', '0', '224.17', '120.72', '0', '0'];
$ArrayPercep_ImporteGravado = ['3184', '0', '1737.65', '0', '0', '125.5', '165.48'];
$ArrayPercep_TipoPercepcion = ['001', '038', '038', '038', '029', '001', '001'];
$ConceptPagNom_ValorUni = 0;
for ($i=0; $icreateElement("cfdi:Comprobante");
$root = $xml->appendChild($root);
$cadena_original='||';
$noatt= array();
#== 11.3 Rutina de integración de nodos =========================================
cargaAtt($root, array(
"Version"=>"4.0",
"Serie"=>$fact_serie,
"Folio"=>$fact_folio,
"Fecha"=>date("Y-m-d")."T".date("H:i:s"),
"NoCertificado"=>$noCertificado,
"SubTotal"=>$subTotal,
"Descuento"=>$totalDeducciones,
"Moneda"=>"MXN",
"TipoCambio"=>$TipoCambio,
"Total"=>$total,
"TipoDeComprobante"=>"N",
"Exportacion"=>$fact_exportacion,
"MetodoPago"=>"PUE",
"LugarExpedicion"=>$LugarExpedicion,
)
);
#== 11.2 Se crea e inserta el primer nodo donde se declaran los namespaces ======
cargaAttSinIntACad($root, array(
"xmlns:cfdi"=>"http://www.sat.gob.mx/cfd/4",
"xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance",
"xmlns:nomina12"=>"http://www.sat.gob.mx/nomina12",
"xsi:schemaLocation"=>"http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd http://www.sat.gob.mx/nomina12 http://www.sat.gob.mx/sitio_internet/cfd/nomina/nomina12.xsd"
)
);
################################################################################################
$emisor = $xml->createElement("cfdi:Emisor");
$emisor = $root->appendChild($emisor);
cargaAtt($emisor, array(
"Rfc"=>$emisor_rfc,
"Nombre"=>$emisor_rs,
"RegimenFiscal"=>$emisor_ClaRegFis
)
);
$receptor = $xml->createElement("cfdi:Receptor");
$receptor = $root->appendChild($receptor);
cargaAtt($receptor, array(
"Rfc"=>$receptor_rfc,
"Nombre"=>$receptor_nom,
"DomicilioFiscalReceptor"=>$DomicilioFiscalReceptor,
"RegimenFiscalReceptor"=>$RegimenFiscalReceptor,
"UsoCFDI"=>$UsoCFDI
)
);
$conceptos = $xml->createElement("cfdi:Conceptos");
$conceptos = $root->appendChild($conceptos);
$concepto = $xml->createElement("cfdi:Concepto");
$concepto = $conceptos->appendChild($concepto);
cargaAtt($concepto, array(
"ClaveProdServ"=>"84111505",
"Cantidad"=>"1",
"ClaveUnidad"=>"ACT",
"Descripcion"=>utf8_decode("Pago de nómina"),
"ValorUnitario"=>$ConceptPagNom_ValorUni,
"Importe"=>$ConceptPagNom_Importe,
"Descuento"=>$totalDeducciones,
"ObjetoImp"=>"01",
)
);
// INICIA CODIFICACIÓN DEL COMPLEMENTO DE NÓMINA 1.2 ###########################
$complemento = $xml->createElement("cfdi:Complemento");
$complemento = $root->appendChild($complemento);
$nomina = $xml->createElement("nomina12:Nomina");
$nomina = $complemento->appendChild($nomina);
cargaAtt($nomina, array(
"Version"=>"1.2",
"TipoNomina"=>"O",
"FechaPago"=>"2017-03-15",
"FechaInicialPago"=>"2017-03-01",
"FechaFinalPago"=>"2017-03-15",
"NumDiasPagados"=>"15",
"TotalPercepciones"=>$totalPercepciones,
"TotalDeducciones"=>$totalDeducciones,
"TotalOtrosPagos"=>$totalOtrosPagos
)
);
$NominaEmisor = $xml->createElement("nomina12:Emisor");
$NominaEmisor = $nomina->appendChild($NominaEmisor);
cargaAtt($NominaEmisor, array(
"RegistroPatronal"=>"C111119110-0"
)
);
// $EntidadSNCF = $xml->createElement("nomina12:EntidadSNCF");
// $EntidadSNCF = $NominaEmisor->appendChild($EntidadSNCF);
// cargaAtt($EntidadSNCF, array(
// "OrigenRecurso"=>"IP"
// )
// );
$NominaReceptor = $xml->createElement("nomina12:Receptor");
$NominaReceptor = $nomina->appendChild($NominaReceptor);
cargaAtt($NominaReceptor, array(
"Curp"=>"VAAI901027HNLRRS07",
"NumSeguridadSocial"=>"01131121161",
"FechaInicioRelLaboral"=>"2001-11-16",
"Antigüedad"=>"P799W",
"TipoContrato"=>"01",
"Sindicalizado"=>utf8_decode("Sí"),
"TipoJornada"=>"01",
"TipoRegimen"=>"02",
"NumEmpleado"=>"143712",
"Departamento"=>"Ejecutivo de Pruebas",
"Puesto"=>"CHOFER",
"RiesgoPuesto"=>"2",
"PeriodicidadPago"=>"04",
"SalarioBaseCotApor"=>"231.67",
"SalarioDiarioIntegrado"=>"428.46",
"ClaveEntFed"=>"MIC"
)
);
$percepciones = $xml->createElement("nomina12:Percepciones");
$percepciones = $nomina->appendChild($percepciones);
cargaAtt($percepciones, array(
"TotalSueldos"=>$Percep_TotalSueldos,
"TotalGravado"=>$Percep_TotalGravado,
"TotalExento"=>$Percep_TotalExento
)
);
// Ciclo "for", recopilación de datos de percepciones. ===============
for ($i=0; $icreateElement("nomina12:Percepcion");
$percepcion = $percepciones->appendChild($percepcion);
cargaAtt($percepcion, array(
"TipoPercepcion"=>$ArrayPercep_TipoPercepcion[$i],
"Clave"=>$ArrayPercep_Clave[$i],
"Concepto"=>$ArrayPercep_Concepto[$i],
"ImporteGravado"=>$ArrayPercep_ImporteGravado[$i],
"ImporteExento"=>$ArrayPercep_ImporteExento[$i]
)
);
}
if (count($ArrayDeduc_TipoDeduccion)>0){
$deducciones = $xml->createElement("nomina12:Deducciones");
$deducciones = $nomina->appendChild($deducciones);
cargaAtt($deducciones, array(
"TotalOtrasDeducciones"=>$TotalOtrasDeducciones,
"TotalImpuestosRetenidos"=>$TotalImpuestosRetenidos
)
);
// Ciclo "for", recopilación de datos de deducciones. ===============
for ($i=0; $icreateElement("nomina12:Deduccion");
$deduccion = $deducciones->appendChild($deduccion);
cargaAtt($deduccion, array(
"TipoDeduccion"=>$ArrayDeduc_TipoDeduccion[$i],
"Clave"=>$ArrayDeduc_Clave[$i],
"Concepto"=>$ArrayDeduc_Concepto[$i],
"Importe"=>$ArrayDeduc_Importe[$i]
)
);
}
}
if (count($ArrayOtrosPag_TipoOtroPago)>0){
$otrosPagos = $xml->createElement("nomina12:OtrosPagos");
$otrosPagos = $nomina->appendChild($otrosPagos);
// cargaAtt($otrosPagos, array(
// "TotalOtrosPagos"=>"100.00"
// )
// );
// Ciclo "for", recopilación de datos de deducciones. ===============
for ($i=0; $icreateElement("nomina12:OtroPago");
$otroPago = $otrosPagos->appendChild($otroPago);
cargaAtt($otroPago, array(
"TipoOtroPago"=>$ArrayOtrosPag_TipoOtroPago[$i],
"Clave"=>$ArrayOtrosPag_Clave[$i],
"Concepto"=>$ArrayOtrosPag_Concepto[$i],
"Importe"=>$ArrayOtrosPag_Importe[$i]
)
);
if ($ArrayOtrosPag_TipoOtroPago[$i]=="002"){
$SubAlEmpl = $xml->createElement("nomina12:SubsidioAlEmpleo");
$SubAlEmpl = $otroPago->appendChild($SubAlEmpl);
cargaAtt($SubAlEmpl, array("SubsidioCausado"=>$ArrayOtrosPag_Importe[$i]));
}
}
}
#== 11.6 Termina de conformarse la "Cadena original" con doble ||
$cadena_original .= "|";
// Descomentar si se desea grabar la Cadena original en un archivo.
// $file = fopen($SendaCFDI."CadenaOriginal_RecNom_".$NoRecNom.".txt", "w");
// fwrite($file, $cadena_original . PHP_EOL);
// fclose($file);
// chmod($SendaCFDI."CadenaOriginal_RecNom_".$NoRecNom.".txt", 0777);
#=== Muestra la cadena original (opcional a mostrar) =======================
echo '
';
echo 'CADENA ORIGINAL';
echo '
';
echo '
';
echo $cadena_original;
echo '
';
#== 11.8 Proceso para obtener el sello digital del archivo .pem.key ========
$keyid = openssl_get_privatekey(file_get_contents($SendaPEMS.$file_key));
openssl_sign($cadena_original, $crypttext, $keyid, OPENSSL_ALGO_SHA256);
openssl_free_key($keyid);
#== 11.9 Se convierte la cadena digital a Base 64 ==========================
$sello = base64_encode($crypttext);
#=== Muestra el sello (opcional a mostrar) =================================
echo '
';
echo 'SELLO';
echo '
';
echo '
';
echo $sello;
echo '
';
#== 11.10 Proceso para extraer el certificado del sello digital ============
$file = $SendaPEMS.$file_cer; // Ruta al archivo
$datos = file($file);
$certificado = "";
$carga=false;
for ($i=0; $i';
echo 'CERTIFICADO DEL SELLO DIGITAL';
echo '';
echo '
';
echo $certificado;
echo '
';
#== 11.12 Se continua con la integración de nodos ===========================
$root->setAttribute("Sello",$sello);
$root->setAttribute("Certificado",$certificado); # Certificado.
#== Fin de la integración de nodos =========================================
$NomArchCFDI = $SendaCFDI."PreCFDI-40_RecNom_".$NoRecNom.".xml";
#=== 11.12 Se guarda el archivo .XML antes de ser timbrado =======================
$cfdi = $xml->saveXML();
$xml->formatOutput = true;
$xml->save($NomArchCFDI); // Guarda el archivo .XML (sin timbrar) en el directorio predeterminado.
unset($xml);
#=== 11.13 Se dan permisos de escritura al archivo .xml. =========================
chmod($NomArchCFDI, 0777);
##### FIN DE LA CREACIÓN DEL ARCHIVO .XML ANTES DE SER TIMBRADO ####################################################
### 12. PROCESO DE TIMBRADO ########################################################
#=== Se muestra el .XML antes de ser timbrado (opcional a mostrar)==========
echo '
';
echo 'ARCHIVO .XML A TIMBRAR';
echo '
';
echo '
';
echo htmlspecialchars($cfdi);
echo '
';
#== 12.1 Se crea una variable de tipo DOM y se le carga el CFDI =================================
$xml2 = new DOMDocument();
$xml2->loadXML($cfdi);
#== 12.2 Convirtiendo el contenido del CFDI a BASE 64 ======================
$xml_cfdi_base64 = base64_encode($cfdi);
#== 12.3 Datos de acceso al servidor de pruebas ============================
$process = curl_init('https://demo-facturacion.finkok.com/servicios/soap/stamp.wsdl');
#== 12.4 Datos de acceso al servidor de producción =========================
# $process = curl_init('https://facturacion.finkok.com/servicios/soap/stamp.wsdl');
#== 12.5 Creando el SOAP de envío ==============================================
$cfdixml = <<$xml_cfdi_base64$username$password
XML;
#== 12.6 Proceso para guardar los datos que se envían al servidor en un archivo .XML ========================
$NomArchSoap = $SendaCFDI."SOAP_Envio_RecNom_".$NoRecNom.".xml";
#== 12.6.1 Si el archivo ya se encuentra se elimina ===========================
if (file_exists ($NomArchSoap)==true){
unlink($NomArchSoap);
}
#== 12.6.2 Se crea el archivo .XML con el SOAP ================================
# Descomentar si se desea grabar el SOAP de envío en un archivo.
// $fp = fopen($NomArchSoap,"a");
// fwrite($fp, $cfdixml);
// fclose($fp);
// chmod($NomArchSoap, 0777);
#=== 12.7 Muestra el contenido del SOAP que se envía al servidor del PAC (REQUEST) =========================
echo '
';
echo 'CONTENIDO DEL SOAP QUE SE ENVIA AL SERVIDOR DEL PAC';
echo '
';
echo '
';
echo htmlspecialchars($cfdixml);
echo '
';
#== 12.8 Se envía el contenido del SOAP al servidor del PAC =====================
curl_setopt($process, CURLOPT_HTTPHEADER, array('Content-Type: text/xml',' charset=utf-8'));
curl_setopt($process, CURLOPT_POSTFIELDS, $cfdixml);
curl_setopt($process, CURLOPT_RETURNTRANSFER, true);
curl_setopt($process, CURLOPT_POST, true);
curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($process, CURLOPT_SSL_VERIFYHOST, false);
$RespServ = curl_exec($process);
#== 12.9 Se muestra la respuesta del servidor del PAC (opcional a mostrar) ================
echo '
';
echo 'RESPUESTA DEL SERVIDOR DEL PAC';
echo '
';
echo '
';
echo htmlspecialchars($RespServ);
echo '
';
curl_close($process);
## FIN DEL PROCESO DE TIMBRADO #################################################
## 13. PROCESOS POSTERIORES AL TIMBRADO ########################################
#== 13.1 Se asigna la respuesta del servidor a una variable de tipo DOM ====
$VarXML = new DOMDocument();
$VarXML->loadXML($RespServ);
#== 13.2 Se graba la respuesta del servidor a un archivo .xml
// $VarXML->save($SendaCFDI."RespServ_RecNom_".$NoRecNom.".xml");
// chmod($SendaCFDI."RespServ_RecNom_".$NoRecNom.".xml", 0777);
echo "";
#== 13.3 Se asigna el contenido del tag "xml" a una variable ===============
$RespServ = $VarXML->getElementsByTagName('xml');
#== 13.4 Se obtiene el valor del nodo ======================================
foreach($RespServ as $Nodo){
$valor_del_nodo = $Nodo->nodeValue;
}
#== Si el nodo contiene datos se realizan los siguientes procesos ======
if($valor_del_nodo != ""){
// unlink($SendaCFDI."xlst_".$NoRecNom.".xml"); <-- Puede ser descomentado para eliminar el archivo .XML sin timbrar.
#== 13.5 Se muestra el .XML ya timbrado (CFDI V 3.2), opcional a mostrar =====
echo '
';
echo 'ARCHIVO .XML (CFDI CON COMPLEMENTO DE NÓMINA) YA TIMBRADO';
echo '
';
#=== 13.6 Guardando el CFDI en archivo .XML ============================
$NomArchXML = "CFDI-40_RecNom_".$NoRecNom.".xml";
$NomArchPDF = "CFDI-40_RecNom_".$NoRecNom.".pdf";
$xmlt = new DOMDocument();
$xmlt->loadXML($valor_del_nodo);
$xmlt->save($SendaCFDI.$NomArchXML);
chmod($SendaCFDI.$NomArchXML, 0777);
#== 13.6.1 Convertir archivo .XML a UTF-8 (OPCIONAL).
// $file_name = $SendaCFDI.$NomArchXML;
// $f = file_get_contents($file_name);
// $f = iconv("WINDOWS-1252", "UTF-8", $f);
// file_put_contents($file_name, "\xEF\xBB\xBF".$f);
#== 13.7 Procesos para extraer datos del Timbre Fiscal del CFDI =========
$docXML = new DOMDocument();
$docXML->load($SendaCFDI."CFDI-40_RecNom_".$NoRecNom.".xml");
$params = $docXML->getElementsByTagName("Comprobante");
foreach ($params as $param) {
$VersionCFDI = $param->getAttribute("Version");
}
$comprobante = $docXML->getElementsByTagName("TimbreFiscalDigital");
#== 13.8 Se obtienen contenidos de los atributos y se asignan a variables para ser mostrados =======
foreach($comprobante as $timFis){
$version_timbre = $timFis->getAttribute('Version');
$sello_SAT = $timFis->getAttribute('SelloSAT');
$cert_SAT = $timFis->getAttribute('NoCertificadoSAT');
$sello_CFD = $timFis->getAttribute('SelloCFD');
$tim_fecha = $timFis->getAttribute('FechaTimbrado');
$tim_uuid = $timFis->getAttribute('UUID');
echo 'Versión de CFDI: '.$VersionCFDI.' ';
echo 'Versión de timbre: '.$version_timbre.' ';
echo 'Sello del SAT: '.$sello_SAT.' ';
echo 'Certificado del SAT: '.$cert_SAT.' ';
echo 'Sello del CFDI: '.$sello_CFD.' ';
echo 'Fecha de timbrado: '.$tim_fecha.' ';
echo 'Folio fiscal: '.$tim_uuid.' ';
}
#== 13.8.1 Se muestra el número de factura asignado por el sistema local (no asingado por el SAT).
echo 'No. de factura asignado por el sistema local: '.$NoRecNom.'
';
echo '';
#== 13.10 Se crea código HTML para mostrar opciones al usuario.
?>
TODO supply a title
getElementsByTagName('CodigoError');
foreach($codigoError as $NodoStatus){
$valorNod = $NodoStatus->nodeValue;
}
echo '
';
echo 'CÓDIGO DE ERROR.';
echo '
';
echo '
';
echo $valorNod;
echo '
';
}
##### FIN DE PROCEDIMIENTOS ####################################################
### 14. FUNCIONES DEL MÓDULO #########################################################
# 14.1 Función que integra los nodos al archivo .XML y forma la "Cadena original".
function cargaAtt(&$nodo, $attr){
global $xml, $cadena_original;
$quitar = array('sello'=>1,'noCertificado'=>1,'certificado'=>1);
foreach ($attr as $key => $val){
$val = preg_replace('/\s\s+/', ' ', $val);
$val = trim($val);
if (strlen($val)>0){
$val = utf8_encode(str_replace("|","/",$val));
$nodo->setAttribute($key,$val);
if (!isset($quitar[$key]))
if (substr($key,0,3) != "xml" &&
substr($key,0,4) != "xsi:")
$cadena_original .= $val . "|";
}
}
}
# 14.2 Función que integra los nodos al archivo .XML sin integrar a la "Cadena original".
function cargaAttSinIntACad(&$nodo, $attr){
global $xml;
$quitar = array('sello'=>1,'noCertificado'=>1,'certificado'=>1);
foreach ($attr as $key => $val){
$val = preg_replace('/\s\s+/', ' ', $val);
$val = trim($val);
if (strlen($val)>0){
$val = utf8_encode(str_replace("|","/",$val));
$nodo->setAttribute($key,$val);
if (!isset($quitar[$key]))
if (substr($key,0,3) != "xml" &&
substr($key,0,4) != "xsi:");
}
}
}
# 14.3 Funciónes que da formato al "Importe total" como lo requiere el SAT para ser integrado al código QR.
function ProcesImpTot($ImpTot){
$ImpTot = number_format($ImpTot, 4);
$ArrayImpTot = explode(".", $ImpTot);
$NumEnt = $ArrayImpTot[0];
$NumDec = ProcesDecFac($ArrayImpTot[1]);
return $NumEnt.".".$NumDec;
}
function ProcesDecFac($Num){
$FolDec = "";
if ($Num < 10){$FolDec = "00000".$Num;}
if ($Num > 9 and $Num < 100){$FolDec = $Num."0000";}
if ($Num > 99 and $Num < 1000){$FolDec = $Num."000";}
if ($Num > 999 and $Num < 10000){$FolDec = $Num."00";}
if ($Num > 9999 and $Num < 100000){$FolDec = $Num."0";}
return $FolDec;
}