@tricoteuses/senat 2.20.28 → 2.20.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -73,7 +73,7 @@ function detectLecture(objet) {
73
73
  return undefined;
74
74
  }
75
75
  function computeCodeEtape(ev, dossier) {
76
- // In order to match with etape, we need to remove the '-SEANCE' suffix from the codeActe
76
+ // In order to match with stage, we need to remove the '-SEANCE' suffix from the codeActe
77
77
  const cleanCode = (code) => code.replace(/-SEANCE$/, "");
78
78
  const lecture = detectLecture(ev.objet ?? "");
79
79
  const organe = ev.organe ?? "";
@@ -84,7 +84,7 @@ function computeCodeEtape(ev, dossier) {
84
84
  : "";
85
85
  const evDate = ev.date.split("T")[0];
86
86
  const flat = buildFlatActes(dossier);
87
- // 1) Strict matching : same date + nature
87
+ // 1) Strict matching: same date + same nature
88
88
  let candidates = flat.filter((a) => {
89
89
  if (a.date !== evDate)
90
90
  return false;
@@ -92,67 +92,63 @@ function computeCodeEtape(ev, dossier) {
92
92
  return false;
93
93
  return true;
94
94
  });
95
- // If lecture is specified, filter by it
95
+ // If a specific lecture is detected in the agenda event, refine the candidates
96
96
  if (lecture !== undefined && candidates.length > 0) {
97
97
  const withLecture = candidates.filter((c) => c.ordreLecture === lecture);
98
98
  if (withLecture.length > 0) {
99
99
  candidates = withLecture;
100
100
  }
101
101
  }
102
- // Multiple candidates : we take the longest ?
103
102
  if (candidates.length > 0) {
103
+ // Multiple candidates: pick the most specific one (longest code string)
104
104
  candidates.sort((a, b) => b.codeActe.length - a.codeActe.length);
105
105
  return cleanCode(candidates[0].codeActe);
106
106
  }
107
- // 2) fallback COM
107
+ // 2) Fallback COM: If no exact date match for a commission event,
108
+ // take the latest commission act for this lecture on or before the event date.
108
109
  if (nature === "COM") {
109
110
  let comActs = flat.filter((a) => a.codeActe.includes("COM") && a.date <= evDate);
110
111
  if (lecture !== undefined) {
111
112
  const byLecture = comActs.filter((a) => a.ordreLecture === lecture);
112
- if (byLecture.length > 0) {
113
+ if (byLecture.length > 0)
113
114
  comActs = byLecture;
114
- }
115
115
  }
116
116
  if (comActs.length > 0) {
117
117
  comActs.sort((a, b) => b.date.localeCompare(a.date) || b.codeActe.length - a.codeActe.length);
118
118
  return cleanCode(comActs[0].codeActe);
119
119
  }
120
120
  }
121
- // 3) Fallback lecture générale
121
+ // 3) Fallback general lecture: if nothing else worked but a lecture is identified,
122
+ // find any act belonging to that lecture (e.g., SN1-DEPOT).
122
123
  if (lecture !== undefined) {
123
- const lectures = dossier["actes_legislatifs"] ?? [];
124
- const lectureNode = lectures.find((l) => l.ordre_lecture === lecture);
125
- const rootCode = lectureNode?.code_acte;
126
- if (rootCode && typeof rootCode === "string") {
127
- return cleanCode(rootCode);
124
+ const genericActe = flat.find((a) => a.ordreLecture === lecture);
125
+ if (genericActe) {
126
+ return cleanCode(genericActe.codeActe);
128
127
  }
129
128
  }
130
- console.log(`Détails technique pour ev=${ev.id}:`, {
131
- nbLectures: dossier["actes_legislatifs"]?.length || 0,
132
- clesDossier: Object.keys(dossier).slice(0, 10),
133
- structurePremierActe: dossier["actes_legislatifs"]?.[0]
134
- ? JSON.stringify(dossier["actes_legislatifs"][0]).substring(0, 200)
135
- : "AUCUN_ACTE",
129
+ console.log(`✖ No stage code found for ev=${ev.id} (Date: ${evDate}, Nature: ${nature}, Lecture: ${lecture})`, {
130
+ totalActsInDossier: dossier["actes_legislatifs"]?.length || 0,
131
+ firstActDate: flat[0]?.date,
136
132
  });
137
133
  return null;
138
134
  }
139
135
  function buildFlatActes(dossier) {
140
- const lectures = dossier["actes_legislatifs"] ?? [];
136
+ const actes = dossier["actes_legislatifs"] ?? [];
141
137
  const res = [];
142
- for (const lectureActe of lectures) {
143
- const assemblee = lectureActe["assemblee"] || "";
144
- if (!assemblee.toLowerCase().includes("sénat") && !assemblee.toLowerCase().includes("senat"))
138
+ for (const acte of actes) {
139
+ if (acte["chambre"] !== "SN")
145
140
  continue;
146
- const ordreLecture = lectureActe.ordre_lecture;
147
- const sub = lectureActe.actes_legislatifs;
148
- const actes = Array.isArray(sub) && sub.length > 0 ? sub : [lectureActe];
149
- for (const acte of actes) {
150
- const codeActe = acte.code_acte;
151
- const dateActe = acte.date?.split("T")[0];
152
- if (!codeActe || !dateActe)
153
- continue;
154
- res.push({ codeActe, ordreLecture, date: dateActe });
155
- }
141
+ const codeActe = acte.code_acte;
142
+ const dateActe = acte.date?.split("T")[0];
143
+ if (!codeActe || !dateActe)
144
+ continue;
145
+ const match = codeActe.match(/^(?:SN|AN)(\d+)/);
146
+ const ordreLecture = match ? parseInt(match[1], 10) : undefined;
147
+ res.push({
148
+ codeActe,
149
+ date: dateActe,
150
+ ordreLecture,
151
+ });
156
152
  }
157
153
  return res;
158
154
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tricoteuses/senat",
3
- "version": "2.20.28",
3
+ "version": "2.20.29",
4
4
  "description": "Handle French Sénat's open data",
5
5
  "keywords": [
6
6
  "France",