4069147000043384623"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043384627"},"message":"Data Added Successfully"}],"code":3000}
{"result":[{"code":3000,"data":{"ID":"4069147000043355079"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355083"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355087"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355091"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355095"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355099"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355103"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355107"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355111"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355115"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355119"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355123"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355127"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355131"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355135"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355139"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355143"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355147"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355151"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355155"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355159"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355163"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355167"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355171"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355175"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355179"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355183"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355187"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355191"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355195"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355199"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355203"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355207"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355211"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355215"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355219"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355223"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355227"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355231"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355235"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355239"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355243"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355247"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355251"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355255"},"message":"Data Added Successfully"},{"code":3000,"data":{"ID":"4069147000043355259"},"messagas:DetalleAux Fecha="2023-05-17" NumUnIdenPol="2340388000037570640" Concepto="17-05-2023 - BILL_PAYMENT 2112474" Debe="0.00" Haber="2445.20"/>
"301", "message" => "ERROR - [wsPolizasAnalytics] Parametros incompletos para el Servicio Web, faltan el appOwner");
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
}
if($anio == "")
{
$j_array = array('code' => "302", "message" => "ERROR - [wsPolizasAnalytics] Parametros incompletos para el Servicio Web, faltan el Anio de vigencia");
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
}
if($mes == "")
{
$j_array = array('code' => "303", "message" => "ERROR - [wsPolizasAnalytics] Parametros incompletos para el Servicio Web, faltan el Mes de vigencia");
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
}
if($organi_id_Analytics == "")
{
$j_array = array('code' => "304", "message" => "ERROR - [wsPolizasAnalytics] Parametros incompletos para el Servicio Web, faltan el Organization ID de Analytics");
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
}
if($RFC == "")
{
$j_array = array('code' => "305", "message" => "ERROR - [wsPolizasAnalytics] Parametros incompletos para el Servicio Web, faltan el RFC");
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
}
if($idWorkspace == "")
{
$j_array = array('code' => "306", "message" => "ERROR - [wsPolizasAnalytics] Parametros incompletos para el Servicio Web, faltan el ID del workspace");
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
}
if($idView == "")
{
$j_array = array('code' => "307", "message" => "ERROR - [wsPolizasAnalytics] Parametros incompletos para el Servicio Web, faltan el Organization ID de la vista");
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
}
$dirBase = realpath("../");
### DEFINICIÓN DE CONSTANTES ###################################################
$SendaPEM = "archs_pem/";
$SendaXML = "archs_xml/";
$SendaZIP = "archs_zip/";
#----------------------------------------------------------------
#== Llamado para generar el token para donatello
#----------------------------------------------------------------
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://donatello.aptuslegal.app/oauth/token/'.$organi_id_Analytics,
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'];
#----------------------------------------------------------------
#== Hacemos el llamado para generar la obtención de los datos en la operación Bulk y obtenemos el Job ID.
#----------------------------------------------------------------
$curl = curl_init();
$dia = obtenerDiasDelMes($mes);
if($dia == "Formato de mes inválido."){
$j_array = array('code' => "309", "message" => "ERROR - [wsPolizasAnalytics] El formato del parámetro del mes no es valido");
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
}
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://analyticsapi.zoho.com/restapi/v2/bulk/workspaces/'.$idWorkspace.'/views/'.$idView.'/data?CONFIG=%7B%22criteria%22%3A%22%5C%22Fecha%20de%20transaccion%5C%22%20between%20%27'.$anio.'-'.$mes.'-01%27%20and%20%27'.$anio.'-'.$mes.'-'.$dia.'%27%22%2C%20%22responseFormat%22%3A%22json%22%7D',
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(
'ZANALYTICS-ORGID: '.$organi_id_Analytics,
'Authorization: Zoho-oauthtoken '.$access_token,
'Content-Type: application/json'
),
));
$response = curl_exec($curl);
curl_close($curl);
$responseData = json_decode($response, true);
// Acceder al 'jobId'
$jobId = $responseData['data']['jobId'];
#----------------------------------------------------------------
#== Obtenemos el status del JobId para saber si se puede descargar la respuesta
#----------------------------------------------------------------
$jobStatus = "JOB IN PROGRESS";
while ($jobStatus === "JOB IN PROGRESS") {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://analyticsapi.zoho.com/restapi/v2/bulk/workspaces/'.$idWorkspace.'/exportjobs/'.$jobId,
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(
'ZANALYTICS-ORGID: '.$organi_id_Analytics,
'Authorization: Zoho-oauthtoken '.$access_token
),
));
$response = curl_exec($curl);
// Decodificar la respuesta JSON
$responseData = json_decode($response, true);
// Verificar el status del trabajo
if (isset($responseData['data']['jobStatus'])) {
$jobStatus = $responseData['data']['jobStatus'];
} else {
// Si no se encuentra jobStatus en la respuesta, salir del ciclo
$j_array = array('code' => "311", "message" => "ERROR - [wsPolizasAnalytics] Error al esperar el Status de JobId de Analytics");
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
}
// Esperar 5 segundos antes de volver a consultar
sleep(5);
}
//Si se obtiene un status diferente al esperado lo interpreta como error
if($jobStatus != "JOB COMPLETED"){
$j_array = array('code' => "312", "message" => "ERROR - [wsPolizasAnalytics] Error el Status del JobId inesperado");
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
}
if (isset($responseData['data']['downloadUrl'])) {
$downloadUrl = $responseData['data']['downloadUrl'];
// echo "Download URL: " . $downloadUrl;
} else {
$j_array = array('code' => "313", "message" => "ERROR - [wsPolizasAnalytics] Error al obtener el downloadUrl de Analytics");
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
}
#----------------------------------------------------------------
#== Llamado para la obtención de los datos en formato JSON de la vista de Analytics.
#----------------------------------------------------------------
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $downloadUrl,
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(
'ZANALYTICS-ORGID: '.$organi_id_Analytics,
'Authorization: Zoho-oauthtoken '.$access_token
),
));
$response = curl_exec($curl);
curl_close($curl);
// Decodificar el JSON
$responseData = json_decode($response, true);
// Verificar si el campo 'data' existe
if (isset($responseData['data'])) {
#----------------------------------------------------------------
#== Creación de la variable de tipo DOM, aquí se conforma el XML a timbrar posteriormente.
#----------------------------------------------------------------
$xml = new DOMdocument('1.0', 'UTF-8');
$root = $xml->createElement("Polizas");
$root = $xml->appendChild($root);
#== Se crea e inserta el primer nodo donde se declaran los namespaces ======
cargaAttNodo(
$root, array("xsi:schemaLocation"=>"www.sat.gob.mx/esquemas/ContabilidadE/1_1/PolizasPeriodo http://www.sat.gob.mx/esquemas/ContabilidadE/1_1/CatalogosParaEsqContE/CatalogosParaEsqContE.xsd",
"xmlns:Polizas"=>"www.sat.gob.mx/esquemas/ContabilidadE/1_1/AuxiliarFolios",
"xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema")
);
#== Rutina de integración de nodos =========================================
cargaAttNodo($root, array(
"Version"=>"1.3",
"RFC"=>$RFC,
"Mes"=>$mes,
"Anio"=>$anio
)
);
$sumTotalDebe = 0;
$sumTotalHaber = 0;
$totalDebe = 0;
$totalHaber = 0;
$polizaControl = "";
$polizaNodo = null; // Variable para mantener la referencia al nodo Poliza
$numeroTotalPolizas = 0;
foreach ($responseData['data'] as $item) {
// Asignar cada valor a variables
$tipoPoliza = $item['Tipo Poliza'];
$transaccion = $item['Transaccion'];
$fechaTransaccion = str_replace('.', '-', $item['Fecha de transaccion']);
$idCuenta = $item['ID de la cuenta'];
$nombre = $item['Nombre'];
$debe = $item['Debe'];
$haber = $item['Haber'];
$creditoDebitoTotal = $item['Credito-Debito - Total'];
$debitoCreditoTotal = $item['Debito-Credito Total'];
$concepto = $item['Concepto'];
$numCta = $item['NumCta'];
// Cuando detectas una nueva transacción (nueva póliza)
if($transaccion != $polizaControl){
// Si ya hay una póliza en proceso, agregas el atributo MontoTotal a la póliza anterior
if ($polizaNodo !== null) {
$montoTotal = $totalDebe - $totalHaber;
$polizaNodo->setAttribute("MontoTotal", number_format($montoTotal, 2, '.', '')); // Agregar MontoTotal
}
// Crear una nueva póliza
$polizaControl = $transaccion;
$Poliza = $xml->createElement("Poliza");
$polizaNodo = $root->appendChild($Poliza);
cargaAttNodo($polizaNodo, array(
"NumUnIdenPol" => $transaccion,
"Fecha" => $fechaTransaccion,
"Concepto" => $tipoPoliza
));
// Reiniciar los totales para la nueva póliza
$totalDebe = 0;
$totalHaber = 0;
}
// Crear un nodo Transaccion y agregarlo a la póliza actual
$transaccion = $xml->createElement("Transaccion");
$nodo = $Poliza->appendChild($transaccion);
cargaAttNodo($nodo, array(
"NumCta" => $numCta,
"DesCta" => $nombre,
"Concepto" => $concepto,
"Debe" => $debe,
"Haber" => $haber
));
// Acumular los valores de Debe y Haber
$totalDebe += (float)$debe;
$totalHaber += (float)$haber;
// Acumular los totales generales
$sumTotalDebe += (float)$debe;
$sumTotalHaber += (float)$haber;
$numeroTotalPolizas += 1;
}
// Para la última póliza en el loop, también agregamos el MontoTotal
if ($polizaNodo !== null) {
$montoTotal = $totalDebe - $totalHaber;
$polizaNodo->setAttribute("MontoTotal", number_format($montoTotal, 2, '.', '')); // Agregar MontoTotal al final
}
// Establecer el tipo de contenido a XML y devolver el contenido
// header('Content-Type: application/xml; charset=utf-8');
// echo $xml->saveXML();
#=== Se guarda el archivo .XML del Catalogo de Cuentas =======================
$file_name_with_full_path = '/var/www/html/aptusContaElec/archs_xml/'.$RFC.$anio.$mes."PP.xml";
#=== Si existe el archivo XML se elimina para crear el nuevo =======================
if(!file_exists($file_name_with_full_path)){
unlink($file_name_with_full_path);
}
#=== Se guarda el archivo XML creado =======================
$polizaXML = $xml->saveXML();
$xml->formatOutput = true;
$xml->save($file_name_with_full_path);
unset($xml);
#=== Se dan permisos de escritura al archivo .xml. =========================
chmod($file_name_with_full_path, 0777);
#=== Se procede a crear el archivo ZIP del Catalogo de Cuentas =========================
$zip = new ZipArchive();
$nombreArchivoZip = '/var/www/html/aptusContaElec/archs_zip/'.$RFC.$anio.$mes."PP.zip";
$nameArchZip = $RFC.$anio.$mes."PP.zip";
#=== Si existe el archivo ZIP se elimina para crear el nuevo =======================
if(!file_exists($nombreArchivoZip)){
unlink($nombreArchivoZip);
}
if (!$zip->open($nombreArchivoZip, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
exit("Error abriendo ZIP en $nombreArchivoZip");
}
$nombre = basename($file_name_with_full_path);
$zip->addFile($file_name_with_full_path, $nombre);
$resultado = $zip->close();
if ($resultado) {
} else {
$j_array = array('code' => "318", "message" => "ERROR - [wsPolizasAnalytics] Error al crear el archivo ZIP");
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
}
#----------------------------------------------------------------
# Se sube archivo ZIP a Workdrive
#----------------------------------------------------------------
$woa_access_token = oauth($appOwner, 'ZWorkrdv', $woa_RefreshToken, $woa_ClientId, $woa_ClientSecret, $woa_RedirectUri, $woa_GrantType, $woa_AuthUrl);
$urlWorkdrv = 'https://workdrive.zoho.com/api/v1/upload?parent_id='.$wdrv_parent_id.'&filename='.$nameArchZip.'&override-name-exist=true';
$curl = curl_init();
curl_setopt_array($curl,
array(
CURLOPT_URL => $urlWorkdrv,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array('content'=> new CURLFILE($nombreArchivoZip)),
CURLOPT_HTTPHEADER => array('Authorization: Zoho-oauthtoken '.$woa_access_token ),
)
);
$response = curl_exec($curl);
curl_close($curl);
#=== FIN DEL PROCESO =======================
$j_array = array('code' => "200", 'message' => "Proceso de creacion de archivo de pólizas del periodo exitoso", 'xml_file_name' => $RFC.$anio.$mes."PP.xml", 'zip_file_name' => $RFC.$anio.$mes."PP.zip",'Total de Polizas' => $numeroTotalPolizas,'Total Debe' =>number_format($sumTotalDebe, 2, '.', ''),'Total Haber' => number_format($sumTotalHaber, 2, '.', ''));
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
} else {
$j_array = array('code' => "315", "message" => "ERROR - [wsPolizasAnalytics] No se obtuvieron datos de la vista");
$Resultado = json_encode($j_array);
echo $Resultado;
return $Resultado;
}
### FUNCIONES DEL MÓDULO #########################################################
# Función que integra los nodos al archivo .XML
function cargaAttNodo(&$nodo, $attr){
global $xmldoc;
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);
}
}
}
function obtenerDiasDelMes($mes) {
// Validar que el parámetro sea una cadena con dos dígitos
if (!preg_match('/^\d{2}$/', $mes)) {
return "Formato de mes inválido.";
}
// Obtener el año actual
$anio = date("Y");
// Usar la función `cal_days_in_month` para obtener la cantidad de días del mes
$dias = cal_days_in_month(CAL_GREGORIAN, intval($mes), $anio);
return $dias;
}