Git Product home page Git Product logo

139bercy / decp-rama Goto Github PK

View Code? Open in Web Editor NEW

This project forked from colinmaudry/decp-json

6.0 6.0 3.0 1.5 MB

Outil pour agréger et convertir en un seul jeu de données toutes les données essentielles de la commande publique

Home Page: https://139bercy.github.io/decp-docs/

License: MIT License

Shell 63.33% XSLT 11.41% Dockerfile 1.41% jq 21.72% Python 2.12%
csv json marche-public ocds open-contracting open-data

decp-rama's People

Contributors

abulte avatar colinmaudry avatar desrousseaux avatar edaubert avatar qmaire avatar strainel avatar yguenneugues avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

decp-rama's Issues

Properties modified by a previous modif are overriden by initial data

The structure of a "marché" is the following

{
      "id": "20192019F1206300",
      "montant": 10000,
      "dureeMois": 12,
      "datePublicationDonnees": "2019-01-01"
      ...
      "modifications": [
        {
          "dureeMois": 18,
          "datePublicationDonneesModification": "2019-01-10"
          ...
        },
        {
          "montant": 12000,
          "datePublicationDonneesModification": "2019-01-20"
          ...
        }
      ]
    }
  1. On 2019-01-01, a publication is made about the initial award, modifications[] is empty
  2. On 2019-01-10, a modification of the duration (dureeMois) is made, the initial data remains unchanged but a modification object is added, including the new duration and the date when the data was published
  3. On 2019-01-20, a modification of the amount (montant) is made, the initial data remains unchanged but a modification object is added, including the new amount and the date when the data was published

Currently, the transformation scripts populates the release by retaining in priority the data in the last modification. If the last modification doesn't modify a field, the value for this field is retrieved from the initial body.

You saw it coming: with the example above, my script would retain the following values for the modified fields:

  • amount: 12000
  • duration: 12 months, because the change didn't occur in the last modification, and is consequently ignored by the script

We consequently end up with a release that has the wrong current value for duration. With the OCDS merge algorithm, the retained duration would be 12, instead of 18.

In order to safely determine the last valid value for all fields, there are several approaches:

  • processing the initial data and each modification as separate release. We will end up with many duplicate releases (can be cleaned up by id) given all the data is repeated every time it's modified. Requires more work to adapt the script.
  • processing only the initial data and the last modification, leaving the modifiable but unmodified fields empty so that they don't override previous modifications. This approach requires little work on current script, but comes with the risk to leave some data behind: the initial award data may never have been published, and was always published with at least one modification.

Nouvelles règles d'exclusion de marché

  • SIRET acheteur ou titulaire = 00000000000000 (que des zéros, peu importe le nombre)
  • pas d'id de marché
  • acheteur sans id
  • pas de titulaires ou array vide
  • pas de montant

Added other id schemes to org-id.guide

