5-29 16:52:28.471 [info] [fetchCompletions] Request 7e0eef48-01ad-4c33-b610-3ad030cb0577 at finished with 200 status after 225.58788799867034ms 2025-05-29 16:52:28.473 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-05-29 16:52:29.166 [info] [fetchCompletions] Request e2e4f9e0-17c3-4b39-9cd9-2dd4f3560d68 at finished with 200 status after 223.06642400100827ms 2025-05-29 16:52:29.169 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-05-29 16:53:52.362 [info] [fetchCompletions] Request 4dea0f1d-b090-4154-a823-3fc431e7a10d at finished with 200 status after 233.68531500175595ms 2025-05-29 16:53:52.702 [info] [fetchCompletions] Request fa2a1620-3b60-4cba-9daf-ea9078b02c36 at finished with 200 status after 336.46533999964595ms 2025-05-29 16:53:52.706 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-05-29 16:53:53.724 [info] [fetchCompletions] Request c98346dd-918e-48d5-ab7a-1c27f41d4cfd at finished with 200 status after 169.13129399716854ms 2025-05-29 16:53:53.727 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-05-29 16:54:07.282 [info] [fetchCompletions] Request 1269a29d-e341-41df-b49d-9f5125db7e8d at finished with 200 status after 316.44714000076056ms 2025-05-29 16:54:07.284 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-05-29 16:54:07.652 [info] [fetchCompletions] Request cee13fed-16ec-4396-9268-bee78e2c266a at finished with 200 status after 167.74440000206232ms 2025-05-29 16:54:07.655 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-05-29 16:54:09.457 [info] [ghostText] Filtered out solution matching next line 2025-05-29 16:54:10.178 [info] [fetchCompletions] Request 64ed3d46-caaf-4c17-92cf-36e4c74ab4ec at finished with 200 status after 215.6370839998126ms 2025-05-29 16:54:10.179 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-05-29 16:54:19.663 [info] [fetchCompletions] Request faf59087-671a-47d0-81e5-c3abbb2ba218 at finished with 200 status after 181.55968599766493ms 2025-05-29 16:54:19.666 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-05-29 16:54:32.946 [info] [fetchCompletions] Request b94c067d-feeb-47ac-b6f6-614449022b9c at finished with 200 status after 945.7267780005932ms 2025-05-29 16:54:33.004 [info] [fetchCompletions] Request 09d66633-ac69-44f1-88ce-11ebfca558b0 at finished with 200 status after 445.9832479991019ms 2025-05-29 16:54:33.007 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-05-29 16:54:53.225 [info] [fetchCompletions] Request 1d172fe9-4ceb-47e8-a408-829b14914ff9 at finished with 200 status after 404.8107009977102ms 2025-05-29 16:54:53.228 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-05-29 16:55:03.663 [info] [fetchCompletions] Request 05001ced-b9e1-4820-a0c1-bf09a5466125 at finished with 200 status after 449.8423530012369ms 2025-05-29 16:55:03.665 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025[1f056b7e-305f-4744-a5ea-e4a782e00e37](2025-05-29 17:53:30) - Intento 1 el registro no contiene foto asociada [1f056b7e-305f-4744-a5ea-e4a782e00e37](2025-05-29 17:53:30) - ERROR al obtener imagen, intento: 2 , respuesta: null [1f056b7e-305f-4744-a5ea-e4a782e00e37](2025-05-29 17:53:32) - Intento 2 el registro no contiene foto asociada [1f056b7e-305f-4744-a5ea-e4a782e00e37](2025-05-29 17:53:32) - ERROR al obtener imagen, intento: 3 , respuesta: null [1f056b7e-305f-4744-a5ea-e4a782e00e37](2025-05-29 17:53:34) - No se pudo encontrar una imagen asociada a registro de CRM \n [0ebd50ad-e0a4-4313-995c-cd5567ba0fd9](2025-05-29 17:54:50) - Proceso de subida de imagen iniciado, data: {"source":"webhook","RefAL":"MAR-129906","MarcaId":"4597192000260992430","user":"gsanchez@arochilindner.com"} [0ebd50ad-e0a4-4313-995c-cd5567ba0fd9](2025-05-29 17:54:57) - Tokens generados: 1000.caa0e4bef6780c12314b618ea3f5a2c3.0916f4d9d2599428ac23b3c3c303a831 [0ebd50ad-e0a4-4313-995c-cd5567ba0fd9](2025-05-29 17:54:58) - Intento 0 el registro no contiene foto asociada [0ebd50ad-e0a4-4313-995c-cd5567ba0fd9](2025-05-29 17:54:58) - ERROR al obtener imagen, intento: 1 , respuesta: null [0ebd50ad-e0a4-4313-995c-cd5567ba0fd9](2025-05-29 17:55:00) - Intento 1 el registro no contiene foto asociada [0ebd50ad-e0a4-4313-995c-cd5567ba0fd9](2025-05-29 17:55:00) - ERROR al obtener imagen, intento: 2 , respuesta: null [0ebd50ad-e0a4-4313-995c-cd5567ba0fd9](2025-05-29 17:55:03) - Intento 2 el registro no contiene foto asociada [0ebd50ad-e0a4-4313-995c-cd5567ba0fd9](2025-05-29 17:55:03) - ERROR al obtener imagen, intento: 3 , respuesta: null [0ebd50ad-e0a4-4313-995c-cd5567ba0fd9](2025-05-29 17:55:05) - No se pudo encontrar una imagen asociada a registro de CRM \n [ea29bdeb-7d1e-4da2-b865-87128ee2e063](2025-05-29 18:41:19) - Proceso de subida de imagen iniciado, data: {"source":"webhook","RefAL":"MAR-129907","MarcaId":"4597192000261223021","user":"sarroyo@arochilindner.com"} [ea29bdeb-7d1e-4da2-b865-87128ee2e063](2025-05-29 18:41:26) - Tokens generados: 1000.caa0e4bef6780c12314b618ea3f5a2c3.0916f4d9d2599428ac23b3c3c303a831 [ea29bdeb-7d1e-4da2-b865-87128ee2e063](2025-05-29 18:41:26) - Intento 0 el registro no contiene foto asociada [ea29bdeb-7d1e-4da2-b865-87128ee2e063](2025-05-29 18:41:26) - ERROR al obtener imagen, intento: 1 , respuesta: null [ea29bdeb-7d1e-4da2-b865-87128ee2e063](2025-05-29 18:41:29) - Intento 1 el registro no contiene foto asociada [ea29bdeb-7d1e-4da2-b865-87128ee2e063](2025-05-29 18:41:29) - ERROR al obtener imagen, intento: 2 , respuesta: null [ea29bdeb-7d1e-4da2-b865-87128ee2e063](2025-05-29 18:41:31) - Intento 2 el registro no contiene foto asociada [ea29bdeb-7d1e-4da2-b865-87128ee2e063](2025-05-29 18:41:31) - ERROR al obtener imagen, intento: 3 , respuesta: null [ea29bdeb-7d1e-4da2-b865-87128ee2e063](2025-05-29 18:41:33) - No se pudo encontrar una imagen asociada a registro de CRM \n [800ac36d-6a8d-4b33-8758-b204bbe6b6c1](2025-05-29 19:19:18) - Proceso de subida de imagen iniciado, data: {"source":"webhook","RefAL":"MAR-129906","MarcaId":"4597192000260992430","user":"gbringas@arochilindner.com"} [800ac36d-6a8d-4b33-8758-b204bbe6b6c1](2025-05-29 19:19:25) - Tokens generados: 1000.2f3a423ed9963f9f9f9a6a7ac1324a12.f4465a92fcc2273ecd252b0f00b63ebf [800ac36d-6a8d-4b33-8758-b204bbe6b6c1](2025-05-29 19:19:25) - Intento 0 para obtener imagen de marca de CRM, respuesta: 200 [800ac36d-6a8d-4b33-8758-b204bbe6b6c1](2025-05-29 19:19:25) - Imagen guardada localmente de manera exitosa [800ac36d-6a8d-4b33-8758-b204bbe6b6c1](2025-05-29 19:19:26) - Intento 0 para actualizar CRM con datos de url de marca: { "data": [ { "code": "SUCCESS", "details": { "Modified_Time": "2025-05-29T20:19:26-04:00", "Modified_By": { "name": "Aptus Legal Administrator", "id": "4597192000000287001" }, "Created_Time": "2025-05-29T18:54:49-04:00", "id": "4597192000260992430", "Created_By": { "name": '302', 'message' => 'ERROR: Falta Año de vigencia']); return; } if ($mesCata == "") { echo json_encode(['code' => '303', 'message' => 'ERROR: Falta Mes de vigencia']); return; } if ($organi_id_ZB == "") { echo json_encode(['code' => '304', 'message' => 'ERROR: Falta Organization ID']); return; } // --- Conexión a base de datos para obtener tokens y RFC --- $conn = mysqli_connect('127.0.0.1','aptuslegal','#Aptus2021#','vendorbills'); if (!$conn) { exit('MySQL connect error: '.mysqli_connect_error()); } $sql = 'SELECT * FROM conndetails WHERE organization_id="'.$organi_id_ZB.'"'; if ($res=$conn->query($sql)) { $row = $res->fetch_assoc(); } else { exit('Consulta BD fallida'); } $appOwner = $row['appOwner']; $boa_RefreshToken = $row['zbooks_rtoken']; $boa_ClientId = $row['zbooksclient_id']; $boa_ClientSecret = $row['zbooksclient_secret']; $boa_RedirectUri = $row['RedirectUri']; $boa_AuthUrl = 'https://accounts.zoho.com/oauth/v2/token'; $boa_GrantType = 'refresh_token'; $regFeCa = $row['rfc']; mysqli_close($conn); // --- Obtener token Zoho Books --- $boa_access_token = oauth($appOwner,'ZBooks',$boa_RefreshToken,$boa_ClientId,$boa_ClientSecret,$boa_RedirectUri,$boa_GrantType,$boa_AuthUrl); // --- Calcular fechas para consulta --- $sFechaIni = date('Y-m-d', strtotime("{$anioCat}-{$mesCata}-01")); $sFechaFin = date('Y-m-d', strtotime($sFechaIni . ' +1 month -1 day')); // --- Iniciar DOMDocument y generar XML (SAT Anexo 24 v1.3) --- $xml = new DOMDocument('1.0','UTF-8'); $xml->preserveWhiteSpace = false; $xml->formatOutput = true; // Crear elemento raíz con namespaces $root = $xml->createElement('RepAux:RepAuxFol'); $root = $xml->appendChild($root); $root->setAttribute('xmlns:RepAux','http://www.sat.gob.mx/esquemas/ContabilidadE/1_3/AuxiliarFolios'); $root->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); $root->setAttribute( 'xsi:schemaLocation', 'http://www.sat.gob.mx/esquemas/ContabilidadE/1_3/AuxiliarFolios ' . 'http://www.sat.gob.mx/esquemas/ContabilidadE/1_3/AuxiliarFolios/AuxiliarFolios_1_3.xsd' ); // Atributos del nodo raíz $root->setAttribute('Version','1.3'); $root->setAttribute('RFC', $regFeCa); $root->setAttribute('Mes', $mesCata); $root->setAttribute('Anio', $anioCat); $root->setAttribute('TipoSolicitud','AF'); $fileCSV = __DIR__.'/archs_csv/'.$regFeCa.$anioCat.$mesCata.'XF.csv'; if (file_exists($fileCSV)) unlink($fileCSV); $csv = fopen($fileCSV, 'w'); chmod($fileCSV, 0777); // Escribir encabezados fputcsv($csv, ['NumUnIdenPol', 'Fecha', 'UUID_CFDI', 'MontoTotal', 'RFC', 'Moneda', 'TipCamb']); // --- Recorrer facturas y agregar DetAuxFol --- $totalFolios = 0; $vPageIndex = 1; $hasMore = true; while ($hasMore && $vPageIndex < 100) { $url = "https://www.zohoapis.com/books/v3/invoices?organization_id={$organi_id_ZB}&page={$vPageIndex}&per_page=100&date_start={$sFechaIni}&date_end={$sFechaFin}"; $vPageIndex++; $ch = curl_init(); curl_setopt_array($ch,[ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Authorization: Zoho-oauthtoken '.$boa_access_token] ]); $resp = curl_exec($ch); curl_close($ch); $data = json_decode($resp); $vInvoices = $data->invoices; $hasMore = $data->page_context->has_more_page; foreach ($vInvoices as $inv) { // Crear DetAuxFol $det = $xml->createElement('RepAux:DetAuxFol'); $det = $root->appendChild($det); $det->setAttribute('NumUnIdenPol', $inv->invoice_id); $det->setAttribute('Fecha', date('Y-m-d', strtotime($inv->due_date))); // Crear ComprNal $cn = $xml->createElement('RepAux:ComprNal'); $cn = $det->appendChild($cn); $cn->setAttribute('UUID_CFDI', $inv->invoice_id); $cn->setAttribute('MontoTotal', number_format($inv->total,2,'.','')); $cn->setAttribute('RFC', $inv->customer_cf_rfc_nit_tax_id); if ($inv->currency_code !== 'MXN') { $cn->setAttribute('Moneda', $inv->currency_code); $cn->setAttribute('TipCamb', $inv->exchange_rate); } fputcsv($csv, [ $inv->invoice_id, date('Y-m-d', strtotime($inv->due_date)), $inv->invoice_id, number_format($inv->total, 2, '.', ''), $inv->customer_cf_rfc_nit_tax_id, ($inv->currency_code !== 'MXN') ? $inv->currency_code : '', ($inv->currency_code !== 'MXN') ? $inv->exchange_rate : '' ]); $totalFolios++; } } fclose($csv); // --- Guardar XML en servidor --- $fileXML = __DIR__.'/archs_xml/'.$regFeCa.$anioCat.$mesCata.'XF.xml'; if (file_exists($fileXML)) unlink($fileXML); $xml->save($fileXML); chmod($fileXML, 0777); // --- Crear ZIP --- $zip = new ZipArchive(); $fileZIP = __DIR__.'/archs_zip/'.$regFeCa.$anioCat.$mesCata.'XF.zip'; if (file_exists($fileZIP)) unlink($fileZIP); if ($zip->open($fileZIP, ZipArchive::CREATE|ZipArchive::OVERWRITE)) { $zip->addFile($fileXML, basename($fileXML)); $zip->close(); } else { exit('Error al crear ZIP'); } // --- Subir ZIP a Zoho WorkDrive --- $woa_token = oauth($appOwner,'ZWorkrdv',$boa_RefreshToken,$boa_ClientId,$boa_ClientSecret,$boa_RedirectUri,$boa_GrantType,$boa_AuthUrl); $uploadUrl = "https://workdrive.zoho.com/api/v1/upload?parent_id={$wdrv_parent_id}&filename=".basename($fileZIP); $ch = curl_init(); curl_setopt_array($ch,[ CURLOPT_URL => $uploadUrl, CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => ['content'=>new CURLFILE($fileZIP)], CURLOPT_HTTPHEADER => ['Authorization: Zoho-oauthtoken '.$woa_token] ]); $resp = curl_exec($ch); curl_close($ch); // --- Respuesta final --- echo json_encode([ 'code' => 200, 'message' => 'Auxiliar de folios fiscales creado con éxito', 'xml_file_name' => basename($fileXML), 'zip_file_name' => basename($fileZIP), 'csv_file_name' => basename($fileCSV), 'total_folios' => $totalFolios ]); return; // --- Función auxiliar (no usada para este XML, pero se conserva) --- function cargaAttNodo(&$nodo, $attrs) { foreach ($attrs as $k=>$v) { if (trim($v)!="") $nodo->setAttribute($k, utf8_encode($v)); } }