Entregas 'Fáciles'¶
La OCDS fomenta el uso del modelo entregas y registros para publicar datos actualizados y oportunos. Sin embargo, a veces los publicadores no pueden adoptar completamente el modelo, porque los datos históricos de los procesos de contratación no se almacenan en el(los) sistema(s) fuente. En este caso, el publicador solo puede producir una entrega para cada proceso de contratación, y la entrega se anula con nuevas actualizaciones.
En esta situación, es todavía posible cumplir los requerimientos de OCDS siguiendo una estrategia para construir diferentes identificadores de entrega cada vez que los datos cambien en un proceso de contratación. Durante el transcurso de múltiples actualizaciones, terceros serían capaces de construir su propio almacenamiento de datos descargando o recolectando los datos publicados periódicamente, e identificando las actualizaciones usando los identificadores de entrega.
Aquí se mostrarán dos enfoques generales que un publicador puede seguir para renovar los identificadores de entrega en cada actualización de datos:
Cuando el sistema almacena una fecha de última modificación para las entidades - use las fechas para crear un nuevo ID de entrega. Esto puede ser tan simple como adjuntar la fecha al final del identificador de entrega.
Cuando el sistema no contiene una fecha de última modificación - use un hash de todos los campos para crear un ID de entrega único. Está garantizado que un hash cambiará cuando los datos cambien, y es casi imposible que este colisione con un identificador previo ya existente para el mismo proceso de contratación.
Vea los ejemplos de abajo para más detalles.
Estos enfoques pueden ser útiles para la mayoría de las situaciones pero no están pensados para ser la mejor solución en todos los casos. Un publicador puede encontrar una alternativa que funcione mejor para su propio escenario.
Consideraciones Adicionales¶
Empaquetado¶
Las entregas en OCDS necesitan ser empaquetadas usando un paquete de entregas. Esto sirve para proveer consistencia y metadatos importantes.
En un escenario de entregas 'Easy' todavía es necesario empaquetar datos. Por lo tanto, la entrega necesita estar envuelta en un paquete de entregas. No es apropiado usar un registro de OCDS para contener la entrega porque record.releases
es una lista de todas las entregas y no sólo de la última.
Ejemplos Prácticos¶
Para los ejemplos en esta sección, se asume la arquitectura mostrada en la imagen de abajo.
Los datos son extraídos de la fuente y transformados a OCDS cada vez que hay una petición, y los archivos JSON resultantes no son almacenados por el dueño.
Escenario 1: cuando se almacena una fecha de última modificación¶
La estructura de base de datos de muestra usada para el presente ejemplo se ilustra en la imagen de abajo.
La tabla 'ProcurementProcess' contiene una sola fila por cada proceso de contratación en el sistema, y la fila es actualizada con cada cambio. Los contratos y proveedores son guardados en tablas separadas. Para las tablas 'ProcurementProcess' y 'Contract' existe una columna llamada lastModifiedDate
, con una marca de tiempo para el último cambio hecho a la fila.
Los siguientes pasos muestran el progreso en un único proceso de contratación, y cómo el identificador único de entrega es construido con cada actualización.
1. Tender initiation¶
El proceso de contratación comienza con un aviso de licitación. Las tablas fuentes contienen los siguientes datos:
ProcurementProcess
processID |
title |
stage |
description |
procurementMethod |
bidSubmissionOpenDate |
bidSubmissionCloseDate |
tenderValue |
tenderCurrency |
buyerID |
buyerName |
awardDate |
awardValue |
awardCurrency |
createdAt |
lastModifiedAt |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
371630 |
Cleaning services |
tender |
Cleaning services for the City Hall |
direct |
2019-12-14T08:00:00Z |
2019-12-14T08:30:00Z |
144300000 |
PYG |
80023736-6 |
City Hall of Juan de Mena |
2019-12-01T09:00:00Z |
2019-12-01T09:00:00Z |
Aún no existen un proveedor o contrato, por lo que no hay entradas en estas tablas para este proceso de contratación. En esta etapa, el ocid es construido añadiendo el valor del campo processID
al prefijo ocid ('ocds-213czf'), ya que processID
está identificando de manera única a cada proceso de contratación.
{
"ocid": "ocds-213czf-371630"
}
Para el ID de entrega, el valor de lastModifiedAt
es añadido al final del ocid:
{
"id": "ocds-213czf-371630/2019-12-01T09:00:00Z"
}
Es posible usar sólo la fecha como el identificador de la entrega, pero colocar el ocid al comienzo hace que sea más fácil diferenciar entregas de varios procesos en el mismo paquete de entregas.
Vea el archivo JSON completo abajo.
2. Tender update¶
The tender has been updated: the value increased slightly and the description has changed.
ProcurementProcess
processID |
title |
stage |
description |
procurementMethod |
bidSubmissionOpenDate |
bidSubmissionCloseDate |
tenderValue |
tenderCurrency |
buyerID |
buyerName |
awardDate |
awardValue |
awardCurrency |
createdAt |
lastModifiedAt |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
371630 |
Cleaning services |
tender |
Cleaning services for the City Hall, from 01/2020 to 12/2020 |
direct |
2019-12-14T08:00:00Z |
2019-12-14T08:30:00Z |
145000000 |
PYG |
1000 |
City Hall of Juan de Mena |
2019-12-01T09:00:00Z |
2019-12-03T09:00:00Z |
El valor de lastModifiedDate
ha cambiado también, por lo tanto el valor del identificador de entrega cambiará:
{
"id": "ocds-213czf-371630/2019-12-03T09:00:00Z"
}
Vea el JSON completo abajo:
Note que el campo tag
todavía tiene el valor de 'tender'.
3. Award¶
Ahora, la licitación ha sido adjudicada. Las columnas relacionadas en la tabla de 'ProcurementProcess' han sido llenadas y ahora hay una nueva fila en la tabla 'Supplier' para el proceso.
ProcurementProcess
processID |
title |
stage |
description |
procurementMethod |
bidSubmissionOpenDate |
bidSubmissionCloseDate |
tenderValue |
tenderCurrency |
buyerID |
buyerName |
awardDate |
awardValue |
awardCurrency |
createdAt |
lastModifiedAt |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
371630 |
Cleaning services |
award |
Cleaning services for the City Hall |
direct |
2019-12-14T08:00:00Z |
2019-12-14T08:30:00Z |
144300000 |
PYG |
80023736-6 |
City Hall of Juan de Mena |
2019-12-26T14:00:00Z |
PYG |
144300000 |
2019-12-01T09:00:00Z |
2019-12-27T14:42:00Z |
Supplier
supplierID |
processID |
name |
companyID |
contactName |
contactEmail |
---|---|---|---|---|---|
144 |
371630 |
Bosques del Parana SRL |
80020095-0 |
Juan Torres |
Ya que la tabla 'ProcurementProcess' ha sido actualizada, la entrega relacionada tendrá un nuevo id:
{
"id": "ocds-213czf-371630/2019-12-14T14:42:00Z"
}
Y la sección de 'awards' será llenada con los datos correspondientes. Vea el JSON completo abajo.
Note que estamos manteniendo la etiqueta 'tender' del paso previo.
4. Contract¶
En la última etapa hay un contrato firmado. La tabla de 'ProcurementProcess' cambia de nuevo para reflejar la nueva etapa, y una nueva entrada es añadida a la tabla de 'Contract' como se muestra abajo.
ProcurementProcess
processID |
title |
stage |
description |
procurementMethod |
bidSubmissionOpenDate |
bidSubmissionCloseDate |
tenderValue |
tenderCurrency |
buyerID |
buyerName |
awardDate |
awardValue |
awardCurrency |
createdAt |
lastModifiedAt |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
371630 |
Cleaning services |
contract |
Cleaning services for the City Hall |
direct |
2019-12-14T08:00:00Z |
2019-12-14T08:30:00Z |
144300000 |
PYG |
80023736-6 |
City Hall of Juan de Mena |
2019-12-26T14:00:00Z |
PYG |
144300000 |
2019-12-01T09:00:00Z |
2020-01-11T07:53:50Z |
Contract
contractID |
processID |
status |
signedDate |
value |
currency |
startDate |
endDate |
createdAt |
lastModifiedAt |
---|---|---|---|---|---|---|---|---|---|
100 |
371630 |
active |
2019-01-10T10:00:00Z |
116400000 |
PYG |
2019-01-15T08:00:00Z |
2020-01-14T17:00:00Z |
2020-01-11T07:53:50Z |
2020-01-11T07:53:50Z |
Un nuevo id de release es generado:
{
"id": "ocds-213czf-371630/2020-01-11T07:53:50Z"
}
Vea el JSON completo abajo.
Escenario 2: cuando NO se almacena una fecha de última modificación¶
Este enfoque puede ser usado cuando no existe una fecha de última modificación en los datos fuente. Abajo hay una imagen actualizada del ejemplo anterior:
El ejemplo es casi el mismo que el anterior, con los mismos pasos, pero no hay una fecha de última modificación en las tablas así como se ve en la imagen de arriba.
1. Tender initiation¶
El ejemplo empieza con la licitación, y los siguientes datos en la tabla de 'ProcurementProcess':
ProcurementProcess
processID |
title |
stage |
description |
procurementMethod |
bidSubmissionOpenDate |
bidSubmissionCloseDate |
tenderValue |
tenderCurrency |
buyerID |
buyerName |
awardDate |
awardValue |
awardCurrency |
createdAt |
lastModifiedAt |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
371630 |
Cleaning services |
tender |
Cleaning services for the City Hall |
direct |
2019-12-14T08:00:00Z |
2019-12-14T08:30:00Z |
144300000 |
PYG |
80023736-6 |
City Hall of Juan de Mena |
2019-12-01T09:00:00Z |
2019-12-01T09:00:00Z |
El identificador único para esta etapa puede ser generado uniendo todos los campos en una sola cadena, y aplicando una función de hash sobre ella. Dependiendo de las herramientas y/o lenguajes de programación usados en el proceso de transformación, hay muchas maneras de lograr esta tarea. Abajo se muestra un ejemplo de cómo puede hacerse esto usando una consulta en PostgreSQL:
SELECT md5(CAST((p.*)AS text))
FROM ProcurementProcess p
WHERE p.processID = 371630
;
Es importante incluir todos los campos de datos que son incluidos en los datos OCDS en el cálculo del hash. Para la fila actual, el valor de salida es 69a19ab9713d08bc7c54793144997d3a
. Como con el campo de fecha en el ejemplo previo, esto se añadirá al final del ocid:
{
"id": "ocds-213czf-371630/69a19ab9713d08bc7c54793144997d3a"
}
Vea el JSON completo abajo.
2. Tender update¶
Ahora que los datos de licitación han cambiado: hay actualizaciones en los campos de valor y descripción.
ProcurementProcess
processID |
title |
stage |
description |
procurementMethod |
bidSubmissionOpenDate |
bidSubmissionCloseDate |
tenderValue |
tenderCurrency |
buyerID |
buyerName |
awardDate |
awardValue |
awardCurrency |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
371630 |
Cleaning services |
tender |
Cleaning services for the City Hall, from 01/2020 to 12/2020 |
direct |
2019-12-14T08:00:00Z |
2019-12-14T08:30:00Z |
145000000 |
PYG |
1000 |
City Hall of Juan de Mena |
La misma operación de hash se repite sobre la fila actualizada y el valor resultante es 957969e7458f5144a931d2feb452ea48
. El nuevo identificador de entrega es:
{
"id": "ocds-213czf-371630/957969e7458f5144a931d2feb452ea48"
}
Vea el JSON completo abajo.
3. Award¶
La licitación ha sido adjudicada, por lo tanto la tabla 'ProcurementProcess' ha sido actualizada y una nueva entrada en la tabla de 'Supplier' es incluida.
ProcurementProcess
processID |
title |
stage |
description |
procurementMethod |
bidSubmissionOpenDate |
bidSubmissionCloseDate |
tenderValue |
tenderCurrency |
buyerID |
buyerName |
awardDate |
awardValue |
awardCurrency |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
371630 |
Cleaning services |
award |
Cleaning services for the City Hall |
direct |
2019-12-14T08:00:00Z |
2019-12-14T08:30:00Z |
144300000 |
PYG |
80023736-6 |
City Hall of Juan de Mena |
2019-12-26T14:00:00Z |
PYG |
144300000 |
Supplier
supplierID |
processID |
name |
companyID |
contactName |
contactEmail |
---|---|---|---|---|---|
144 |
371630 |
Bosques del Parana SRL |
80020095-0 |
Juan Torres |
Los nuevos datos en la tabla de 'Supplier' también pueden ser incluidos en la generación del hash. En PostgreSQL, la sentencia anterior puede ser cambiada para incluir la tabla 'Supplier' como sigue:
WITH data AS (
SELECT * from ProcurementProcess
JOIN Supplier on Supplier.processID = ProcurementProcess.processID
WHERE processID = 371630
)
SELECT md5(CAST((data.*)AS text)) FROM data
;
El resultado de la consulta es 610d5900f947bcf67100449999ea49ce
, y el nuevo identificador de entrega es:
{
"id": "ocds-213czf-371630/610d5900f947bcf67100449999ea49ce"
}
Vea el JSON completo abajo.
4. Contract¶
En la última etapa el contrato es firmado, la tabla de 'ProcurementProcess' es actualizada y una nueva entrada en la tabla de 'Contract' es añadida.
ProcurementProcess
processID |
title |
stage |
description |
procurementMethod |
bidSubmissionOpenDate |
bidSubmissionCloseDate |
tenderValue |
tenderCurrency |
buyerID |
buyerName |
awardDate |
awardValue |
awardCurrency |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
371630 |
Cleaning services |
contract |
Cleaning services for the City Hall |
direct |
2019-12-14T08:00:00Z |
2019-12-14T08:30:00Z |
144300000 |
PYG |
80023736-6 |
City Hall of Juan de Mena |
2019-12-26T14:00:00Z |
PYG |
144300000 |
Contract
contractID |
processID |
status |
signedDate |
value |
currency |
startDate |
endDate |
---|---|---|---|---|---|---|---|
100 |
371630 |
active |
2019-01-10T10:00:00Z |
116400000 |
PYG |
2019-01-15T08:00:00Z |
2020-01-14T17:00:00Z |
Ya que hay una tabla más involucrada ('Contract'), las tres tablas que almacenan datos para el proceso completo pueden ser usadas para calcular el hash. La consulta SQL anterior puede ser cambiada de nuevo para incluir la tabla de 'Contract':
WITH data AS (
SELECT * from ProcurementProcess
JOIN Supplier on Supplier.processID = ProcurementProcess.processID
JOIN Contract on Contract.processID = ProcurementProcess.processID
WHERE processID = 371630
)
SELECT md5(CAST((data.*)AS text)) FROM data
;
Aunque es cierto que los datos en la tabla 'Supplier' no han cambiado en el último paso, esta debería ser incluida a menos que esté garantizado que los datos de la tabla no cambian después de cierto paso en el proceso (para los proveedores, esto podría ser posible en algunos escenarios pero ese supuesto no es tomado aquí).
El nuevo valor de hash es 1a87b0662990c66e140e62e813165107
, y el nuevo identificador de entrega es:
{
"id": "ocds-213czf-371630/1a87b0662990c66e140e62e813165107"
}
Vea el JSON final abajo.