The FR-RCS scheme is the most present in the data, but others can be used:

  • TVA (numéro de TVA intracommunautaire, pour les entreprises de pays membres de l'Union européenne)
  • TAHITI (identifiants pour Tahiti et la Polynésie française, 9 chiffres)
  • RIDET (identifiants pour la Nouvelle-Calédonie, 10 chiffres)
  • FRWF (identifiants pour Wallis-et-Futuna, " FRWF " + 14 premières lettres de la raison sociale. Ex. : FRWFDURANDCHAUFFAG)
  • IREP (personnes physiques françaises, 5 chiffres + LIEU DE NAISSANCE + NOM + PRENOM. Ex. : 18102VANNESDURANDMATHIEU)
  • HORS-UE (identifiants pour les entreprises de pays non membres de l'Union Européenne. Code pays ISO 3166 + 16 premiers caractères de la dénomination sociale. Ex. : BRDASILVAMOTORES)

Ne traiter que le flux, pas le stock

Sur proposition de @strainel : afin de réduire le temps de traitement et donc :

  • d'éviter les timeout sur CircleCI
  • de ne pas dépasser notre capital de crédit CircleCI
  • de réduire l'empreinte du traitement

Il s'agit :

  1. pour chaque source, d'extraire les données qui n'ont pas encore été publiées et ne traiter que ces données
  2. de créer les données du jour en fusion le flux de chaque source
  3. de fusionner ces données avec le stock pour dédoublonnement et production des statistiques

Les enjeux :

Certaines anomalies des données téléchargées sur marches-publics.info persistent

Issue original : ColinMaudry#2

Il s'agit des données téléchargeables à cette adresse : https://www.marches-publics.info/mpiaws/index.cfm?fuseaction=pub.affResultats&IDs=25

Voici les anomalies identifiées et corrigées dans b6454a :

  • id doit être une string, pas un nombre (201820180020100)
  • dureeMois doit être un nombre, pas une string (2018M18403GTR00)
  • dureeMois doit être un entier, pas un nombre décimal (20180700) (0.5)
  • dureeMois doit être supérieur à 0 (2019000700)
  • acheteur.id doit être une string, pas un nombre
  • autoriteConcedante.id doit être une string, pas un nombre (2018DSP100)
  • titulaire.id doit être une string, pas un nombre
  • titulaire.denominationSociale doit être une string (201918A10300)
  • modifications.titulaires.id doit être une string, pas un nombre (2019616101)
  • les modifications ne doivent pas être identiques (20191815AC202, 2019007003)
  • donneesExecution doit être un array (2018DSP100)
  • montant doit être un nombre, pas une string
  • codeCPV doit être une string, pas un nombre
  • lieuExecution.code doit être une string, pas un nombre
  • lieuExecution.nom doit être une string, pas un nombre (2019S1813DCP1a00)
  • donneesExecution doit être un array d'objet, pas une string (2018DSP100)
  • il manque un caractère dans les dateNotification et les dateNotificationModification contenant des mois de janvier à septembre (1 à 9) (il manque le zéro)

Voici les anomalies identifiées mais non-corrigées :

  • le code CPV doit être composé de 8 chiffres, et optionnellement de 1 chiffre de contrôle ([0-9]{8}(\-[0-9])?) (2019010400)
  • dans un array modifications, toutes les entrées doivent uniques, aucun doublon n'est autorisé

Proposer un fichier agrégé des nouvelles données du jour

Afin de satisfaire le besoin des réutilisateurs et réutilisatrices (:wave: @marion-paclot) qui ne souhaitent que récupérer les nouvelles données du jour, nous devons produire un fichier ne contenant que les nouvelles données.

Pour ce faire, un diff sera effectué entre le fichier agrégé de la veille et le fichier agrégé du jour.

Conserver les champs non-réglementaires lors de la conversion

Actuellement, lorsque l'on convertit une source XML en JSON, les champs supplémentaires sont supprimés. Ces champs, même s'ils ne sont pas standards, apportent des informations susceptibles d'être dignes d'intérêt.

Il faut donc nous assurer que ces champs supplémentaires sont conservés.

Anomalies dans les données Klekoon

Après téléchargement, les anomalies suivantes ont été repérées dans les données. Elles seront cochées au fur et à mesure de leur résolution par Klekoon ou par un post-traitement :

  • SIRET de titulaires (.titulaires.id) incorrects (trop courts) : voir marchés 2019000018520100, 2020000018997300, mais je pense que tous les marchés sont impactés
  • beaucoup de marchés dont .acheteur.nom est "KLEKOON Compte entreprise". Le SIRET varie un peu, mais je ne trouve que 57 SIRET d'acheteur (.acheteur.id) différents dans l'ensemble des données.
  • certains marchés ont un format de date incorrect : marché 2019000018651000, "08/08/2019 12:07" au lieu de "2019-08-08" (aaaa-mm-jj)
  • valeurs normées incorrectement capitalisées : marché 2019000018651000, "ferme et actualisable" au lieu de "Ferme et actualisable", "marché" au lieu de "Marché", etc.

Toutes ces anomalies sont bloquantes pour l'intégration aux données consolidées.

cc @ungeric-klekoon

Liste et exclusions des données de marchés inexploitables

Certaines données, par leur valeur exagérée ou leur objet étrange, semble ne pas être liées à de véritables attributions de marchés.

Afin de ne pas polluer les statistiques créées à partir de données, ces fausses données doivent être identifiées par leur uid et exclues des données consolidées.

Duplicate release ids

Validation reported 12 duplicates in release ids, including those 3:

  • 086180387000102018511551-00
  • 200066884000122018S-REPASCRE-00
  • 200071678000112018C18072-00

AIFE : certains fichiers XML ont le même nom, un préfix .1 leur est ajouté au téléchargement

Au moment du téléchargement les fichiers qui ont le même nom qu'un fichier déjà téléchargé reçoive un suffixe .1 pour ne pas écraser le fichier précédent.

Au moment de l'étape de correction des anomalies (fix.sh), l'ensemble des fichiers, même préfixé, est traité (cf https://github.com/etalab/decp-rama/blob/master/scripts/sources/data.gouv.fr_aife/fix.sh#L16 pas de discrimination)

En revanche à l'étape de conversion vers JSON (convert.sh), le script ne prend que les fichiers qui se terminent par .xml, laissant de côté les fichiers qui se terminent par .xml.1 (cf https://github.com/etalab/decp-rama/blob/master/scripts/sources/data.gouv.fr_aife/convert.sh#L11). C'est ici qu'il faut corriger.

Conversion du JSON agrégé au format OCDS JSON : HS

Nombre de marchés dans le fichier des nouveaux marchés : 210

## Conversion du JSON agrégé en XML...
-rw-r--r-- 1 root root 265M Apr 16 09:14 xml/decp.xml

## Conversion du JSON du jour en XML...
-rw-r--r-- 1 root root 234K Apr 16 09:14 decp_2021-04-16.xml

## Conversion du JSON agrégé au format OCDS JSON...
Error: writing output failed: Cannot allocate memory

Exited with code exit status 2
CircleCI received exit code 2

et j'ai testé en local, le script fonctionne bien. mystère. @edaubert

Anomalies dans les données collectées par l'AIFE

Les données collectées et mises à disposition (mais pas produites) par l'AIFE sur data.gouv.fr ne sont pas conformes au format réglementaire.

Anomalies corrigées par notre script XSLT :

  • les valeurs du champ nature sont en MAJUSCULES au lieu d'avoir seulement La Première Lettre Accentuée
  • les valeurs du champ typeCode sont en MAJUSCULES au lieu d'avoir seulement La Première Lettre Accentuée

Anomalie non-corrigées

  • certains caractères des champs objet sont corrompus
  • les champs dateNotification et datePublicationDonnees sont souvent manquants
  • quelques champs id sont manquants (jq '.marches[] | select(.id | not))' json/data.gouv.fr_aife.json)
  • des codes de lieu d'exécution invalides (voir comm de marion-paclot)
  • des marchés n'ont pas de <titulaires> (jq '[ .marches[] | select((.titulaires | type != "array") and ._type == "Marché")] | length' json/decp.json)

Intégrer les données de klekoon.com

Klekoon publie les données essentielles de ses clients à raison d'un fichier par marché public (exemple : http://data.klekoon.com/api/dcat/json/2019000018937600).

Les marchés d'un acheteur sont rassemblés dans un catalogue DCAT (conformément à la réglementation) (exemple : http://data.klekoon.com/api/dcat/21040190700014 pour le SIRET 21040190700014).

Enfin, l'ensemble des catalogues DCAT des acheteurs sont listés dans un fichier CSV (séparateur ;) : https://www.klekoon.com/declaration-profil-acheteur.

Détection et suppression des doublons

Définition : marché dont les caractéristiques suivantes sont identiques à un autre :

  • uid (concaténation du SIRET de l'acheteur ou de l'autorité concédante (acheteur.id/autoriteConcedante.id) et de l'identifiant du marché (id))
  • nombre de modifications (nombre d'objets dans modifications)
  • nombre de données d'exécution (nombre d'objets dans donneesExecution)

Explication : plusieurs marchés peuvent avoir la même uid, car chaque modification du marché requiert une republication de l'ensemble des données, avec l'ajout d'une modification. Pour les concessions, les autorités concédantes doivent republier les données des concessions en ajoutant les nouvelles données d'exécution (tarifs, etc.) chaque année.

Il ne s'agit pas d'une définition absolue, mais d'une définition représentant un bon équilibre entre

  • l'effort nécessaire pour être appliquée
  • l'efficacité à supprimer les doublons
  • le risque de faux positifs

Le script d'extraction des nouveaux marchés échoue si trop nombreux

Mis à part le dataset AWS, lorsque les sources sont mises à jour, il n'y a aucun soucis. En revanche, lorsque je mets à jour le dataset AWS avec quelques centaines ou milliers de nouveaux marchés, le script plante :

https://circleci.com/gh/etalab/decp-rama/68

parse error: Expected separator between values at line 37323, column 1

(ça plante ici : https://github.com/etalab/decp-rama/blob/master/scripts/get_new_data.sh#L63)
(le JSON n'est pas valide).

Ternum-bfc: échec sur Circle, OK en local

============================================
2020-10-02T13:13:20 : début du traitement pour source ternum-bfc

Téléchargement (ternum-bfc)...

Exited with code exit status 8

Je n'ai pas trouvé de documentation sur ce code 8 et sa signification.

Documenting OCDS data

In order to facilitate the use of the OCDS data, we will publish specific documentation.

Champs id manquant pour certains titulaires

Bonjour,

Il semblerait que certains titulaires n'aient aucun champs id dans le fichier decp.json récupéré depuis l'url suivante:
https://www.data.gouv.fr/fr/datasets/r/16962018-5c31-4296-9454-5998585496d2

Cela concerne les 31 uid de marché suivants:
2175000160001920191080010010
2175000160001920191210020021
2175000160001920191230000325
2175000160001920191230000573
2175000160001920191230000980
2175000160001920191230000985
2175000160001920191230001523
2175000160001920191230025400
2175000160001920191230082211
2175000160001920191230082702
2175000160001920191230082704
2175000160001920191320000685
2175000160001920191320000734
2175000160001920191320000802
2175000160001920191320010581
2175000160001920191370000381
2175000160001920191370000763
2175000160001920191370000946
2175000160001920191370021500
2175000160001920191370022900
2175000160001920191370023000
2175000160001920191370025700
2175000160001920191410001294
2175000160001920191440029400
2175000160001920201320010633
2175000160001920201320010635
2175000160001920201320010636
2175000160001920201370032300
2175000160001920201370090003
2175000160001920201370090004
2175000160001920201390000226

Je n'ai pas vérifié pour tous les uid, mais à priori ça semble être la même erreur pour tous.
Exemple pour 2175000160001920191080010010:

{
"id": "20191080010010",
"source": "data.gouv.fr_aife",
"uid": "2175000160001920191080010010",
"acheteur": {
"id": "21750001600019",
"nom": "VILLE DE PARIS BUDGET PRINCIPAL"
},
"_type": "Marché",
"nature": "Marché",
"objet": "SA1 SURVEILLANCE/SURETE EVENEMENTIEL - LOT1 MULTIATTRIBUTAIR",
"codeCPV": "79714000",
"procedure": "Appel d'offres ouvert",
"lieuExecution": {
"code": "75056",
"typeCode": "Code commune",
"nom": "PARIS"
},
"dureeMois": 48,
"dateNotification": "2019-10-24",
"datePublicationDonnees": "2019-11-01",
"montant": 11505789.99,
"formePrix": "Révisable",
"titulaires": [
{
"typeIdentifiant": "SIRET",
"id": "45029024200061",
"denominationSociale": "SIPP"
},
{
"denominationSociale": "MARCHE MULTIATTRIBUTAIRE"
}
,
{
"typeIdentifiant": "SIRET",
"id": "34329965700076",
"denominationSociale": "ALTAIR SECURITE"
}
],
"modifications": []
}

Cordialement,

Adaptation des valeurs du champ "procedure" à l'arrêté du 22/03/2019

Texte de l'arrêté : https://www.legifrance.gouv.fr/affichTexte.do?cidTexte=JORFTEXT000038318675&categorieLien=i

Voici la liste des nouvelles valeurs possibles :

  • Procédure adaptée
  • Appel d'offres ouvert
  • Appel d'offres restreint
  • Procédure avec négociation
  • Marché passé sans publicité ni mise en concurrence préalable
  • Dialogue compétitif

Pour les données produites selon la liste de valeurs documentées dans l'arrêté du 14 avril 2017, voici les équivalences :

  • Procédure concurrentielle avec négociation ➡️ Procédure avec négociation
  • Procédure négociée avec mise en concurrence préalable ➡️ Procédure avec négociation
  • Marché négocié sans publicité ni mise en concurrence préalable ➡️ Marché passé sans publicité ni mise en concurrence préalable

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.