sTicksAndRejections (node:internal/process/task_queues:91:21) 2025-07-16 12:43:52.340 [error] CodeExpectedError: Could not find pty 2 on pty host at I.W (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:46:6444) at I.updateTitle (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:46:1839) at s. (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:45:2938) at Object.call (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:28:4204) at gl.s (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:81498) at gl.q (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:81021) at ps.value (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:80423) at E.C (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:2373) at E.fire (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:2591) at process.C (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:24:30107) at process.emit (node:events:518:28) at emit (node:internal/child_process:949:14) at process.processTicksAndRejections (node:internal/process/task_queues:91:21) 2025-07-16 12:43:52.340 [error] CodeExpectedError: Could not find pty 2 on pty host at I.W (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:46:6444) at I.updateTitle (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:46:1839) at s. (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:45:2938) at Object.call (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:28:4204) at gl.s (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:81498) at gl.q (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:81021) at ps.value (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:80423) at E.C (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:2373) at E.fire (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:2591) at process.C (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:24:30107) at process.emit (node:events:518:28) at emit (node:internal/child_process:949:14) at process.processTicksAndRejections (node:internal/process/task_queues:91:21) 2025-07-16 12:43:52.341 [error] CodeExpectedError: Could not find pty 2 on pty host at I.W (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:46:6444) at I.updateTitle (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:46:1839) at s. (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:45:2938) at Object.call (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:28:4204) at gl.s (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:81498) at gl.q (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:81021) at ps.value (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:80423) at E.C (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:2373) at E.fire (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:26:2591) at process.C (file:///home/ubuntu/.vscode-server/cli/servers/Stable-cb0c47c0cfaad0757385834bd89d410c78a856c0/server/out/vs/platform/terminal/node/ptyHostMain.js:24:30107) at process.emit (node:events:518:28) at emit (node:internal/child_process:949:14) at process.processTicksAndRejections (node:internal/process/task_queues:91:21) 2025-07-16 14:45:01.671 [info] [][fb920f87][ManagementConnection] The client has disconnected, will wait for reconnection 3h before disposing... 2025-07-16 14:51:41.467 [info] [][fb920f87][ManagementConnection] Another client has connected, will shorten the wait for reconnection 5m before disposing... 2025-07-16 14:51:41.467 [info] [][03d7b379][ExtensionHostConnection] New connection established. 2025-07-16 14:51:41.470 [info] [][03d7b379][ExtensionHostConnection] <2862747> Launched Extension Host Process. 2025-07-16 14:51:41.496 [info] [][4b43ac95][ManagementConnection] New connection established. 2025-07-16 14:51:47.304 [info] Getting Manifest... github.copilot-chat 2025-07-16 14:51:47.394 [info] Installing extension: github.copilot-chat {"productVersion":{"version":"1.102.1","date":"2025-07-15T16:40:30.132Z"},"pinned":false,"operation":3,"isApplicationScoped":false,"donotVerifySignature":false,"context":{"clientTargetPlatform":"win32-x64"},"profileLocation":{"$mid":1,"fsPath":"/home/ubuntu/.vscode-server/extensions/extensions.json","external":"file:///home/ubuntu/.vscode-server/extensions/extensions.json","path":"/home/ubuntu/.vscode-server/extensions/extensions.json","scheme":"file"}} 2025-07-16 14:51:48.545 [info] Extension signature verification result for github.copilot-chat: Success. Internal Code: 0. Executed: true. Duration: 801ms. 2025-07-16 14:51:48.906 [info] Extracted extension to file:///home/ubuntu/.vscode-server/extensions/github.copilot-chat-0.29.1: github.copilot-chat 2025-07-16 14:51:48.918 [info] Renamed to /home/ubuntu/.vscode-server/extensions/github.copilot-chat-0.29.1 2025-07-16 14:51:48.981 [info] Extension installed successfully: github.copilot-chat file:///home/ubuntu/.vscode-server/extensions/extensions.json 2025-07-16 14:51:48.987 [info] Marked extension as removed github.copilot-chat-0.28.5 2025-07-16 14:51:48.987 [info] Marked extension as removed github.copilot-chat-0.29.0 2025-07-16 14:56:41.590 [info] [][fb920f87][ManagementConnection] The reconnection short grace time of 5m has expired, so the connection will be disposed. 2025-07-16 14:56:41.762 [info]rmat %(refname)%00%(objectname)%00%(*objectname) [2ms] 2025-07-16 12:44:10.572 [info] > git config --get commit.template [2ms] 2025-07-16 12:44:10.578 [info] > git for-each-ref --format=%(refname)%00%(upstream:short)%00%(objectname)%00%(upstream:track)%00%(upstream:remotename)%00%(upstream:remoteref) refs/heads/master refs/remotes/master [2ms] 2025-07-16 12:44:10.585 [info] > git status -z -uall [4ms] 2025-07-16 12:44:10.586 [info] > git for-each-ref --sort -committerdate --format %(refname)%00%(objectname)%00%(*objectname) [1ms] 2025-07-16 12:44:15.598 [info] > git config --get commit.template [5ms] 2025-07-16 12:44:15.598 [info] > git for-each-ref --format=%(refname)%00%(upstream:short)%00%(objectname)%00%(upstream:track)%00%(upstream:remotename)%00%(upstream:remoteref) refs/heads/master refs/remotes/master [1ms] 2025-07-16 12:44:15.606 [info] > git status -z -uall [5ms] 2025-07-16 12:44:15.606 [info] > git for-each-ref --sort -committerdate --format %(refname)%00%(objectname)%00%(*objectname) [1ms] 2025-07-16 12:44:20.618 [info] > git config --get commit.template [5ms] 2025-07-16 12:44:20.619 [info] > git for-each-ref --format=%(refname)%00%(upstream:short)%00%(objectname)%00%(upstream:track)%00%(upstream:remotename)%00%(upstream:remoteref) refs/heads/master refs/remotes/master [1ms] 2025-07-16 12:44:20.628 [info] > git status -z -uall [5ms] 2025-07-16 12:44:20.628 [info] > git for-each-ref --sort -committerdate --format %(refname)%00%(objectname)%00%(*objectname) [2ms] 2025-07-16 12:45:59.220 [info] > git rev-parse --show-toplevel [4ms] 2025-07-16 12:45:59.220 [info] fatal: not a git repository (or any of the parent directories): .git 2025-07-16 12:55:11.567 [info] > git config --get commit.template [3ms] 2025-07-16 12:55:11.568 [info] > git for-each-ref --format=%(refname)%00%(upstream:short)%00%(objectname)%00%(upstream:track)%00%(upstream:remotename)%00%(upstream:remoteref) refs/heads/master refs/remotes/master [1ms] 2025-07-16 12:55:11.576 [info] > git status -z -uall [3ms] 2025-07-16 12:55:11.577 [info] > git for-each-ref --sort -committerdate --format %(refname)%00%(objectname)%00%(*objectname) [1ms] 2025-07-16 12:55:28.518 [info] > git config --get commit.template [4ms] 2025-07-16 12:55:28.519 [info] > git for-each-ref --format=%(refname)%00%(upstream:short)%00%(objectname)%00%(upstream:track)%00%(upstream:remotename)%00%(upstream:remoteref) refs/heads/master refs/remotes/master [2ms] 2025-07-16 12:55:28.528 [info] > git status -z -uall [5ms] 2025-07-16 12:55:28.529 [info] > git for-each-ref --sort -committerdate --format %(refname)%00%(objectname)%00%(*objectname) [4ms] 2025-07-16 12:55:47.177 [info] > git rev-parse --show-toplevel [1ms] 2025-07-16 12:55:47.177 [info] fatal: not a git repository (or any of the parent directories): .git 2025-07-16 12:57:12.063 [info] > git config --get commit.template [1ms] 2025-07-16 12:57:12.068 [info] > git for-each-ref --format=%(refname)%00%(upstream:short)%00%(objectname)%00%(upstream:track)%00%(upstream:remotename)%00%(upstream:remoteref) refs/heads/master refs/remotes/master [2ms] 2025-07-16 12:57:12.075 [info] > git status -z -uall [4ms] 2025-07-16 12:57:12.075 [info] > git for-each-ref --sort -committerdate --format %(refname)%00%(objectname)%00%(*objectname) [1ms] 2025-07-16 12:57:17.085 [info] > git config --get commit.template [4ms] 2025-07-16 12:57:17.086 [info] > git for-each-ref --format=%(refname)%00%(upstream:short)%00%(objectname)%00%(upstream:track)%00%(upstream:remotename)%00%(upstream:remoteref) refs/heads/master refs/remotes/master [1ms] 2025-07-16 12:57:17.093 [info] > git status -z -uall [3ms] 2025-07-16 12:57:17.095 [info] > git for-each-ref --sort -committerdate --format %(refname)%00%(objectname)%00%(*objectname) [3ms] 2025-07-16 12:57:22.106 [info] > git config --get commit.template [5ms] 2025-07-16 12:57:22.107 [info] > git for-each-ref --format=%(refname)%00%(upstream:short)%00%(objectname)%00%(upstream:track)%00%(upstream:remotename)%00%(upstream:remoteref) refs/heads/master refs/remotes/master [1ms] 2025-07-16 12:57:22.114 [info] > git status - "300", "message" => "ERROR - [wsInvoiceSF] Parametros incompletos para el Servicio Web, faltan el Propoietario de la Aplicación"); $Resultado = json_encode($j_array); echo $Resultado; return; } if($bRecId == "") { $j_array = array('code' => "300", "message" => "ERROR - [wsInvoiceSF] Parametros incompletos para el Servicio Web, faltan el ID del CFDI a actualizar"); $Resultado = json_encode($j_array); echo $Resultado; return; } if($bDatPAC == "") { $j_array = array('code' => "300", "message" => "ERROR - [wsInvoiceSF] Parametros incompletos para el Servicio Web, faltan los Datos del PAC"); $Resultado = json_encode($j_array); echo $Resultado; return; } if($bDatGen == "") { $j_array = array('code' => "300", "message" => "ERROR - [wsInvoiceSF] Parametros incompletos para el Servicio Web, faltan los Datos Generales"); $Resultado = json_encode($j_array); echo $Resultado; return; } if($bDatEmi == "") { $j_array = array('code' => "300", "message" => "ERROR - [wsInvoiceSF] Parametros incompletos para el Servicio Web, faltan los Datos del Emisor"); $Resultado = json_encode($j_array); echo $Resultado; return; } if($bDatRec == "" or $bDatArt == "") { $j_array = array('code' => "300", "message" => "ERROR - [wsInvoiceSF] Parametros incompletos para el Servicio Web, faltan los Datos del Receptor"); $Resultado = json_encode($j_array); echo $Resultado; return; } if($bDatArt == "") { $j_array = array('code' => "300", "message" => "ERROR - [wsInvoiceSF] Parametros incompletos para el Servicio Web, faltan los Datos de los Articulos"); $Resultado = json_encode($j_array); echo $Resultado; return; } ### 0. EXTRACCION DE PARAMETROS PARA EL CFDI ###################################################### #== Primero, extraemos el JSON del string en base 64 $bdDatPAC = base64_decode($bDatPAC); $bdDatGen = base64_decode($bDatGen); $bdDatEmi = base64_decode($bDatEmi); $bdDatRec = base64_decode($bDatRec); $bdDatArt = base64_decode($bDatArt); if($bDatRel <> "") { $bdDatRel = base64_decode($bDatRel); } #== Segundo, decodificamos el JSON a un arreglo $abdDatPAC = json_decode($bdDatPAC,true); $abdDatGen = json_decode($bdDatGen,true); $abdDatEmi = json_decode($bdDatEmi,true); $abdDatRec = json_decode($bdDatRec,true); $abdDatArt = json_decode($bdDatArt,true); if($bDatRel <> "") { $abdDatRel = json_decode($bdDatRel,true); } $dirBase = realpath("../"); ### CÓDIGO FUENTE, FACTURACIÓN ELECTRÓNICA CFDI VERSIÓN 3.2 ACORDE A LOS REQUIRIMIENTOS DEL SAT, ANEXO 20. ### 1. CONFIGURACIÓN INICIAL ###################################################### # 1.1 Configuración de zona horaria date_default_timezone_set('America/Mexico_City'); // # 1.2 Muestra la zona horaria predeterminada del servidor (opcional a mostrar) ### 2. DEFINICIÓN DE CONSTANTES ################################################### $SendaPEMS = "archs_pem/"; $SendaCFDI = "archs_cfdi/"; $SendaGRAFS = "archs_graf/"; $SendaXSD = "archs_xsd/"; // 2.1 Datos de acceso del usuario (proporcionados por el PAC). if($abdDatPAC["tipoTim"] == 1){ ## Timbrado en producción $urlPAC = "https://solucionfactible.com/ws/services/Timbrado"; } else { ## Timbrado en pruebas $urlPAC = "https://testing.solucionfactible.com/ws/services/Timbrado?wsdl"; } $username = $abdDatPAC["username"]; $password = $abdDatPAC["password"]; $valorNod = ''; $metodoDePago = ""; ### MUESTRA LOS DATOS DEL USUARIO QUE ESTÁ TIMBRANDO (OPCIONAL A MOSTRAR) ###### ### 3. DEFINICIÓN DE VARIABLES INICIALES ########################################## //$noCertificado = "00001000000409970859"; //$file_cer = "00001000000409970859.cer.pem"; //$file_key = "00001000000409970859.key.pem"; $noCertificado = $abdDatGen["Certificado_SAT"]; $file_cer = $abdDatGen["Archivo_CER"]; $file_key = $abdDatGen["Archivo_KEY"]; $organi_id_ZB = $abdDatGen["organization_id_ZB"]; $authtoken_ZB = $abdDatGen["authtoken_ZB"]; $authtoken_ZC = $abdDatGen["authtoken_ZC"]; #== Datos y Variables para OAuth Token $coa_ClientId = $abdDatGen["C_OAuth_client_id"]; $coa_ClientSecret = $abdDatGen["C_OAuth_client_secret"]; $coa_RefreshToken = $abdDatGen["C_OAuth_refresh_token"]; $coa_GrantType = $abdDatGen["C_OAuth_grant_type"]; $coa_RedirectUri = $abdDatGen["C_OAuth_redirect_uri"]; $coa_AuthUrl = "https://accounts.zoho.com/oauth/v2/token"; #---------------------------------------------------------------- #== Llamado para generar el token para donatello #---------------------------------------------------------------- $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => 'https://donatello.aptuslegal.app/oauth/token/f/'.$appOwner, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => array( 'Authorization: Token e68d5a079f937ea29ad2ec5a5b105b75491a0e0c' ), )); $response = curl_exec($curl); curl_close($curl); // Decodificamos la respuesta JSON $data = json_decode($response, true); // Accedemos al valor de 'access_token de donatello' $access_token = $data['access_token']; ### 4. DESTINATARIOS DE E-MAILS, PERSONAS A QUIENES LES LLEGARÁ DE MANERA ADJUNTA LA FACTURA ELECTRÓNICA EN ARCHIVOS .XML Y .PDF $CadenaEmails = $abdDatGen["CadenaEmails"]; $CadenaEmails = "ffaccinetto@aptus-legal.com"; ### 5. DATOS GENERALES DE LA FACTURA ############################################## $fact_serie = $abdDatGen["fact_serie"]; $fact_folio = $abdDatGen["fact_folio"]; $NoFac = $fact_serie.$fact_folio; $fact_tipcompr = $abdDatGen["fact_tipcompr"]; $tasa_iva = $abdDatGen["tasa_iva"]; $subTotal = number_format($abdDatGen["subTotal"],2,'.',''); $descuento = number_format($abdDatGen["descuento"],2,'.',''); $IVA = number_format($abdDatGen["IVA"],2,'.',''); $total = number_format($abdDatGen["total"],2,'.',''); $fecha_fact = $abdDatGen["fecha_fact"]; $condicionesDePago = $abdDatGen["condicionesDePago"]; $formaDePago = utf8_decode($abdDatGen["formaDePago"]); $metodoDePago = utf8_decode($abdDatGen["metodoDePago"]); $TipoCambio = $abdDatGen["TipoCambio"]; $LugarExpedicion = utf8_decode($abdDatGen["LugarExpedicion"]); $moneda = $abdDatGen["moneda"]; $invoiceID = $abdDatGen["invoiceID"]; $invoiceNumber = $abdDatGen["invoiceNumber"]; $TipoRelacion = $abdDatGen["TipoRelacion"]; if($TipPDFGen == 1) { $sObservaciones = base64_encode(utf8_decode($abdDatGen["Observaciones"])); $sOrdenCobro = $abdDatGen["OrdenCobro"]; } $subTotal = 0; $totalImpuestosRetenidos = 0; // 5.24 Total de impuestos retenidos. $totalImpuestosTrasladados = 0; // 5.25 Total de impuestos trasladados. // Calculando subTotal, Impuestos Trasladados y Retenidos. for ($i = 0; $icreateElement("cfdi:Comprobante"); $root = $xml->appendChild($root); $cadena_original='||'; $noatt= array(); #== 10.2 Se crea e inserta el primer nodo donde se declaran los namespaces ====== cargaAtt($root, array("xsi:schemaLocation"=>"http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd", "xmlns:cfdi"=>"http://www.sat.gob.mx/cfd/4", "xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance" ) ); #== 10.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"), "FormaPago"=>$formaDePago, "NoCertificado"=>$noCertificado, "CondicionesDePago"=>$condicionesDePago, "SubTotal"=>$subTotal, "Descuento"=>$descuento, "Moneda"=>$moneda, "TipoCambio"=>$TipoCambio, "Total"=>$total, "TipoDeComprobante"=>$fact_tipcompr, "MetodoPago"=>$metodoDePago, "LugarExpedicion"=>$LugarExpedicion ) ); $emisor = $xml->createElement("cfdi:Emisor"); $emisor = $root->appendChild($emisor); cargaAtt($emisor, array("Rfc"=>$emisor_rfc, "Nombre"=>$emisor_rs, "RegimenFiscal"=>$emisor_regfis ) ); $receptor = $xml->createElement("cfdi:Receptor"); $receptor = $root->appendChild($receptor); cargaAtt($receptor, array("Rfc"=>$receptor_rfc, "Nombre"=>$receptor_rs, "DomicilioFiscalReceptor"=>$receptor_cp, "RegimenFiscalReceptor"=>$receptor_regfis, "UsoCFDI"=>$receptor_uso ) ); // Adicionado por FFR en Marzo 30, 2019 // Para el manejo de los CFDI Relacionados if($bDatRel <> "") { $cfdiRelacionados = $xml->createElement("cfdi:CfdiRelacionados"); $cfdiRelacionados = $root->appendChild($cfdiRelacionados); cargaAtt($cfdiRelacionados, array("TipoRelacion"=>utf8_decode($TipoRelacion))); for ($i=0; $i < count($abdDatRel); $i++) { $cfdiRelacionado = $xml->createElement("cfdi:cfdiRelacionado"); $cfdiRelacionado = $cfdiRelacionados->appendChild($cfdiRelacionado); cargaAtt($cfdiRelacionado, array("UUID"=>utf8_decode($abdDatRel[$i]["UUID"]))); } } $conceptos = $xml->createElement("cfdi:Conceptos"); $conceptos = $root->appendChild($conceptos); $isrImpuesto = "001"; $ivaImpuesto = "002"; $lIvaTraslad = false; $lIsrRetenid = false; #== 10.4 Ciclo "for", recopilación de datos de artículos e integración de sus respectivos nodos = $ivaTasaOCuota = 0.160000; for ($i=0; $icreateElement("cfdi:Concepto"); $concepto = $conceptos->appendChild($concepto); cargaAtt($concepto, array( "ClaveProdServ"=>utf8_decode($abdDatArt[$i]["claveProd"]), "Cantidad"=>$abdDatArt[$i]["cantidad"], "ClaveUnidad"=>utf8_decode($abdDatArt[$i]["unidad"]), "Unidad"=>utf8_decode($abdDatArt[$i]["descUnidad"]), "Descripcion"=>utf8_decode($abdDatArt[$i]["descripcion"]), "ValorUnitario"=>number_format($abdDatArt[$i]["valorUnitario"],2,'.',''), "Importe"=>number_format($abdDatArt[$i]["importe"],2,'.',''), "Descuento"=>number_format($abdDatArt[$i]["descuento"],2,'.',''), "ObjetoImp"=>utf8_decode($abdDatArt[$i]["ObjetoImp"]) ) ); $impuestos = $xml->createElement("cfdi:Impuestos"); $impuestos = $concepto->appendChild($impuestos); //if ($abdDatArt[$i]["ivaImporte"] > 0) if($abdDatArt[$i]["ivaImpuesto"] == "002") { $lIvaTraslad = true; $Traslados = $xml->createElement("cfdi:Traslados"); $Traslados = $impuestos->appendChild($Traslados); $Traslado = $xml->createElement("cfdi:Traslado"); $Traslado = $Traslados->appendChild($Traslado); $ivaImpuesto = $abdDatArt[$i]["ivaImpuesto"]; cargaAtt($Traslado, array( "Base"=>number_format($abdDatArt[$i]["ivaBase"],2,'.',''), "Impuesto"=>$abdDatArt[$i]["ivaImpuesto"], "TipoFactor"=>$abdDatArt[$i]["ivaTipoFactor"], "TasaOCuota"=>number_format($abdDatArt[$i]["ivaTasaOCuota"],6,'.',''), "Importe"=>number_format($abdDatArt[$i]["ivaImporte"],2,'.','') ) ); $ivaTasaOCuota = $abdDatArt[$i]["ivaTasaOCuota"]; } //if ($abdDatArt[$i]["isrImporte"] > 0) if($abdDatArt[$i]["isrImpuesto"] == "001") { $lIsrRetenid = true; $Retenciones = $xml->createElement("cfdi:Retenciones"); $Retenciones = $impuestos->appendChild($Retenciones); $Retencion = $xml->createElement("cfdi:Retencion"); $Retencion = $Retenciones->appendChild($Retencion); $isrImpuesto = $abdDatArt[$i]["isrImpuesto"]; cargaAtt($Retencion, array( "Base"=>number_format($abdDatArt[$i]["isrBase"],2,'.',''), "Impuesto"=>$abdDatArt[$i]["isrImpuesto"], "TipoFactor"=>$abdDatArt[$i]["isrTipoFactor"], "TasaOCuota"=>number_format($abdDatArt[$i]["isrTasaOCuota"],6,'.',''), "Importe"=>number_format($abdDatArt[$i]["isrImporte"],2,'.','') ) ); } } $Impuestos = $xml->createElement("cfdi:Impuestos"); $Impuestos = $root->appendChild($Impuestos); //if ($totalImpuestosTrasladados > 0) if ($lIvaTraslad == true) { $Traslados = $xml->createElement("cfdi:Traslados"); $Traslados = $Impuestos->appendChild($Traslados); $Traslado = $xml->createElement("cfdi:Traslado"); $Traslado = $Traslados->appendChild($Traslado); cargaAtt($Traslado, array( "Impuesto"=>$ivaImpuesto, "TipoFactor"=>"Tasa", "TasaOCuota"=>number_format($ivaTasaOCuota,6,'.',''), "Importe"=>number_format($totalImpuestosTrasladados,2,'.','') ) ); cargaAtt($Impuestos, array( "TotalImpuestosTrasladados"=>number_format($totalImpuestosTrasladados,2,'.','') ) ); } //if ($totalImpuestosRetenidos > 0) if ($lIsrRetenid == true) { $Retenciones = $xml->createElement("cfdi:Retenciones"); $Retenciones = $Impuestos->appendChild($Retenciones); $Retencion = $xml->createElement("cfdi:Retencion"); $Retencion = $Retenciones->appendChild($Retencion); cargaAtt($Retencion, array( "Impuesto"=>$isrImpuesto, "Importe"=>number_format($totalImpuestosRetenidos,2,'.','') ) ); cargaAtt($Impuestos, array( "TotalImpuestosRetenidos"=>number_format($totalImpuestosRetenidos,2,'.','') ) ); } $complemento = $xml->createElement("cfdi:Complemento"); $complemento = $root->appendChild($complemento); #== 10.7 Termina de conformarse la "Cadena original" con doble || $cadena_original .= "|"; #=== Muestra la cadena original (opcional a mostrar) ======================= #== 10.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); #== 10.9 Se convierte la cadena digital a Base 64 =========================== $sello = base64_encode($crypttext); #=== Muestra el sello (opcional a mostrar) ================================= #== 10.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; $isetAttribute("sello",$sello); $root->setAttribute("certificado",$certificado); # Certificado. //$root->setAttribute("motivoDescuento",$MotivDesc); # Motivo de descuento. //$root->setAttribute("folio",$fact_folio); # Folio de la factura (número entero). //$root->setAttribute("serie",$fact_serie); # Serie de la factura (letra o letras). #== Fin de la integración de nodos ========================================= #=== 10.12 Se guarda el archivo .XML antes de ser timbrado ======================= $NomArchCFDI = $SendaCFDI."PreCFDI-33_".$NoFac.".xml"; $NomArchPDF1 = $SendaCFDI."VP_CFDI_".$fact_serie.str_pad($fact_folio, 6, "0", STR_PAD_LEFT)."_".$invoiceNumber.".pdf"; $NomArchXML = "PreCFDI-33_".$NoFac.".xml"; $NomArchPDF = "VP_CFDI_".$fact_serie.str_pad($fact_folio, 6, "0", STR_PAD_LEFT)."_".$invoiceNumber.".pdf"; // $cfdi = $xml->saveXML(); $xml->formatOutput = true; $xml->save($NomArchCFDI); // Guarda el archivo .XML (sin timbrar) en el directorio predeterminado. unset($xml); #=== 10.13 Se dan permisos de escritura al archivo .xml. ========================= chmod($NomArchCFDI, 0777); ### 13. CREACION DE PDF Y ENVIO DE CORREO CON XML Y PDF ########################### # 13.1 Creación del Archivo PDF //$url = 'http://localhost/aptusCFDIRF/wsInvoicePDF_VP_v33.php?NomArchXML='.$NomArchXML.'&NomArchPDF='.$NomArchPDF; //$url = 'http://localhost/aptusCFDIRF/'.$FormatoPDF.'.php?NomArchXML='.$NomArchXML.'&NomArchPDF='.$NomArchPDF; if($TipPDFGen == 1) { $url = 'https://aptuslegal.app/aptusCFDIRF/'.$FormatoPDF.'.php?NomArchXML='.$NomArchXML.'&NomArchPDF='.$NomArchPDF.'&pInvNumb='.$invoiceNumber.'&pOrdCob='.$sOrdenCobro.'&pObserva='.$sObservaciones.'&pDirRecep='.$sDireRecep; echo $url; } else { $url = 'https://aptuslegal.app/aptusCFDIRF/'.$FormatoPDF.'.php?NomArchXML='.$NomArchXML.'&NomArchPDF='.$NomArchPDF; } $objCurl = curl_init(); curl_setopt($objCurl, CURLOPT_URL, $url); curl_setopt($objCurl, CURLOPT_HEADER, 0); curl_setopt($objCurl, CURLOPT_RETURNTRANSFER, true); curl_exec($objCurl); curl_close($objCurl); # 13.3 Envio del Archivos a Invoice de Zoho Creator # Primero el PDF $file_name_with_full_path = '/var/www/html/aptusCFDIRF/archs_cfdi/'.$NomArchPDF; //$request_url = 'https://creator.zoho.com/api/xml/fileupload/scope=creatorapi'; # Actualización a API V2 con OAuth. JFA y FFR 2021-06-18 $request_url = 'https://creator.zoho.com/api/v2/'.$appOwner.'/'.$applnkname.'/report/cfdi_I_query/'.$bRecId.'/File_PDF_VP/upload'; if (function_exists('curl_file_create')) { // php 5.6+ $cFile = curl_file_create($file_name_with_full_path); } else { $cFile = '@' . realpath($file_name_with_full_path); } /* echo $bRecId; echo "
"; echo $authtoken_ZC; echo "
"; echo $NomArchPDF; echo "
"; echo $file_name_with_full_path; echo "
"; echo $request_url; echo "
"; echo "Parametros"; print_r($post); echo "
"; */ $post = array( // 'authtoken' => $authtoken_ZC, // 'applinkname' => $applnkname, // 'formname' => 'CreacionCFDIv33', // 'fieldname' => 'File_PDF_VP', // 'recordId' => $bRecId, 'filename' => $NomArchPDF, 'file'=> $cFile); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $request_url); //curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); #JFA: Cambiamos el método de Autenticación a OAuth curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Zoho-oauthtoken ' . $access_token)); $r = curl_exec($ch); //print_r($r); //echo "
"; curl_close ($ch); #== Se elimina los archivos de trabajo //unlink($NomArchCFDI); //unlink($NomArchPDF1); $j_array = array('code' => "200", "message" => "Proceso de creacion de CFDI fue exitoso", 'file_upload' => $NomArchPDF); $Resultado = json_encode($j_array); echo $Resultado; return; ### 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ónes que da formato al "Importe total" como lo requiere el SAT para ser integrado al código QR. function ProcesImpTot($ImpTot){ $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; }