Servicios de Parsable
1. Descripción
La información proveniente de Parsable es procesada mediante Apache NiFi y almacenada en diferentes objetos de la base de datos omnicanal, de acuerdo con el tipo de información.
La integración se encuentra organizada en tres grupos principales:
- Jobs: información relacionada con los trabajos ejecutados en Parsable.
- Deviations: información relacionada con las desviaciones detectadas durante la ejecución de los trabajos.
- Imágenes: información relacionada con las imágenes asociadas a los registros de Parsable.
Los Servicios de Parsable son servicios de integración que permiten procesar y exponer información proveniente de la plataforma Parsable.
2. Servicios de Parsable
| No. | Origen | Catálogo | Descripción |
|---|---|---|---|
| 1 | Jobs | Visitas por Día / Status | Muestra el total de los trabajos realizados por estatus de las visitas al día. |
| 2 | Jobs | Visitas por Asesor / Día | Muestra el total de los trabajos realizados por asesor al día. |
| 3 | Jobs | Tiempo Visita | Muestra el tiempo registrado para las visitas realizadas en Parsable. |
| 4 | Jobs | Resumen Tiempo Visita | Genera un resumen del tiempo empleado en las visitas realizadas en Parsable. |
| 5 | Deviations | Desviaciones | Muestra el total de las desviaciones realizados por día. |
| 6 | Deviations | Resumen Desviaciones | Genera un resumen de las desviaciones realizadas en Parsable. |
| 7 | Imagenes | Recuperación de Imagenes | Recupera de Alfresco la Imagene correspondiente al ID. |
Estas funciones encapsulan las reglas de negocio para generar información de Parsable y son expuestas mediante servicios REST a través de la API de Catálogos.
2. Arquitectura de la solución
El flujo general de información es el siguiente:
3. Componentes de la solución
| Componente | Descripción |
|---|---|
| Parsable | Plataforma origen de la información de los catálogos. |
| Alfresco | Repositorio documental y gestor utilizado para el almacenamiento y administración de imágenes. |
general_catalogs | Esquema donde se encuentran las funciones e información de Parsable. |
alp_cat_parsable_jobs | Tabla de Omnicanal donde se almacena la información proveniente de Parsable de Jobs. |
alp_cat_parsable_deviations | Tabla de Omnicanal donde se almacena la información proveniente de Parsable de Deviations. |
alp_cat_parsable_alfresco | Tabla de referencia que asocia los registros de Parsable con sus respectivas imágenes almacenadas en Alfresco. |
| Funciones PostgreSQL | Procesan la información de Parsable y generan los datos requeridos. |
| API de Catálogos | Expone las funciones mediante servicios REST. |
| Keycloak | Servicio utilizado para la autenticación y generación del token de acceso. |
4. Autenticación
Para consumir los servicios de la API de Catálogos es necesario obtener previamente un token de acceso mediante el servicio de autenticación de Keycloak.
La autenticación se realiza mediante el flujo password, enviando las credenciales del usuario y la información del cliente configurado en el proveedor de identidad.
Si quieres una presentación aún más compacta y visual, puedes usar una tabla general:
4.1. Información del servicio de autenticación
| Elemento | Valor |
|---|---|
| 🌐 Endpoint | /realms/Alpura/protocol/openid-connect/token |
| ⚙️ Método HTTP | POST |
| 📦 Content-Type | application/x-www-form-urlencoded |
4.2. Parámetros de autenticación
| Parámetro | Descripción |
|---|---|
grant_type | Tipo de flujo de autenticación utilizado para obtener el token. |
client_id | Identificador del cliente configurado en Keycloak. |
client_secret | Secreto asociado al cliente. |
username | Usuario utilizado para realizar la autenticación. |
password | Contraseña del usuario. |
Los valores sensibles deben gestionarse mediante variables de entorno o un administrador de secretos.
5. Servicios de Catálogos
Para facilitar la integración y el mantenimiento, todos los endpoints de la API de Catálogos comparten una dirección base común. Las consultas específicas se realizan modificando el catálogo de destino en la URL.
5.1. Información de los Servicios Jobs
- Visitas por Día / Status
- Visitas por Asesor / Día
- Tiempo Visita
- Resumen Tiempo Visita
| Elemento | Valor |
|---|---|
| 🌐 Endpoint | /gc/v1/api/v1/catalogo/funcion/cat_parsable_visitas_dia_status |
| ⚙️ Método HTTP | POST |
| 📦 Content-Type | application/json |
| 🔒 Authorization | Bearer {access_token} |
| 🔒 ALP_AUTH | Bearer {access_token} |
| 🔗 Body WS | ["p_inicio", "p_fin","p_plantilla","{p_no_ranchos}"] |
| 🧩 Función BD | general_catalogs.alp_parsable_visitas_dia_status |
Los parámetros de p_inicio y p_fin deben enviarse utilizando el formato YYYY-MM-DD, de acuerdo con la siguiente estructura:
- YYYY: 4 dígitos para el año
- MM: 2 dígitos para el mes
- DD: 2 dígitos para el día
Ejemplo: 2026-06-01
El parámetro p_plantilla permite utilizar el carácter comodín % para realizar búsquedas parciales dentro del nombre de la plantilla.
Ejemplo:
CALIDAD%LECHE
Este valor permite buscar plantillas cuyo nombre contenga la cadena CALIDAD seguida de LECHE.
El parámetro p_no_ranchos recibe un arreglo con los números de los ranchos que se desean consultar. Si se especifican uno o más ranchos, la consulta devolverá únicamente la información correspondiente a esos registros.
Ejemplos:
"40" → Devuelve únicamente la información del Rancho 40.
"227" → Devuelve únicamente la información de los Ranchos 40 y 227.
Estructura de la Respuesta
El servicio devuelve un arreglo de objetos JSON. Cada objeto representa una fila de datos retornada por la función y contiene los siguientes campos:
| Campo | Tipo de dato (SQL) | Descripción |
|---|---|---|
no_rancho | BIGINT | Número identificador del rancho, extraído de los campos personalizados. |
rancho | TEXT | Nombre del rancho, extraído de los campos personalizados. |
plantilla | TEXT | Nombre o título de la plantilla del trabajo (job_template_title). |
job_started_date | DATE | Fecha de inicio del trabajo, convertida desde UTC. |
job_status | TEXT | Estatus actual del trabajo. Ejemplo: Completed, In Progress. |
job_lookup_id | BIGINT | Cantidad total de trabajos agrupados bajo estos criterios (COUNT(DISTINCT job_id)). |
Datos Técnicos
- cURL
- Ejemplo
- Respuesta del servicio
- Función BD
- Ejemplo Función BD
curl --location '<url_base>/gc/v1/api/v1/catalogo/funcion/cat_parsable_visitas_dia_status' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--header 'ALP_AUTH: Bearer <access_token>' \
--data '[<p_inicio>,<p_fin>,<p_plantilla>,"{<p_no_ranchos>}"]'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<url_base>con los datos correspondientes del servicio. - Sustituir los marcadores
<access_token>con el token de Keycloak obtenido previamente. - Configurar en el cuerpo (
--data) los parámetros específicos que requiere el catálogo.
curl --location '<url_base>/gc/v1/api/v1/catalogo/funcion/cat_parsable_visitas_dia_status' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--header 'ALP_AUTH: Bearer <access_token>' \
--data '["2026-05-01", "2026-05-31", "CALIDAD%LECHE", "{40,227}"]'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<url_base>con los datos correspondientes del servicio. - Sustituir los marcadores
<access_token>con el token de Keycloak obtenido previamente.
{
"header": {
"code": 0,
"message": "OK"
},
"success": false,
"errors": null,
"data": {
"nombre": "Información de Visitas por Dia / Status",
"esMaestro": false,
"appName": "parsable",
"registros": [
{
"no_rancho": 40,
"rancho": "EL OLIMPO",
"plantilla": "SA 04-01 CALIDAD DE LECHE",
"job_started_date": "2026-05-20",
"job_status": "Completed",
"job_lookup_id": 4
},
{
"no_rancho": 217,
"rancho": "OJO DE AGUA",
"plantilla": "SA-04-01 CALIDAD DE LECHE",
"job_started_date": "2026-05-29",
"job_status": "Completed",
"job_lookup_id": 2
}
]
},
"newToken": null,
"hash": "98C9B9B8090E1E71D610FEBFBD86965CC6E357C5251F7B8A600CCCE61ED77C1F",
"totalRows": 9,
"page": null
}
CREATE OR REPLACE FUNCTION general_catalogs.alp_parsable_visitas_dia_status(p_inicio date, p_fin date, p_plantilla text, p_no_ranchos bigint[])
RETURNS TABLE(no_rancho bigint, rancho text, plantilla text, job_started_date date, job_status text, job_lookup_id bigint)
LANGUAGE sql
AS $function$
with alp_info as
( select job_id
, split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'), '|', 1)::bigint no_rancho
, trim(split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'), '|', 2)) nombre_rancho
, job_template_title plantilla
, job_started_date_utc::date job_started_date
, job_status
from alp_cat_parsable
where job_status not in ('Canceled','Archived')
and job_started_date_utc::date between p_inicio::date
and p_fin::date
and job_template_title like '%' || p_plantilla || '%'
group by job_id
, job_template_title
, job_started_date_utc::date
, job_status
having split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'),'|',1)::bigint = any(p_no_ranchos))
select no_rancho
, nombre_rancho
, plantilla
, job_started_date
, job_status
, count(distinct job_id) job_lookup_id
from alp_info
group by no_rancho
, nombre_rancho
, plantilla
, job_started_date
, job_status
order by plantilla
, job_started_date desc
, job_status
$function$
;
select *
from general_catalogs.alp_parsable_visitas_dia_status(
'2026-06-01',
'2026-06-30',
'SA-04-01 CALIDAD DE LECHE',
'{40,227}'
);
| Elemento | Valor |
|---|---|
| 🌐 Endpoint | /gc/v1/api/v1/catalogo/funcion/cat_parsable_visitas_asesor_dia |
| ⚙️ Método HTTP | POST |
| 📦 Content-Type | application/json |
| 🔒 Authorization | Bearer {access_token} |
| 🔒 ALP_AUTH | Bearer {access_token} |
| 🔗 Body WS | ["p_inicio", "p_fin","p_plantilla","{p_no_ranchos}"] |
| 🧩 Función BD | general_catalogs.alp_parsable_visitas_asesor_dia |
Los parámetros de p_inicio y p_fin deben enviarse utilizando el formato YYYY-MM-DD, de acuerdo con la siguiente estructura:
- YYYY: 4 dígitos para el año
- MM: 2 dígitos para el mes
- DD: 2 dígitos para el día
Ejemplo: 2026-06-01
El parámetro p_plantilla permite utilizar el carácter comodín % para realizar búsquedas parciales dentro del nombre de la plantilla.
Ejemplo:
CALIDAD%LECHE
Este valor permite buscar plantillas cuyo nombre contenga la cadena CALIDAD seguida de LECHE.
El parámetro p_no_ranchos recibe un arreglo con los números de los ranchos que se desean consultar. Si se especifican uno o más ranchos, la consulta devolverá únicamente la información correspondiente a esos registros.
Ejemplos:
"40" → Devuelve únicamente la información del Rancho 40.
"227" → Devuelve únicamente la información de los Ranchos 40 y 227.
Estructura de la Respuesta
El servicio devuelve un arreglo de objetos JSON. Cada objeto representa una fila de datos retornada por la función y contiene los siguientes campos:
| Campo | Tipo de dato (SQL) | Descripción |
|---|---|---|
no_rancho | BIGINT | Número identificador del rancho, extraído de los campos personalizados. |
rancho | TEXT | Nombre del rancho, extraído de los campos personalizados. |
plantilla | TEXT | Nombre o título de la plantilla del trabajo (job_template_title). |
job_started_date | DATE | Fecha de inicio del trabajo, convertida desde UTC. |
asesor | TEXT | Nombre del Asesor que realizó el trabajo.. |
job_lookup_id | BIGINT | Cantidad total de trabajos agrupados bajo estos criterios (COUNT(DISTINCT job_id)). |
Datos Técnicos
- cURL
- Ejemplo
- Respuesta del servicio
- Función BD
- Ejemplo Función BD
curl --location '<url_base>/gc/v1/api/v1/catalogo/funcion/cat_parsable_visitas_asesor_dia' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--header 'ALP_AUTH: Bearer <access_token>' \
--data '[<p_inicio>,<p_fin>,<p_plantilla>,"{<p_no_ranchos>}"]'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<url_base>con los datos correspondientes del servicio. - Sustituir los marcadores
<access_token>con el token de Keycloak obtenido previamente. - Configurar en el cuerpo (
--data) los parámetros específicos que requiere el catálogo.
curl --location '<url_base>/gc/v1/api/v1/catalogo/funcion/cat_parsable_visitas_asesor_dia' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--header 'ALP_AUTH: Bearer <access_token>' \
--data '["2026-05-01", "2026-05-31", "CALIDAD%LECHE", "{40,227}"]'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<url_base>con los datos correspondientes del servicio. - Sustituir los marcadores
<access_token>con el token de Keycloak obtenido previamente.
{
"header": {
"code": 0,
"message": "OK"
},
"success": false,
"errors": null,
"data": {
"nombre": "Información de Visitas por Asesor / Dia ",
"esMaestro": false,
"appName": "parsable",
"registros": [
{
"no_rancho": 40,
"rancho": " EL OLIMPO ",
"plantilla": "SA 04-01 CALIDAD DE LECHE",
"job_started_date": "2026-05-20",
"asesor": "JUAN CARLOS MILLAN GALLEGOS",
"job_lookup_id": 4
},
{
"no_rancho": 40,
"rancho": " EL OLIMPO ",
"plantilla": "SA 04-01 CALIDAD DE LECHE",
"job_started_date": "2026-05-19",
"asesor": "JUAN CARLOS MILLAN GALLEGOS",
"job_lookup_id": 1
}
]
},
"newToken": null,
"hash": "F049614016EF662862FB0D24F1404BE52DD6F8BC31184C4BB018DCA4FB5460C7",
"totalRows": 9,
"page": null
}
CREATE OR REPLACE FUNCTION general_catalogs.alp_parsable_visitas_asesor_dia(p_inicio date, p_fin date, p_plantilla text, p_no_ranchos bigint[])
RETURNS TABLE(no_rancho bigint, rancho text, plantilla text, job_started_date date, asesor text, job_lookup_id bigint)
LANGUAGE sql
AS $function$
with alp_info as
( select job_id
, trim(split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'), '|', 1))::bigint no_rancho
, trim(split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'), '|', 2)) rancho
, job_template_title plantilla
, job_started_date_utc::date job_started_date
, max(field_value) filter (where field_label = 'Nombre de Asesor Técnico') asesor
from alp_cat_parsable
where step_hierarchy_position = '1'
and job_status <> 'Canceled'
and job_started_date_utc::date between p_inicio::date
and p_fin::date
and job_template_title like '%' || p_plantilla || '%'
group by job_id
, job_template_title
, job_started_date_utc::date
having split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'),'|',1)::bigint = any(p_no_ranchos))
select no_rancho
, rancho
, plantilla
, job_started_date
, asesor
, count(distinct job_id) job_lookup_id
from alp_info
group by no_rancho
, rancho
, plantilla
, job_started_date
, asesor
order by plantilla
, job_started_date desc
, asesor
, no_rancho
$function$
;
select *
from general_catalogs.alp_parsable_visitas_asesor_dia(
'2026-06-01',
'2026-06-30',
'SA-04-01 CALIDAD DE LECHE',
'{40,270}'
);
| Elemento | Valor |
|---|---|
| 🌐 Endpoint | /gc/v1/api/v1/catalogo/funcion/cat_parsable_tiempo_visitas |
| ⚙️ Método HTTP | POST |
| 📦 Content-Type | application/json |
| 🔒 Authorization | Bearer {access_token} |
| 🔒 ALP_AUTH | Bearer {access_token} |
| 🔗 Body WS | ["p_inicio", "p_fin","p_plantilla","{p_no_ranchos}"] |
| 🧩 Función BD | general_catalogs.alp_parsable_tiempo_visitas |
Los parámetros de p_inicio y p_fin deben enviarse utilizando el formato YYYY-MM-DD, de acuerdo con la siguiente estructura:
- YYYY: 4 dígitos para el año
- MM: 2 dígitos para el mes
- DD: 2 dígitos para el día
Ejemplo: 2026-06-01
El parámetro p_plantilla permite utilizar el carácter comodín % para realizar búsquedas parciales dentro del nombre de la plantilla.
Ejemplo:
CALIDAD%LECHE
Este valor permite buscar plantillas cuyo nombre contenga la cadena CALIDAD seguida de LECHE.
El parámetro p_no_ranchos recibe un arreglo con los números de los ranchos que se desean consultar. Si se especifican uno o más ranchos, la consulta devolverá únicamente la información correspondiente a esos registros.
Ejemplos:
"40" → Devuelve únicamente la información del Rancho 40.
"227" → Devuelve únicamente la información de los Ranchos 40 y 227.
Estructura de la Respuesta
El servicio devuelve un arreglo de objetos JSON. Cada objeto representa una fila de datos retornada por la función y contiene los siguientes campos:
| Campo | Tipo de dato (SQL) | Descripción |
|---|---|---|
no_rancho | BIGINT | Número identificador del rancho, extraído de los campos personalizados. |
rancho | TEXT | Nombre del rancho, extraído de los campos personalizados. |
plantilla | TEXT | Nombre o título de la plantilla del trabajo (job_template_title). |
job_started_date | DATE | Fecha de inicio del trabajo, convertida desde UTC. |
horas | NUMERIC | Son el total de Horas trabajadas. |
Datos Técnicos
- cURL
- Ejemplo
- Respuesta del servicio
- Función BD
- Ejemplo Función BD
curl --location '<url_base>/gc/v1/api/v1/catalogo/funcion/cat_parsable_tiempo_visitas' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--header 'ALP_AUTH: Bearer <access_token>' \
--data '[<p_inicio>,<p_fin>,<p_plantilla>,"{<p_no_ranchos>}"]'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<url_base>con los datos correspondientes del servicio. - Sustituir los marcadores
<access_token>con el token de Keycloak obtenido previamente. - Configurar en el cuerpo (
--data) los parámetros específicos que requiere el catálogo.
curl --location '<url_base>/gc/v1/api/v1/catalogo/funcion/cat_parsable_tiempo_visitas' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--header 'ALP_AUTH: Bearer <access_token>' \
--data '["2026-05-01", "2026-05-31", "CALIDAD%LECHE", "{40,227}"]'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<url_base>con los datos correspondientes del servicio. - Sustituir los marcadores
<access_token>con el token de Keycloak obtenido previamente.
{
"header": {
"code": 0,
"message": "OK"
},
"success": false,
"errors": null,
"data": {
"nombre": "Información de Tiempo Visita",
"esMaestro": false,
"appName": "parsable",
"registros": [
{
"no_rancho": 102,
"rancho": " GRANJA MAGAN ",
"plantilla": "SA-04-01 CALIDAD DE LECHE",
"fecha": "2026-05-27",
"horas": 245.21
},
{
"no_rancho": 1275,
"rancho": " CEDROS ",
"plantilla": "SA-04-01 CALIDAD DE LECHE",
"fecha": "2026-05-27",
"horas": 6.75
}
]
},
"newToken": null,
"hash": "AAC996E31A561A6EE057F3288CF4F81F6F874C48FFD23F9940001A76B4A78291",
"totalRows": 35,
"page": null
}
CREATE OR REPLACE FUNCTION general_catalogs.alp_parsable_tiempo_visitas(p_inicio date, p_fin date, p_plantilla text, p_no_ranchos bigint[])
RETURNS TABLE(no_rancho bigint, rancho text, plantilla text, fecha date, horas numeric)
LANGUAGE sql
AS $function$
select trim(split_part(rancho, '|', 1))::bigint no_rancho
, trim(split_part(rancho, '|', 2)) rancho
, job_template_title plantilla
, job_started_date fecha
, trunc(sum(segundos) / 3600,2) horas
from ( select job_id
, max(field_value) filter (where lower(field_label) like '%nombre de rancho%') rancho
, job_template_title
, job_started_date_utc::date job_started_date
, job_started_date_utc
, job_completed_date_utc
, coalesce(extract(EPOCH from (job_completed_date_utc - job_started_date_utc)),0) segundos
, extract(EPOCH from (job_completed_date_utc - job_started_date_utc)) / 3600 horas
from alp_cat_parsable
where job_status <> 'Canceled'
and job_started_date_utc::date between p_inicio::date
and p_fin::date
and job_template_title like '%' || p_plantilla || '%'
group by job_id
, job_template_title
, job_started_date_utc
, job_completed_date_utc
having split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'),'|',1)::bigint = any(p_no_ranchos))
group by rancho
, job_template_title
, job_started_date
, trim(split_part(rancho, '|', 1))::bigint
$function$
;
select *
from general_catalogs.alp_parsable_tiempo_visitas(
'2026-06-01',
'2026-06-30',
'SA-04-01 CALIDAD DE LECHE',
'{40,270}'
);
| Elemento | Valor |
|---|---|
| 🌐 Endpoint | /gc/v1/api/v1/catalogo/funcion/cat_parsable_resumen_tiempo_visitas |
| ⚙️ Método HTTP | POST |
| 📦 Content-Type | application/json |
| 🔒 Authorization | Bearer {access_token} |
| 🔒 ALP_AUTH | Bearer {access_token} |
| 🔗 Body WS | ["p_inicio", "p_fin","p_plantilla","{p_no_ranchos}"] |
| 🧩 Función BD | general_catalogs.alp_parsable_resumen_tiempo_visitas |
Los parámetros de p_inicio y p_fin deben enviarse utilizando el formato YYYY-MM-DD, de acuerdo con la siguiente estructura:
- YYYY: 4 dígitos para el año
- MM: 2 dígitos para el mes
- DD: 2 dígitos para el día
Ejemplo: 2026-06-01
El parámetro p_plantilla permite utilizar el carácter comodín % para realizar búsquedas parciales dentro del nombre de la plantilla.
Ejemplo:
CALIDAD%LECHE
Este valor permite buscar plantillas cuyo nombre contenga la cadena CALIDAD seguida de LECHE.
El parámetro p_no_ranchos recibe un arreglo con los números de los ranchos que se desean consultar. Si se especifican uno o más ranchos, la consulta devolverá únicamente la información correspondiente a esos registros.
Ejemplos:
"40" → Devuelve únicamente la información del Rancho 40.
"227" → Devuelve únicamente la información de los Ranchos 40 y 227.
Estructura de la Respuesta
El servicio devuelve un arreglo de objetos JSON. Cada objeto representa una fila de datos retornada por la función y contiene los siguientes campos:
| Campo | Tipo de dato (SQL) | Descripción |
|---|---|---|
no_rancho | TEXT | Número identificador del rancho. |
nombre_rancho | TEXT | Nombre del rancho. |
plantilla | TEXT | Nombre o título de la plantilla del trabajo. |
job_started_date | TIMESTAMP | Fecha y hora de inicio del trabajo. |
job_id | TEXT | Identificador único del trabajo realizado. |
tipo_visita | TEXT | Tipo de visita realizada. |
region | TEXT | Región a la que pertenece el rancho. |
rancho | TEXT | Nombre o descripción del rancho asociado a la visita. |
titulo_visita | TEXT | Título o nombre de la visita realizada. |
firma_asesor_real | TEXT | Firma registrada del asesor responsable de la visita (Id de Alfresco). |
firma_socio_real | TEXT | Firma registrada del socio o responsable del rancho (Id de Alfresco). |
fecha_firma_socio | TIMESTAMP | Fecha y hora en que se registró la firma del socio. |
horas_visita | NUMERIC | Cantidad de horas registradas para la visita. |
Datos Técnicos
- cURL
- Ejemplo
- Respuesta del servicio
- Función BD
- Ejemplo Función BD
curl --location '<url_base>/gc/v1/api/v1/catalogo/funcion/cat_parsable_resumen_tiempo_visitas' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--header 'ALP_AUTH: Bearer <access_token>' \
--data '[<p_inicio>,<p_fin>,<p_plantilla>,"{<p_no_ranchos>}"]'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<url_base>con los datos correspondientes del servicio. - Sustituir los marcadores
<access_token>con el token de Keycloak obtenido previamente. - Configurar en el cuerpo (
--data) los parámetros específicos que requiere el catálogo.
curl --location '<url_base>/gc/v1/api/v1/catalogo/funcion/cat_parsable_resumen_tiempo_visitas' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--header 'ALP_AUTH: Bearer <access_token>' \
--data '["2026-05-01", "2026-05-31", "CALIDAD%LECHE", "{40,227}"]'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<url_base>con los datos correspondientes del servicio. - Sustituir los marcadores
<access_token>con el token de Keycloak obtenido previamente.
{
"header": {
"code": 0,
"message": "OK"
},
"success": false,
"errors": null,
"data": {
"nombre": "Información de Resumen Tiempo Visita",
"esMaestro": false,
"appName": "parsable",
"registros": [
{
"no_rancho": null,
"nombre_rancho": null,
"plantilla": "SA 04-01 CALIDAD DE LECHE",
"job_started_date": "2026-05-20T22:35:20.000+00:00",
"job_id": "Job-185",
"tipo_visita": null,
"region": null,
"rancho": null,
"titulo_visita": "SA-02-01 Salud del Hato",
"firma_asesor_real": null,
"firma_socio_real": null,
"fecha_firma_socio": null,
"horas_visita": 0.00
},
{
"no_rancho": null,
"nombre_rancho": null,
"plantilla": "SA 04-01 CALIDAD DE LECHE",
"job_started_date": "2026-05-20T22:34:36.000+00:00",
"job_id": "Job-184",
"tipo_visita": null,
"region": null,
"rancho": null,
"titulo_visita": "SA-02-01 Salud del Hato",
"firma_asesor_real": null,
"firma_socio_real": null,
"fecha_firma_socio": null,
"horas_visita": 0.01
}
]
},
"newToken": null,
"hash": "53C0FC0E83ABBC3A9641F1F71AF41BA6B5BA42A5BAF67C4C51E9886A03FB1FFD",
"totalRows": 37,
"page": null
}
CREATE OR REPLACE FUNCTION general_catalogs.alp_parsable_resumen_tiempo_visitas(p_inicio date, p_fin date, p_plantilla text, p_no_ranchos bigint[])
RETURNS TABLE(no_rancho bigint, nombre_rancho text, plantilla text, job_started_date timestamp without time zone, job_id text, tipo_visita text, region text, rancho text, titulo_visita text, firma_asesor_real text, firma_socio_real text, fecha_firma_socio timestamp without time zone, horas_visita numeric)
LANGUAGE sql
AS $function$
select split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'), '|', 1)::bigint no_rancho
, trim(split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'), '|', 2)) nombre_rancho
, job_template_title plantilla
, job_started_date_utc job_started_date
, job_id
, max(field_value) filter (where field_label = 'Visita') tipo_visita
, max(field_value) filter (where field_label = 'REGION') region
, trim(split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'), '|', 1))
|| ' | '
|| trim(split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'), '|', 2)) nombre_rancho
, job_title titulo_visita
, max(field_value) filter (where lower(field_label) like '%firma%asesor%') firma_asesor_real
, max(field_value) filter (where lower(field_label) like '%firma%socio%') firma_socio_real
, max(field_last_updated_date_utc) filter (where lower(field_label) like '%firma%socio%') fecha_firma_socio
, trunc(coalesce(extract(epoch from (job_completed_date_utc - job_started_date_utc)),0::numeric) / 3600,2) horas_visita
from alp_cat_parsable
where job_status <> 'Canceled'
and job_started_date_utc::date between p_inicio::date
and p_fin::date
and job_template_title like '%' || p_plantilla || '%'
group by job_title
, job_template_title
, job_started_date_utc
, job_completed_date_utc
, job_id
having split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'),'|',1)::bigint = any(p_no_ranchos)
order by job_template_title
, job_started_date_utc desc
, replace(job_id, 'Job-', '')::bigint desc
, trim(split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'), '|', 1))::bigint
$function$
;
select *
from general_catalogs.alp_parsable_resumen_tiempo_visitas(
'2026-06-01',
'2026-06-30',
'SA-04-01 CALIDAD DE LECHE',
'{40,270}'
);
5.2. Información de los Servicios Deviations
- Desviaciones
- Resumen Desviaciones
| Elemento | Valor |
|---|---|
| 🌐 Endpoint | /gc/v1/api/v1/catalogo/funcion/cat_parsable_deviations |
| ⚙️ Método HTTP | POST |
| 📦 Content-Type | application/json |
| 🔒 Authorization | Bearer {access_token} |
| 🔒 ALP_AUTH | Bearer {access_token} |
| 🔗 Body WS | ["p_inicio", "p_fin","p_plantilla","{p_no_ranchos}"] |
| 🧩 Función BD | general_catalogs.alp_parsable_deviations |
Los parámetros de p_inicio y p_fin deben enviarse utilizando el formato YYYY-MM-DD, de acuerdo con la siguiente estructura:
- YYYY: 4 dígitos para el año
- MM: 2 dígitos para el mes
- DD: 2 dígitos para el día
Ejemplo: 2026-06-01
El parámetro p_plantilla permite utilizar el carácter comodín % para realizar búsquedas parciales dentro del nombre de la plantilla.
Ejemplo:
CALIDAD%LECHE
Este valor permite buscar plantillas cuyo nombre contenga la cadena CALIDAD seguida de LECHE.
El parámetro p_no_ranchos recibe un arreglo con los números de los ranchos que se desean consultar. Si se especifican uno o más ranchos, la consulta devolverá únicamente la información correspondiente a esos registros.
Ejemplos:
"40" → Devuelve únicamente la información del Rancho 40.
"227" → Devuelve únicamente la información de los Ranchos 40 y 227.
Estructura de la Respuesta
El servicio devuelve un arreglo de objetos JSON. Cada objeto representa una fila de datos retornada por la función y contiene los siguientes campos:
| Campo | Tipo de dato (SQL) | Descripción |
|---|---|---|
fecha_desviacion | TIMESTAMP | Fecha y hora en que se registró la desviación, expresada en formato ISO 8601. |
nombre_paso | TEXT | Nombre del paso o actividad del proceso donde se identificó la desviación. |
numero_desviaciones | TEXT | Número de desviaciones identificadas para el paso y fecha correspondientes. |
Datos Técnicos
- cURL
- Ejemplo
- Respuesta del servicio
- Función BD
- Ejemplo Función BD
curl --location '<url_base>/gc/v1/api/v1/catalogo/funcion/cat_parsable_deviations' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--header 'ALP_AUTH: Bearer <access_token>' \
--data '[<p_inicio>,<p_fin>,<p_plantilla>,"{<p_no_ranchos>}"]'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<url_base>con los datos correspondientes del servicio. - Sustituir los marcadores
<access_token>con el token de Keycloak obtenido previamente. - Configurar en el cuerpo (
--data) los parámetros específicos que requiere el catálogo.
curl --location '<url_base>/gc/v1/api/v1/catalogo/funcion/cat_parsable_deviations' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--header 'ALP_AUTH: Bearer <access_token>' \
--data '["2026-05-01", "2026-05-31", "CALIDAD%LECHE", "{40,134,219}"]'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<url_base>con los datos correspondientes del servicio. - Sustituir los marcadores
<access_token>con el token de Keycloak obtenido previamente.
{
"header": {
"code": 0,
"message": "OK"
},
"success": false,
"errors": null,
"data": {
"nombre": "Información de las Desviaciones",
"esMaestro": false,
"appName": "parsable",
"registros": [
{
"fecha_desviacion": "2026-08-03T06:00:00.000+00:00",
"nombre_paso": "Lavado y desinfección de equipo, termo, y/o silo",
"numero_desviaciones": "1"
},
{
"fecha_desviacion": "2026-08-07T06:00:00.000+00:00",
"nombre_paso": "Lavado y desinfección de equipo, termo, y/o silo",
"numero_desviaciones": "1"
},
{
"fecha_desviacion": "2026-08-07T06:00:00.000+00:00",
"nombre_paso": "Parámetros de Calidad",
"numero_desviaciones": "2"
}
]
},
"newToken": null,
"hash": "F5A299193B52DB1A329646F2C7210DBD6EAFF720B4C0E370992C8574C48C66DD",
"totalRows": 20,
"page": null
}
CREATE OR REPLACE FUNCTION general_catalogs.alp_parsable_deviations(p_inicio date, p_fin date, p_plantilla text, p_no_ranchos bigint[])
RETURNS TABLE(fecha_desviacion timestamp without time zone, nombre_paso text, numero_desviaciones text)
LANGUAGE sql
AS $function$
with alp_parsable_jobs as
( select job_id
from alp_cat_parsable_jobs
where job_status <> 'Canceled'
and job_started_date_utc::date between p_inicio::date
and p_fin::date
and job_template_title like '%' || p_plantilla || '%'
group by job_id
having split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'),'|',1)::bigint = any(p_no_ranchos))
select acpd.deviation_created_date_utc::date fecha_desviacion
, acpd.deviation_step_title nombre_paso
, count(*) numero_desviaciones
from alp_parsable_jobs apj
join alp_cat_parsable_deviations acpd
on apj.job_id = acpd.job_id
where acpd.deviation_type <> 'DEVIATION_STEP_INCOMPLETE'
group by acpd.deviation_created_date_utc::date
, acpd.deviation_step_title
order by acpd.deviation_created_date_utc::date
, acpd.deviation_step_title
$function$
;
select *
from general_catalogs.alp_parsable_deviations(
'2026-08-01',
'2026-08-30',
'CALIDAD%LECHE',
'{40,134,219}'
);
| Elemento | Valor |
|---|---|
| 🌐 Endpoint | /gc/v1/api/v1/catalogo/funcion/cat_parsable_resumen_deviations |
| ⚙️ Método HTTP | POST |
| 📦 Content-Type | application/json |
| 🔒 Authorization | Bearer {access_token} |
| 🔒 ALP_AUTH | Bearer {access_token} |
| 🔗 Body WS | ["p_inicio", "p_fin","p_plantilla","{p_no_ranchos}"] |
| 🧩 Función BD | general_catalogs.alp_parsable_resumen_deviations |
Los parámetros de p_inicio y p_fin deben enviarse utilizando el formato YYYY-MM-DD, de acuerdo con la siguiente estructura:
- YYYY: 4 dígitos para el año
- MM: 2 dígitos para el mes
- DD: 2 dígitos para el día
Ejemplo: 2026-06-01
El parámetro p_plantilla permite utilizar el carácter comodín % para realizar búsquedas parciales dentro del nombre de la plantilla.
Ejemplo:
CALIDAD%LECHE
Este valor permite buscar plantillas cuyo nombre contenga la cadena CALIDAD seguida de LECHE.
El parámetro p_no_ranchos recibe un arreglo con los números de los ranchos que se desean consultar. Si se especifican uno o más ranchos, la consulta devolverá únicamente la información correspondiente a esos registros.
Ejemplos:
"40" → Devuelve únicamente la información del Rancho 40.
"227" → Devuelve únicamente la información de los Ranchos 40 y 227.
Estructura de la Respuesta
El servicio devuelve un arreglo de objetos JSON. Cada objeto representa una fila de datos retornada por la función y contiene los siguientes campos:
| Campo | Tipo de dato (SQL) | Descripción |
|---|---|---|
fecha_inicio | TIMESTAMP | Fecha y hora de inicio del trabajo, convertida desde UTC a la zona horaria correspondiente. |
job_id | TEXT | Identificador único del trabajo (Job_id) en Parsable. |
visita | TEXT | Estatus o tipo de visita asociado al trabajo. |
region | TEXT | Región geográfica a la que pertenece el trabajo, obtenida de los campos personalizados. |
nombre_rancho | TEXT | Nombre del rancho donde se realizó el trabajo, obtenido de los campos personalizados. |
titulo_visita | TEXT | Título de la visita o nombre de la plantilla asociada al trabajo (job_template_title). |
deviation_type | TEXT | Tipo de desviación identificada durante la ejecución del trabajo. |
nombre_paso | TEXT | Nombre del paso o actividad dentro del trabajo en el que se registró la información. |
campo_entrada | TEXT | Nombre o identificador del campo de entrada donde se capturó la información. |
valor_capturado | TEXT | Valor registrado en el campo de entrada durante la ejecución del trabajo. |
Datos Técnicos
- cURL
- Ejemplo
- Respuesta del servicio
- Función BD
- Ejemplo Función BD
curl --location '<url_base>/gc/v1/api/v1/catalogo/funcion/cat_parsable_resumen_deviations' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--header 'ALP_AUTH: Bearer <access_token>' \
--data '[<p_inicio>,<p_fin>,<p_plantilla>,"{<p_no_ranchos>}"]'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<url_base>con los datos correspondientes del servicio. - Sustituir los marcadores
<access_token>con el token de Keycloak obtenido previamente. - Configurar en el cuerpo (
--data) los parámetros específicos que requiere el catálogo.
curl --location '<url_base>/gc/v1/api/v1/catalogo/funcion/cat_parsable_resumen_deviations' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--header 'ALP_AUTH: Bearer <access_token>' \
--data '["2026-08-01", "2026-08-31", "CALIDAD%LECHE", "{40,134,219}"]'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<url_base>con los datos correspondientes del servicio. - Sustituir los marcadores
<access_token>con el token de Keycloak obtenido previamente.
{
"header": {
"code": 0,
"message": "OK"
},
"success": false,
"errors": null,
"data": {
"nombre": "Información de Resumen Desviaciones",
"esMaestro": false,
"appName": "parsable",
"registros": [
{
"fecha_inicio": "2026-08-21T06:00:00.000+00:00",
"job_id": "Job-10923",
"visita": "Programada",
"region": "QUERETARO",
"nombre_rancho": "134 | SAN FANDILA",
"titulo_visita": "SA-04-01 Calidad de leche: Programada-QUERETARO-EUGENIO ISMAEL OLGUÍN PRADO-134 | SAN FANDILA-2026-08-21",
"deviation_type": "DEVIATION_VALIDATION_TRIGGERED",
"nombre_paso": "Lavado y desinfección de equipo, termo, y/o silo",
"campo_entrada": "¿Considera la visita para revisión de lavado de equipo, termo y/o silo?",
"valor_capturado": "yes"
},
{
"fecha_inicio": "2026-08-21T06:00:00.000+00:00",
"job_id": "Job-10923",
"visita": "Programada",
"region": "QUERETARO",
"nombre_rancho": "134 | SAN FANDILA",
"titulo_visita": "SA-04-01 Calidad de leche: Programada-QUERETARO-EUGENIO ISMAEL OLGUÍN PRADO-134 | SAN FANDILA-2026-08-21",
"deviation_type": "DEVIATION_VALIDATION_TRIGGERED",
"nombre_paso": "Parámetros de Calidad",
"campo_entrada": "Promedio semanal de Bacteriología en tanque. (<2,500 U.F.C/ml.)",
"valor_capturado": "3160.0"
},
{
"fecha_inicio": "2026-08-21T06:00:00.000+00:00",
"job_id": "Job-10923",
"visita": "Programada",
"region": "QUERETARO",
"nombre_rancho": "134 | SAN FANDILA",
"titulo_visita": "SA-04-01 Calidad de leche: Programada-QUERETARO-EUGENIO ISMAEL OLGUÍN PRADO-134 | SAN FANDILA-2026-08-21",
"deviation_type": "DEVIATION_VALIDATION_TRIGGERED",
"nombre_paso": "Parámetros de Calidad",
"campo_entrada": "Promedio semanal de Bacteriología en tanque. (<2,500 U.F.C/ml.)",
"valor_capturado": "3270.0"
}
]
},
"newToken": null,
"hash": "2272BBDBBAB567F0033B2162985A6E47133ADA8103C8DA526C36F26051188161",
"totalRows": 31,
"page": null
}
CREATE OR REPLACE FUNCTION general_catalogs.alp_parsable_resumen_deviations(p_inicio date, p_fin date, p_plantilla text, p_no_ranchos bigint[])
RETURNS TABLE(fecha_inicio timestamp without time zone, job_id text, visita text, region text, nombre_rancho text, titulo_visita text, deviation_type text, nombre_paso text, campo_entrada text, valor_capturado text)
LANGUAGE sql
AS $function$
with alp_parsable_jobs as
( select job_id
, max(field_value) filter (where field_label = 'Visita') visita
, max(field_value) filter (where field_label = 'REGION') region
, trim(split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'), '|', 1))
|| ' | '
|| trim(split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'), '|', 2)) nombre_rancho
from alp_cat_parsable_jobs
where job_status <> 'Canceled'
and job_started_date_utc::date between p_inicio::date
and p_fin::date
and job_template_title like '%' || p_plantilla || '%'
group by job_id
having split_part(max(field_value) filter (where lower(field_label) like '%nombre de rancho%'),'|',1)::bigint = any(p_no_ranchos))
select acpd.deviation_created_date_utc::date fecha_inicio
, apj.job_id
, apj.visita
, apj.region
, apj.nombre_rancho
, acpd.job_title titulo_visita
, acpd.deviation_type
, acpd.deviation_step_title nombre_paso
, acpd.deviation_field_label campo_entrada
, acpd.deviation_field_value valor_capturado
from alp_parsable_jobs apj
join alp_cat_parsable_deviations acpd
on apj.job_id = acpd.job_id
where acpd.deviation_type <> 'DEVIATION_STEP_INCOMPLETE'
order by apj.job_id
, acpd.deviation_step_title
$function$
;
select *
from general_catalogs.alp_parsable_resumen_deviations(
'2026-08-01',
'2026-08-30',
'CALIDAD%LECHE',
'{40,134,219}'
);
5.3. Recuperación de Imagenes de Alfresco
| Elemento | Valor |
|---|---|
| 🌐 Endpoint | <url_alfresco>/nodes/<file_alfresco_id>/content |
| ⚙️ Método HTTP | GET |
| 🔒 Authorization | Basic Auth |
El identificador file_alfresco_id se obtiene de las columnas firma_asesor_real y firma_socio_real que se encuentra en el servicio de Jobs Resumen Tiempo Visita.
Estructura de la Respuesta
Recupera la imagen vinculada desde el repositorio de Alfresco mediante el identificador file_alfresco_id.
Datos Técnicos
- cURL
- Ejemplo
curl --location '<url_alfresco>/nodes/<file_alfresco_id>/content' \
--header 'Authorization: ••••••'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<file_alfresco_id>: Utiliza el identificador obtenido de las columnas firma_asesor_real o firma_socio_real del servicio JobsResumen Tiempo Visita. - Autenticación básica: Proporciona las credenciales requeridas en el encabezado Authorization.
curl --location '<url_alfresco>/nodes/c55c9e2e-2f28-4817-9c9e-2e2f28b81778/content' \
--header 'Authorization: ••••••'
Puedes ejecutar la petición directamente desde tu terminal utilizando el siguiente comando curl. Asegúrate de:
- Reemplazar
<url_alfresco>con los datos correspondientes del servicio. - Autenticación básica: Proporciona las credenciales requeridas en el encabezado Authorization.